From 41fec243ae961bf3371eec8143ff1b648ac9a1c6 Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 4 Jul 2023 11:44:39 +0200 Subject: [PATCH 01/64] [Cases] Guardrails: Limit bulk get cases and bulk get attachments (#161088) Connected to https://github.com/elastic/kibana/issues/146945 ## Summary | Description | Limit | Done? | Documented? | ------------- | ---- | :---: | ---- | | Total number of attachments returned by bulk get API | 100 | :white_check_mark: | No (internal) | | Total number of cases returned by bulk get API | 1000 | :white_check_mark: | No (internal) | - Replaced the code validation with schema validation. - BulkGet Cases - The minimum of cases that can be returned is now 1(was not validated before). - BulkGet Attachments - The maximum of attachments that can be returned is now 100(was **10000**). - The minimum of attachments that can be returned is now 1(was not validated before). - Updated unit and e2e tests. - The documentation was not updated because these are internal APIs. - Skipping the release notes because these are internal APIs. ### 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] [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 --- x-pack/plugins/cases/common/api/cases/case.ts | 3 +- .../cases/common/api/cases/comment/index.ts | 9 +++- .../plugins/cases/common/constants/index.ts | 2 +- .../client/attachments/bulk_get.test.ts | 41 +++++++++++++++++++ .../server/client/attachments/bulk_get.ts | 13 ------ .../server/client/cases/bulk_get.test.ts | 17 +++++--- .../cases/server/client/cases/bulk_get.ts | 10 ----- .../common/internal/bulk_get_attachments.ts | 41 +++++++++---------- .../tests/common/internal/bulk_get_cases.ts | 13 ++++-- 9 files changed, 94 insertions(+), 55 deletions(-) create mode 100644 x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts diff --git a/x-pack/plugins/cases/common/api/cases/case.ts b/x-pack/plugins/cases/common/api/cases/case.ts index a4bd4b016d955..9778195465432 100644 --- a/x-pack/plugins/cases/common/api/cases/case.ts +++ b/x-pack/plugins/cases/common/api/cases/case.ts @@ -24,6 +24,7 @@ import { MAX_ASSIGNEES_FILTER_LENGTH, MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, + MAX_BULK_GET_CASES, } from '../../constants'; export const AttachmentTotalsRt = rt.strict({ @@ -509,7 +510,7 @@ export const GetCategoriesResponseRt = rt.array(rt.string); export const GetReportersResponseRt = rt.array(UserRt); export const CasesBulkGetRequestRt = rt.strict({ - ids: rt.array(rt.string), + ids: limitedArraySchema({ codec: rt.string, min: 1, max: MAX_BULK_GET_CASES, fieldName: 'ids' }), }); export const CasesBulkGetResponseRt = rt.strict({ diff --git a/x-pack/plugins/cases/common/api/cases/comment/index.ts b/x-pack/plugins/cases/common/api/cases/comment/index.ts index f688dc24fdf85..1662631ae2b79 100644 --- a/x-pack/plugins/cases/common/api/cases/comment/index.ts +++ b/x-pack/plugins/cases/common/api/cases/comment/index.ts @@ -6,6 +6,8 @@ */ import * as rt from 'io-ts'; +import { MAX_BULK_GET_ATTACHMENTS } from '../../../constants'; +import { limitedArraySchema } from '../../../schema'; import { jsonValueRt } from '../../runtime_types'; import { NumberFromString } from '../../saved_object'; @@ -307,7 +309,12 @@ export const FindCommentsQueryParamsRt = rt.exact( export const BulkCreateCommentRequestRt = rt.array(CommentRequestRt); export const BulkGetAttachmentsRequestRt = rt.strict({ - ids: rt.array(rt.string), + ids: limitedArraySchema({ + codec: rt.string, + min: 1, + max: MAX_BULK_GET_ATTACHMENTS, + fieldName: 'ids', + }), }); export const BulkGetAttachmentsResponseRt = rt.strict({ diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index bee8ff9f3b17e..b7b4987042495 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -101,7 +101,7 @@ export const MAX_ALERTS_PER_CASE = 1000 as const; * Searching */ export const MAX_DOCS_PER_PAGE = 10000 as const; -export const MAX_BULK_GET_ATTACHMENTS = MAX_DOCS_PER_PAGE; +export const MAX_BULK_GET_ATTACHMENTS = 100 as const; export const MAX_CONCURRENT_SEARCHES = 10 as const; export const MAX_BULK_GET_CASES = 1000 as const; export const MAX_COMMENTS_PER_PAGE = 100 as const; diff --git a/x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts b/x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts new file mode 100644 index 0000000000000..078f79128391b --- /dev/null +++ b/x-pack/plugins/cases/server/client/attachments/bulk_get.test.ts @@ -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 { MAX_BULK_GET_ATTACHMENTS } from '../../../common/constants'; +import { createCasesClientMockArgs, createCasesClientMock } from '../mocks'; +import { bulkGet } from './bulk_get'; + +describe('bulkGet', () => { + describe('errors', () => { + const casesClient = createCasesClientMock(); + const clientArgs = createCasesClientMockArgs(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it(`throws when trying to fetch more than ${MAX_BULK_GET_ATTACHMENTS} attachments`, async () => { + await expect( + bulkGet( + { attachmentIDs: Array(MAX_BULK_GET_ATTACHMENTS + 1).fill('foobar'), caseID: '123' }, + clientArgs, + casesClient + ) + ).rejects.toThrow( + `Error: The length of the field ids is too long. Array must be of length <= ${MAX_BULK_GET_ATTACHMENTS}.` + ); + }); + + it('throws when trying to fetch zero attachments', async () => { + await expect( + bulkGet({ attachmentIDs: [], caseID: '123' }, clientArgs, casesClient) + ).rejects.toThrow( + 'Error: The length of the field ids is too short. Array must be of length >= 1.' + ); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/client/attachments/bulk_get.ts b/x-pack/plugins/cases/server/client/attachments/bulk_get.ts index 294b39bab6959..553f8ca258669 100644 --- a/x-pack/plugins/cases/server/client/attachments/bulk_get.ts +++ b/x-pack/plugins/cases/server/client/attachments/bulk_get.ts @@ -5,10 +5,7 @@ * 2.0. */ -import Boom from '@hapi/boom'; - import { partition } from 'lodash'; -import { MAX_BULK_GET_ATTACHMENTS } from '../../../common/constants'; import type { BulkGetAttachmentsResponse, CommentAttributes } from '../../../common/api'; import { decodeWithExcessOrThrow, @@ -45,8 +42,6 @@ export async function bulkGet( try { const request = decodeWithExcessOrThrow(BulkGetAttachmentsRequestRt)({ ids: attachmentIDs }); - throwErrorIfIdsExceedTheLimit(request.ids); - // perform an authorization check for the case await casesClient.cases.resolve({ id: caseID }); @@ -83,14 +78,6 @@ export async function bulkGet( } } -const throwErrorIfIdsExceedTheLimit = (ids: string[]) => { - if (ids.length > MAX_BULK_GET_ATTACHMENTS) { - throw Boom.badRequest( - `Maximum request limit of ${MAX_BULK_GET_ATTACHMENTS} attachments reached` - ); - } -}; - interface PartitionedAttachments { validAttachments: AttachmentSavedObject[]; attachmentsWithErrors: AttachmentSavedObjectWithErrors; diff --git a/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts b/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts index 0ee8955c9adb5..771f5ece6f188 100644 --- a/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts +++ b/x-pack/plugins/cases/server/client/cases/bulk_get.test.ts @@ -5,22 +5,29 @@ * 2.0. */ +import { MAX_BULK_GET_CASES } from '../../../common/constants'; import { createCasesClientMockArgs } from '../mocks'; import { bulkGet } from './bulk_get'; describe('bulkGet', () => { - describe('throwErrorIfCaseIdsReachTheLimit', () => { + describe('errors', () => { const clientArgs = createCasesClientMockArgs(); beforeEach(() => { jest.clearAllMocks(); }); - it('throws if the requested cases are more than 1000', async () => { - const ids = Array(1001).fill('test'); + it(`throws when trying to fetch more than ${MAX_BULK_GET_CASES} cases`, async () => { + await expect( + bulkGet({ ids: Array(MAX_BULK_GET_CASES + 1).fill('foobar') }, clientArgs) + ).rejects.toThrow( + `Error: The length of the field ids is too long. Array must be of length <= ${MAX_BULK_GET_CASES}.` + ); + }); - await expect(bulkGet({ ids }, clientArgs)).rejects.toThrow( - 'Maximum request limit of 1000 cases reached' + it('throws when trying to fetch zero cases', async () => { + await expect(bulkGet({ ids: [] }, clientArgs)).rejects.toThrow( + 'Error: The length of the field ids is too short. Array must be of length >= 1.' ); }); diff --git a/x-pack/plugins/cases/server/client/cases/bulk_get.ts b/x-pack/plugins/cases/server/client/cases/bulk_get.ts index 13df81bf06965..4665c27cebbf6 100644 --- a/x-pack/plugins/cases/server/client/cases/bulk_get.ts +++ b/x-pack/plugins/cases/server/client/cases/bulk_get.ts @@ -5,10 +5,8 @@ * 2.0. */ -import Boom from '@hapi/boom'; import { partition } from 'lodash'; -import { MAX_BULK_GET_CASES } from '../../../common/constants'; import type { CasesBulkGetResponse, CasesBulkGetRequest, @@ -45,8 +43,6 @@ export const bulkGet = async ( try { const request = decodeWithExcessOrThrow(CasesBulkGetRequestRt)(params); - throwErrorIfCaseIdsReachTheLimit(request.ids); - const cases = await caseService.getCases({ caseIds: request.ids }); const [validCases, soBulkGetErrors] = partition( @@ -91,12 +87,6 @@ export const bulkGet = async ( } }; -const throwErrorIfCaseIdsReachTheLimit = (ids: string[]) => { - if (ids.length > MAX_BULK_GET_CASES) { - throw Boom.badRequest(`Maximum request limit of ${MAX_BULK_GET_CASES} cases reached`); - } -}; - const constructErrors = ( soBulkGetErrors: CaseSavedObjectWithErrors, unauthorizedCases: CaseSavedObjectTransformed[] diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts index 2d1a7c2ab69a6..8907f7e28841c 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_attachments.ts @@ -90,27 +90,6 @@ export default ({ getService }: FtrProviderContext): void => { expect(response.attachments[1].id).to.eql(updatedCase.comments![1].id); }); - it('returns an empty array when no ids are requested', async () => { - const { attachments, errors } = await bulkGetAttachments({ - attachmentIds: [], - caseId: updatedCase.id, - supertest, - expectedHttpCode: 200, - }); - - expect(attachments.length).to.be(0); - expect(errors.length).to.be(0); - }); - - it('returns a 400 when more than 10k ids are requested', async () => { - await bulkGetAttachments({ - attachmentIds: Array.from(Array(10001).keys()).map((item) => item.toString()), - caseId: updatedCase.id, - supertest, - expectedHttpCode: 400, - }); - }); - it('populates the errors field with attachments that could not be found', async () => { const response = await bulkGetAttachments({ attachmentIds: [updatedCase.comments![0].id, 'does-not-exist'], @@ -455,5 +434,25 @@ export default ({ getService }: FtrProviderContext): void => { }); } }); + + describe('errors', () => { + it('400s when requesting more than 100 attachments', async () => { + await bulkGetAttachments({ + attachmentIds: Array(101).fill('foobar'), + caseId: 'id', + expectedHttpCode: 400, + supertest, + }); + }); + + it('400s when requesting zero attachments', async () => { + await bulkGetAttachments({ + attachmentIds: [], + caseId: 'id', + expectedHttpCode: 400, + supertest, + }); + }); + }); }); }; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts index 3ea30d7371b3e..449251377a077 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_get_cases.ts @@ -7,6 +7,7 @@ import expect from '@kbn/expect'; import { CommentType } from '@kbn/cases-plugin/common'; +import { MAX_BULK_GET_CASES } from '@kbn/cases-plugin/common/constants'; import { getPostCaseRequest, postCaseReq } from '../../../../common/lib/mock'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { @@ -111,12 +112,18 @@ export default ({ getService }: FtrProviderContext): void => { }); describe('errors', () => { - it('400s when requesting more than 1000 cases', async () => { - const ids = Array(1001).fill('test'); + it(`400s when requesting more than ${MAX_BULK_GET_CASES} cases`, async () => { + await bulkGetCases({ + supertest, + ids: Array(MAX_BULK_GET_CASES + 1).fill('foobar'), + expectedHttpCode: 400, + }); + }); + it('400s when requesting zero cases', async () => { await bulkGetCases({ supertest, - ids, + ids: [], expectedHttpCode: 400, }); }); From 023b23f2a6a16612e48300494e66836d2c49c785 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Tue, 4 Jul 2023 11:54:02 +0200 Subject: [PATCH 02/64] Fix infinite loading of APM alert table (#161134) Fixes #161095 ## Summary This PR fixes triggering and immediately canceling /bsearch requests infinitely. --- .../public/components/app/alerts_overview/index.tsx | 11 +++++++---- .../templates/apm_service_template/index.tsx | 1 + .../templates/mobile_service_template/index.tsx | 1 + .../correlations/failed_transaction_correlations.ts | 13 +++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx b/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx index d5cd8c530332e..7e4914f29a671 100644 --- a/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/alerts_overview/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useMemo, useEffect } from 'react'; +import React, { useState, useMemo, useEffect, useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { ObservabilityAlertSearchBar } from '@kbn/observability-plugin/public'; import { AlertStatus } from '@kbn/observability-plugin/common/typings'; @@ -72,6 +72,11 @@ export function AlertsOverview() { ]; }, [serviceName, environment]); + const onKueryChange = useCallback( + (value) => push(history, { query: { kuery: value } }), + [history] + ); + return ( @@ -86,9 +91,7 @@ export function AlertsOverview() { onRangeToChange={(value) => push(history, { query: { rangeTo: value } }) } - onKueryChange={(value) => - push(history, { query: { kuery: value } }) - } + onKueryChange={onKueryChange} defaultSearchQueries={apmQueries} onStatusChange={setAlertStatusFilter} onEsQueryChange={setEsQuery} diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx index 6400365aa87a1..a2ab809092055 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx @@ -401,5 +401,6 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { prepend, append, isSelected: key === selectedTab, + 'data-test-subj': `${key}Tab`, })); } diff --git a/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx index 2f92aa4b18f4c..496010a14853a 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/mobile_service_template/index.tsx @@ -222,5 +222,6 @@ function useTabs({ selectedTabKey }: { selectedTabKey: Tab['key'] }) { label, append, isSelected: key === selectedTabKey, + 'data-test-subj': `${key}Tab`, })); } diff --git a/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts b/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts index 84913086f3c89..61b19327428e7 100644 --- a/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts +++ b/x-pack/test/functional/apps/apm/correlations/failed_transaction_correlations.ts @@ -16,6 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'error', 'timePicker', 'security']); const testSubjects = getService('testSubjects'); const appsMenu = getService('appsMenu'); + const observability = getService('observability'); const testData = { correlationsTab: 'Failed transaction correlations', @@ -149,6 +150,18 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ); }); }); + + it('navigates to the alerts tab', async function () { + await find.clickByCssSelector(`[data-test-subj="alertsTab"]`); + + await PageObjects.timePicker.timePickerExists(); + await PageObjects.timePicker.setCommonlyUsedTime('Last_15 minutes'); + + // Should show no data message + await retry.try(async () => { + await observability.overview.common.getAlertsTableNoDataOrFail(); + }); + }); }); }); } From 9685de25e06061dd9b9c4d71ee5e3b2a4b251bdf Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Tue, 4 Jul 2023 12:20:49 +0200 Subject: [PATCH 03/64] Modify open_close_signals route to avoid using update_by_query when possible (#159703) issue: https://github.com/elastic/security-team/issues/6829 ## Summary * Update `open_close_signals_route` to call `_update_by_query` API only when a query is provided. When the alert ids are provided it will call `_bulk` update instead. * It also unifies the response so both `updateAlerts` calls return the same interface. ### Context We still can call updateByQuery as many times as we need if the feature works with eventual consistency (search after writing returns stale data). If we need to show the updated data after writing, we need refresh: true, which is expensive (updateByQuery doesn't support refresh: wait_for). So, it makes sense to avoid calling refresh: true when we have the ids by using _bulk update with refresh: wait_for. ### How to test it? #### Old Alerts Table/Grouped Alerts Table * Select one or more rows * Open the bulk action menu and update the alert status Screenshot 2023-06-27 at 16 51 42 * It should update Alerts by id instead of sending a query and calling `update_by_query` API * Bulk updating all alert statuses doesn't change #### Close Alerts From Exceptions * Click on the row of actions for an alert * Select the 'Add rule exception' option Screenshot 2023-06-27 at 16 55 54 * Fill all required fields on the flyout + `Close this alert` * Click on "Add rule exception" * It should update the Alerts by id instead of sending a query and calling the `update_by_query` API * Bulk updating all alert statuses doesn't change ### 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 --- .../event_details/event_details.tsx | 4 - .../event_details/overview/index.tsx | 13 +- .../overview/status_popover_button.test.tsx | 1 - .../overview/status_popover_button.tsx | 4 +- .../common/components/events_viewer/index.tsx | 1 - .../events_viewer/use_alert_bulk_actions.tsx | 4 - .../bulk_actions/alert_bulk_actions.tsx | 3 - .../bulk_actions/alert_bulk_tags.test.tsx | 4 +- .../toolbar/bulk_actions/helpers.ts | 18 +++ .../bulk_actions/update_alerts.test.ts | 58 +++++++++ .../toolbar/bulk_actions/update_alerts.ts | 60 +++++++++ .../bulk_actions/use_bulk_action_items.tsx | 16 +-- .../bulk_actions/use_set_alert_tags.tsx | 2 +- .../toolbar/bulk_actions/use_update_alerts.ts | 41 ------- .../logic/use_close_alerts.tsx | 10 +- .../components/alerts_table/actions.tsx | 24 ++-- .../alerts_table/alerts_sub_grouping.tsx | 1 - .../group_take_action_items.test.tsx | 8 -- .../group_take_action_items.tsx | 8 +- .../timeline_actions/alert_context_menu.tsx | 1 - .../timeline_actions/use_alerts_actions.tsx | 3 - .../take_action_dropdown/index.test.tsx | 1 - .../components/take_action_dropdown/index.tsx | 3 - .../detection_engine/alerts/api.test.ts | 57 +++++++-- .../containers/detection_engine/alerts/api.ts | 29 ++++- .../detection_engine/alerts/types.ts | 10 +- .../use_alert_actions.tsx | 18 +-- .../public/flyout/right/footer.tsx | 11 +- .../event_details/expandable_event.tsx | 1 - .../event_details/flyout/footer.test.tsx | 1 - .../event_details/flyout/footer.tsx | 7 -- .../side_panel/event_details/flyout/index.tsx | 1 - .../side_panel/event_details/index.tsx | 1 - .../routes/signals/open_close_signals.test.ts | 47 +++++++ .../signals/open_close_signals_route.ts | 107 ++++++++++------ .../group10/open_close_signals.ts | 115 ++++++++++++++---- .../group10/set_alert_tags.ts | 4 +- .../utils/get_signal_status_empty_response.ts | 2 +- .../utils/set_signal_status.ts | 5 +- 39 files changed, 466 insertions(+), 238 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.ts delete mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.ts diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx index a282a5c58a77c..4457a669b19ae 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx @@ -86,7 +86,6 @@ interface Props { data: TimelineEventsDetailsItem[]; detailsEcsData: Ecs | null; id: string; - indexName: string; isAlert: boolean; isDraggable?: boolean; rawEventData: object | undefined; @@ -154,7 +153,6 @@ const EventDetailsComponent: React.FC = ({ data, detailsEcsData, id, - indexName, isAlert, isDraggable, rawEventData, @@ -235,7 +233,6 @@ const EventDetailsComponent: React.FC = ({ contextId={scopeId} data={data} eventId={id} - indexName={indexName} scopeId={scopeId} handleOnEventClosed={handleOnEventClosed} isReadOnly={isReadOnly} @@ -328,7 +325,6 @@ const EventDetailsComponent: React.FC = ({ scopeId, data, id, - indexName, handleOnEventClosed, isReadOnly, renderer, diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx index 497c3c5083b54..b33f777dcff41 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.tsx @@ -42,22 +42,12 @@ interface Props { data: TimelineEventsDetailsItem[]; eventId: string; handleOnEventClosed: () => void; - indexName: string; scopeId: string; isReadOnly?: boolean; } export const Overview = React.memo( - ({ - browserFields, - contextId, - data, - eventId, - handleOnEventClosed, - indexName, - scopeId, - isReadOnly, - }) => { + ({ browserFields, contextId, data, eventId, handleOnEventClosed, scopeId, isReadOnly }) => { const statusData = useMemo(() => { const item = find({ field: SIGNAL_STATUS_FIELD_NAME, category: 'kibana' }, data); return ( @@ -128,7 +118,6 @@ export const Overview = React.memo( eventId={eventId} contextId={contextId} enrichedFieldInfo={statusData} - indexName={indexName} scopeId={scopeId} handleOnEventClosed={handleOnEventClosed} /> diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx index 5a2f27e7a98c4..28a0a117bacc1 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.test.tsx @@ -45,7 +45,6 @@ const props = { fields: {}, }, }, - indexName: '.internal.alerts-security.alerts-default-000001', scopeId: 'alerts-page', handleOnEventClosed: jest.fn(), }; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx index 748b2d6a4779f..ba88adaf99a48 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/status_popover_button.tsx @@ -24,13 +24,12 @@ interface StatusPopoverButtonProps { eventId: string; contextId: string; enrichedFieldInfo: EnrichedFieldInfoWithValues; - indexName: string; scopeId: string; handleOnEventClosed: () => void; } export const StatusPopoverButton = React.memo( - ({ eventId, contextId, enrichedFieldInfo, indexName, scopeId, handleOnEventClosed }) => { + ({ eventId, contextId, enrichedFieldInfo, scopeId, handleOnEventClosed }) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const togglePopover = useCallback(() => setIsPopoverOpen(!isPopoverOpen), [isPopoverOpen]); const closePopover = useCallback(() => setIsPopoverOpen(false), []); @@ -51,7 +50,6 @@ export const StatusPopoverButton = React.memo( closePopover: closeAfterAction, eventId, scopeId, - indexName, alertStatus: enrichedFieldInfo.values[0] as Status, refetch: refetchGlobalQuery, }); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index 97c72e0c5e975..b145fa81345a3 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -496,7 +496,6 @@ const StatefulEventsViewerComponent: React.FC) => { + return { + query: { + bool: { + filter: { + terms: { + _id: eventIds, + }, + }, + }, + }, + }; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.ts new file mode 100644 index 0000000000000..ccf45b091174d --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.test.ts @@ -0,0 +1,58 @@ +/* + * 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 { updateAlertStatus } from './update_alerts'; + +const mockUpdateAlertStatusByIds = jest.fn().mockReturnValue(new Promise(() => {})); +const mockUpdateAlertStatusByQuery = jest.fn().mockReturnValue(new Promise(() => {})); + +jest.mock('../../../../detections/containers/detection_engine/alerts/api', () => { + return { + updateAlertStatusByQuery: (params: unknown) => mockUpdateAlertStatusByQuery(params), + updateAlertStatusByIds: (params: unknown) => mockUpdateAlertStatusByIds(params), + }; +}); + +const status = 'open'; + +describe('updateAlertStatus', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should throw an error if neither query nor signalIds are provided', () => { + expect(() => { + updateAlertStatus({ status }); + }).toThrowError('Either query or signalIds must be provided'); + }); + + it('should call updateAlertStatusByIds if signalIds are provided', () => { + const signalIds = ['1', '2']; + updateAlertStatus({ + status, + signalIds, + }); + expect(mockUpdateAlertStatusByIds).toHaveBeenCalledWith({ + status, + signalIds, + }); + expect(mockUpdateAlertStatusByQuery).not.toHaveBeenCalled(); + }); + + it('should call mockUpdateAlertStatusByQuery if query is provided', () => { + const query = { query: 'query' }; + updateAlertStatus({ + status, + query, + }); + expect(mockUpdateAlertStatusByIds).not.toHaveBeenCalled(); + expect(mockUpdateAlertStatusByQuery).toHaveBeenCalledWith({ + status, + query, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.ts new file mode 100644 index 0000000000000..2ffa195fee497 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/update_alerts.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 type { UpdateByQueryResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { Status } from '../../../../../common/detection_engine/schemas/common'; +import { + updateAlertStatusByIds, + updateAlertStatusByQuery, +} from '../../../../detections/containers/detection_engine/alerts/api'; + +interface UpdatedAlertsResponse { + updated: number; + version_conflicts: UpdateByQueryResponse['version_conflicts']; +} + +interface UpdatedAlertsProps { + status: Status; + query?: object; + signalIds?: string[]; + signal?: AbortSignal; +} + +/** + * Update alert status by query or signalIds. + * Either query or signalIds must be provided + * `signalIds` is the preferred way to update alerts because it is more cost effective on Serverless. + * + * @param status to update to('open' / 'closed' / 'acknowledged') + * @param index index to be updated + * @param query optional query object to update alerts by query. + * @param signalIds optional signalIds to update alerts by signalIds. + * @param signal to cancel request + * + * @throws An error if response is not OK + */ +export const updateAlertStatus = ({ + status, + query, + signalIds, + signal, +}: UpdatedAlertsProps): Promise => { + if (signalIds && signalIds.length > 0) { + return updateAlertStatusByIds({ status, signalIds, signal }).then(({ items }) => ({ + updated: items.length, + version_conflicts: 0, + })); + } else if (query) { + return updateAlertStatusByQuery({ status, query, signal }).then( + ({ updated, version_conflicts: conflicts }) => ({ + updated: updated ?? 0, + version_conflicts: conflicts, + }) + ); + } + throw new Error('Either query or signalIds must be provided'); +}; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx index d2647023539e8..34b6a523efa59 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_action_items.tsx @@ -14,22 +14,17 @@ import type { SetEventsLoading, } from '../../../../../common/types'; import * as i18n from './translations'; -import { useUpdateAlertsStatus } from './use_update_alerts'; +import { updateAlertStatus } from './update_alerts'; import { useAppToasts } from '../../../hooks/use_app_toasts'; import { useStartTransaction } from '../../../lib/apm/use_start_transaction'; import { APM_USER_INTERACTIONS } from '../../../lib/apm/constants'; import type { AlertWorkflowStatus } from '../../../types'; import type { OnUpdateAlertStatusError, OnUpdateAlertStatusSuccess } from './types'; -export const getUpdateAlertsQuery = (eventIds: Readonly) => { - return { bool: { filter: { terms: { _id: eventIds } } } }; -}; - export interface BulkActionsProps { eventIds: string[]; currentStatus?: AlertWorkflowStatus; query?: string; - indexName: string; setEventsLoading: SetEventsLoading; setEventsDeleted: SetEventsDeleted; showAlertStatusActions?: boolean; @@ -42,7 +37,6 @@ export const useBulkActionItems = ({ eventIds, currentStatus, query, - indexName, setEventsLoading, showAlertStatusActions = true, setEventsDeleted, @@ -50,7 +44,6 @@ export const useBulkActionItems = ({ onUpdateFailure, customBulkActions, }: BulkActionsProps) => { - const { updateAlertStatus } = useUpdateAlertsStatus(); const { addSuccess, addError, addWarning } = useAppToasts(); const { startTransaction } = useStartTransaction(); @@ -116,11 +109,10 @@ export const useBulkActionItems = ({ try { setEventsLoading({ eventIds, isLoading: true }); - const response = await updateAlertStatus({ - index: indexName, status, - query: query ? JSON.parse(query) : getUpdateAlertsQuery(eventIds), + query: query && JSON.parse(query), + signalIds: eventIds, }); // TODO: Only delete those that were successfully updated from updatedRules @@ -140,8 +132,6 @@ export const useBulkActionItems = ({ [ setEventsLoading, eventIds, - updateAlertStatus, - indexName, query, setEventsDeleted, onAlertStatusUpdateSuccess, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx index 4805c8dc996fb..9b211f9c259cc 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx @@ -10,11 +10,11 @@ import type { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { getUpdateAlertsQuery } from '../../../../detections/components/alerts_table/actions'; import type { AlertTags } from '../../../../../common/detection_engine/schemas/common'; import { DETECTION_ENGINE_ALERT_TAGS_URL } from '../../../../../common/constants'; import { useAppToasts } from '../../../hooks/use_app_toasts'; import * as i18n from './translations'; +import { getUpdateAlertsQuery } from './helpers'; export type SetAlertTagsFunc = ( tags: AlertTags, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.ts deleted file mode 100644 index 13ecf12b4479c..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_update_alerts.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { CoreStart } from '@kbn/core/public'; - -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { DETECTION_ENGINE_SIGNALS_STATUS_URL } from '../../../../../common/constants'; -import type { AlertWorkflowStatus } from '../../../types'; - -/** - * Update alert status by query - * - * @param status to update to('open' / 'closed' / 'acknowledged') - * @param index index to be updated - * @param query optional query object to update alerts by query. - - * - * @throws An error if response is not OK - */ -export const useUpdateAlertsStatus = (): { - updateAlertStatus: (params: { - status: AlertWorkflowStatus; - index: string; - query: object; - }) => Promise; -} => { - const { http } = useKibana().services; - return { - updateAlertStatus: async ({ status, index, query }) => { - return http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { - method: 'POST', - body: JSON.stringify({ status, query }), - }); - }, - }; -}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx index a6dce444527d0..4c2493fbb81e4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx @@ -8,9 +8,6 @@ import { useEffect, useRef, useState } from 'react'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; - -import { updateAlertStatus } from '../../../detections/containers/detection_engine/alerts/api'; -import { getUpdateAlertsQuery } from '../../../detections/components/alerts_table/actions'; import { buildAlertStatusesFilter, buildAlertsFilter, @@ -21,6 +18,7 @@ import { prepareExceptionItemsForBulkClose } from '../utils/helpers'; import * as i18nCommon from '../../../common/translations'; import * as i18n from './translations'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { updateAlertStatus } from '../../../common/components/toolbar/bulk_actions/update_alerts'; /** * Closes alerts. @@ -65,7 +63,7 @@ export const useCloseAlertsFromExceptions = (): ReturnUseCloseAlertsFromExceptio let bulkResponse: estypes.UpdateByQueryResponse | undefined; if (alertIdToClose != null) { alertIdResponse = await updateAlertStatus({ - query: getUpdateAlertsQuery([alertIdToClose]), + signalIds: [alertIdToClose], status: 'closed', signal: abortCtrl.signal, }); @@ -88,9 +86,7 @@ export const useCloseAlertsFromExceptions = (): ReturnUseCloseAlertsFromExceptio ); bulkResponse = await updateAlertStatus({ - query: { - query: filter, - }, + query: filter, status: 'closed', signal: abortCtrl.signal, }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx index 8e8973310056e..28d46d96953b8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx @@ -44,7 +44,6 @@ import { import type { TimelineResult } from '../../../../common/types/timeline/api'; import { TimelineId } from '../../../../common/types/timeline'; import { TimelineStatus, TimelineType } from '../../../../common/types/timeline/api'; -import { updateAlertStatus } from '../../containers/detection_engine/alerts/api'; import type { SendAlertToTimelineActionProps, ThresholdAggregationData, @@ -83,20 +82,7 @@ import { DEFAULT_FROM_MOMENT, DEFAULT_TO_MOMENT, } from '../../../common/utils/default_date_settings'; - -export const getUpdateAlertsQuery = (eventIds: Readonly) => { - return { - query: { - bool: { - filter: { - terms: { - _id: eventIds, - }, - }, - }, - }, - }; -}; +import { updateAlertStatus } from '../../../common/components/toolbar/bulk_actions/update_alerts'; export const updateAlertStatusAction = async ({ query, @@ -110,8 +96,12 @@ export const updateAlertStatusAction = async ({ try { setEventsLoading({ eventIds: alertIds, isLoading: true }); - const queryObject = query ? { query: JSON.parse(query) } : getUpdateAlertsQuery(alertIds); - const response = await updateAlertStatus({ query: queryObject, status: selectedStatus }); + const response = await updateAlertStatus({ + query: query && JSON.parse(query), + status: selectedStatus, + signalIds: alertIds, + }); + // TODO: Only delete those that were successfully updated from updatedRules setEventsDeleted({ eventIds: alertIds, isDeleted: true }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx index f2fa9e8bb6d1b..2465de8f14c26 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx @@ -235,7 +235,6 @@ export const GroupedSubLevelComponent: React.FC = ({ ); const takeActionItems = useGroupTakeActionsItems({ - indexName: indexPattern.title, currentStatus: currentAlertStatusFilterValue, showAlertStatusActions: hasIndexWrite && hasIndexMaintenance, }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx index d663b2abc2c61..6470c9a4abc66 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.test.tsx @@ -35,7 +35,6 @@ describe('useGroupTakeActionsItems', () => { const { result, waitForNextUpdate } = renderHook( () => useGroupTakeActionsItems({ - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -53,7 +52,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: [], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -71,7 +69,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['open', 'closed'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -89,7 +86,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['open'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -110,7 +106,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['closed'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -131,7 +126,6 @@ describe('useGroupTakeActionsItems', () => { () => useGroupTakeActionsItems({ currentStatus: ['acknowledged'], - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { @@ -151,7 +145,6 @@ describe('useGroupTakeActionsItems', () => { const { result, waitForNextUpdate } = renderHook( () => useGroupTakeActionsItems({ - indexName: '.alerts-security.alerts-default', showAlertStatusActions: false, }), { @@ -167,7 +160,6 @@ describe('useGroupTakeActionsItems', () => { const { result, waitForNextUpdate } = renderHook( () => useGroupTakeActionsItems({ - indexName: '.alerts-security.alerts-default', showAlertStatusActions: true, }), { diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx index 5d151d2e4cc88..1384c592162db 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_take_action_items.tsx @@ -15,7 +15,7 @@ import { useStartTransaction } from '../../../../common/lib/apm/use_start_transa import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import type { AlertWorkflowStatus } from '../../../../common/types'; import { APM_USER_INTERACTIONS } from '../../../../common/lib/apm/constants'; -import { useUpdateAlertsStatus } from '../../../../common/components/toolbar/bulk_actions/use_update_alerts'; +import { updateAlertStatus } from '../../../../common/components/toolbar/bulk_actions/update_alerts'; import { BULK_ACTION_ACKNOWLEDGED_SELECTED, BULK_ACTION_CLOSE_SELECTED, @@ -33,16 +33,13 @@ import type { StartServices } from '../../../../types'; export interface TakeActionsProps { currentStatus?: Status[]; - indexName: string; showAlertStatusActions?: boolean; } export const useGroupTakeActionsItems = ({ currentStatus, - indexName, showAlertStatusActions = true, }: TakeActionsProps) => { - const { updateAlertStatus } = useUpdateAlertsStatus(); const { addSuccess, addError, addWarning } = useAppToasts(); const { startTransaction } = useStartTransaction(); const getGlobalQuerySelector = inputsSelectors.globalQuery(); @@ -163,7 +160,6 @@ export const useGroupTakeActionsItems = ({ try { const response = await updateAlertStatus({ - index: indexName, status, query: query ? JSON.parse(query) : {}, }); @@ -176,8 +172,6 @@ export const useGroupTakeActionsItems = ({ [ startTransaction, reportAlertsGroupingTakeActionClick, - updateAlertStatus, - indexName, onAlertStatusUpdateSuccess, onAlertStatusUpdateFailure, ] diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 57b0491446121..a9e3958332322 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -177,7 +177,6 @@ const AlertContextMenuComponent: React.FC void; eventId: string; scopeId: string; - indexName: string; refetch?: () => void; } @@ -28,7 +27,6 @@ export const useAlertsActions = ({ closePopover, eventId, scopeId, - indexName, refetch, }: Props) => { const dispatch = useDispatch(); @@ -63,7 +61,6 @@ export const useAlertsActions = ({ const actionItems = useBulkActionItems({ eventIds: [eventId], currentStatus: alertStatus as AlertWorkflowStatus, - indexName, setEventsLoading: localSetEventsLoading, setEventsDeleted, onUpdateSuccess: onStatusUpdate, diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx index 1a9c71b68bc4f..5874abe8397c5 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx @@ -99,7 +99,6 @@ describe('take action dropdown', () => { detailsData: generateAlertDetailsDataMock() as TimelineEventsDetailsItem[], ecsData: getDetectionAlertMock(), handleOnEventClosed: jest.fn(), - indexName: 'index', isHostIsolationPanelOpen: false, loadingEventDetails: false, onAddEventFilterClick: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx index 666db98405454..107af049ae6af 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx @@ -48,7 +48,6 @@ export interface TakeActionDropdownProps { detailsData: TimelineEventsDetailsItem[] | null; ecsData?: Ecs; handleOnEventClosed: () => void; - indexName: string; isHostIsolationPanelOpen: boolean; loadingEventDetails: boolean; onAddEventFilterClick: () => void; @@ -65,7 +64,6 @@ export const TakeActionDropdown = React.memo( detailsData, ecsData, handleOnEventClosed, - indexName, isHostIsolationPanelOpen, loadingEventDetails, onAddEventFilterClick, @@ -180,7 +178,6 @@ export const TakeActionDropdown = React.memo( alertStatus: actionsData.alertStatus, closePopover: closePopoverAndFlyout, eventId: actionsData.eventId, - indexName, refetch, scopeId, }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts index eea9500e868a8..601bbf9498617 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.test.ts @@ -16,11 +16,12 @@ import { } from './mock'; import { fetchQueryAlerts, - updateAlertStatus, getSignalIndex, getUserPrivilege, createSignalIndex, createHostIsolation, + updateAlertStatusByQuery, + updateAlertStatusByIds, } from './api'; import { coreMock } from '@kbn/core/public/mocks'; @@ -57,40 +58,40 @@ describe('Detections Alerts API', () => { }); }); - describe('updateAlertStatus', () => { + describe('updateAlertStatusByQuery', () => { beforeEach(() => { fetchMock.mockClear(); fetchMock.mockResolvedValue({}); }); test('check parameter url, body when closing an alert', async () => { - await updateAlertStatus({ + await updateAlertStatusByQuery({ query: mockStatusAlertQuery, signal: abortCtrl.signal, status: 'closed', }); expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { - body: '{"conflicts":"proceed","status":"closed","bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}', + body: '{"conflicts":"proceed","status":"closed","query":{"bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}}', method: 'POST', signal: abortCtrl.signal, }); }); test('check parameter url, body when opening an alert', async () => { - await updateAlertStatus({ + await updateAlertStatusByQuery({ query: mockStatusAlertQuery, signal: abortCtrl.signal, status: 'open', }); expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { - body: '{"conflicts":"proceed","status":"open","bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}', + body: '{"conflicts":"proceed","status":"open","query":{"bool":{"filter":{"terms":{"_id":["b4ee5c32e3a321057edcc953ca17228c6fdfe5ba43fdbbdaffa8cefa11605cc5"]}}}}}', method: 'POST', signal: abortCtrl.signal, }); }); test('happy path', async () => { - const alertsResp = await updateAlertStatus({ + const alertsResp = await updateAlertStatusByQuery({ query: mockStatusAlertQuery, signal: abortCtrl.signal, status: 'open', @@ -99,6 +100,48 @@ describe('Detections Alerts API', () => { }); }); + describe('updateAlertStatusById', () => { + beforeEach(() => { + fetchMock.mockClear(); + fetchMock.mockResolvedValue({}); + }); + + test('check parameter url, body when closing an alert', async () => { + await updateAlertStatusByIds({ + signalIds: ['123'], + signal: abortCtrl.signal, + status: 'closed', + }); + expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { + body: '{"status":"closed","signal_ids":["123"]}', + method: 'POST', + signal: abortCtrl.signal, + }); + }); + + test('check parameter url, body when opening an alert', async () => { + await updateAlertStatusByIds({ + signalIds: ['123'], + signal: abortCtrl.signal, + status: 'open', + }); + expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/signals/status', { + body: '{"status":"open","signal_ids":["123"]}', + method: 'POST', + signal: abortCtrl.signal, + }); + }); + + test('happy path', async () => { + const alertsResp = await updateAlertStatusByIds({ + signalIds: ['123'], + signal: abortCtrl.signal, + status: 'open', + }); + expect(alertsResp).toEqual({}); + }); + }); + describe('getSignalIndex', () => { beforeEach(() => { fetchMock.mockClear(); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts index d8d1bae460a6d..91430d4818317 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts @@ -24,9 +24,10 @@ import type { QueryAlerts, AlertSearchResponse, AlertsIndex, - UpdateAlertStatusProps, + UpdateAlertStatusByQueryProps, CasesFromAlertsResponse, CheckSignalIndex, + UpdateAlertStatusByIdsProps, } from './types'; import { isolateHost, unIsolateHost } from '../../../../common/lib/endpoint_isolation'; import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables'; @@ -84,14 +85,34 @@ export const fetchQueryRuleRegistryAlerts = async ({ * * @throws An error if response is not OK */ -export const updateAlertStatus = async ({ +export const updateAlertStatusByQuery = async ({ query, status, signal, -}: UpdateAlertStatusProps): Promise => +}: UpdateAlertStatusByQueryProps): Promise => KibanaServices.get().http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { method: 'POST', - body: JSON.stringify({ conflicts: 'proceed', status, ...query }), + body: JSON.stringify({ conflicts: 'proceed', status, query }), + signal, + }); + +/** + * Update alert status by signalIds + * + * @param signalIds List of signal ids to update + * @param status to update to('open' / 'closed' / 'acknowledged') + * @param signal AbortSignal for cancelling request + * + * @throws An error if response is not OK + */ +export const updateAlertStatusByIds = async ({ + signalIds, + status, + signal, +}: UpdateAlertStatusByIdsProps): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, { + method: 'POST', + body: JSON.stringify({ status, signal_ids: signalIds }), signal, }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts index 9d39a3f39770f..717f2bee7a768 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/types.ts @@ -38,10 +38,16 @@ export interface AlertSearchResponse }; } -export interface UpdateAlertStatusProps { +export interface UpdateAlertStatusByQueryProps { query: object; status: Status; - signal?: AbortSignal; // TODO: implement cancelling + signal?: AbortSignal; +} + +export interface UpdateAlertStatusByIdsProps { + signalIds: string[]; + status: Status; + signal?: AbortSignal; } export interface AlertsIndex { diff --git a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx index 0f214d2f9b959..5ac7628f5376f 100644 --- a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx @@ -12,14 +12,12 @@ import { buildEsQuery } from '@kbn/es-query'; import type { TableId } from '@kbn/securitysolution-data-table'; import type { SourcererScopeName } from '../../../common/store/sourcerer/model'; import { APM_USER_INTERACTIONS } from '../../../common/lib/apm/constants'; -import { useUpdateAlertsStatus } from '../../../common/components/toolbar/bulk_actions/use_update_alerts'; -import { useSourcererDataView } from '../../../common/containers/sourcerer'; +import { updateAlertStatus } from '../../../common/components/toolbar/bulk_actions/update_alerts'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { useStartTransaction } from '../../../common/lib/apm/use_start_transaction'; import type { AlertWorkflowStatus } from '../../../common/types'; import { FILTER_CLOSED, FILTER_OPEN, FILTER_ACKNOWLEDGED } from '../../../../common/types'; import * as i18n from '../translations'; -import { getUpdateAlertsQuery } from '../../components/alerts_table/actions'; import { buildTimeRangeFilter } from '../../components/alerts_table/helpers'; interface UseBulkAlertActionItemsArgs { @@ -45,7 +43,6 @@ export const useBulkAlertActionItems = ({ }: UseBulkAlertActionItemsArgs) => { const { startTransaction } = useStartTransaction(); - const { updateAlertStatus } = useUpdateAlertsStatus(); const { addSuccess, addError, addWarning } = useAppToasts(); const onAlertStatusUpdateSuccess = useCallback( @@ -92,8 +89,6 @@ export const useBulkAlertActionItems = ({ [addError] ); - const { selectedPatterns } = useSourcererDataView(scopeId); - const getOnAction = useCallback( (status: AlertWorkflowStatus) => { const onActionClick: BulkActionsConfig['onClick'] = async ( @@ -103,14 +98,13 @@ export const useBulkAlertActionItems = ({ clearSelection, refresh ) => { - const ids = items.map((item) => item._id); - let query: Record = getUpdateAlertsQuery(ids).query; + let ids: string[] | undefined = items.map((item) => item._id); + let query: Record | undefined; if (isSelectAllChecked) { const timeFilter = buildTimeRangeFilter(from, to); query = buildEsQuery(undefined, [], [...timeFilter, ...filters], undefined); - } - if (query) { + ids = undefined; startTransaction({ name: APM_USER_INTERACTIONS.BULK_QUERY_STATUS_UPDATE }); } else if (items.length > 1) { startTransaction({ name: APM_USER_INTERACTIONS.BULK_STATUS_UPDATE }); @@ -121,9 +115,9 @@ export const useBulkAlertActionItems = ({ try { setAlertLoading(true); const response = await updateAlertStatus({ - index: selectedPatterns.join(','), status, query, + signalIds: ids, }); setAlertLoading(false); @@ -150,8 +144,6 @@ export const useBulkAlertActionItems = ({ [ onAlertStatusUpdateFailure, onAlertStatusUpdateSuccess, - updateAlertStatus, - selectedPatterns, startTransaction, filters, from, diff --git a/x-pack/plugins/security_solution/public/flyout/right/footer.tsx b/x-pack/plugins/security_solution/public/flyout/right/footer.tsx index d3f035ce64065..d0980141ebfcc 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/right/footer.tsx @@ -17,14 +17,8 @@ import { useHostIsolationTools } from '../../timelines/components/side_panel/eve */ export const PanelFooter: FC = memo(() => { const { closeFlyout } = useExpandableFlyoutContext(); - const { - eventId, - indexName, - dataFormattedForFieldBrowser, - dataAsNestedObject, - refetchFlyoutData, - scopeId, - } = useRightPanelContext(); + const { dataFormattedForFieldBrowser, dataAsNestedObject, refetchFlyoutData, scopeId } = + useRightPanelContext(); const { isHostIsolationPanelOpen, showHostIsolationPanel } = useHostIsolationTools(); @@ -36,7 +30,6 @@ export const PanelFooter: FC = memo(() => { ( detailsEcsData={detailsEcsData} id={event.eventId} isAlert={isAlert} - indexName={event.indexName} isDraggable={isDraggable} rawEventData={rawEventData} scopeId={scopeId} diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx index 6f069cb8dc83e..ab24a16ca1a93 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.test.tsx @@ -115,7 +115,6 @@ const defaultProps = { isHostIsolationPanelOpen: false, handleOnEventClosed: jest.fn(), onAddIsolationStatusClick: jest.fn(), - expandedEvent: { eventId: ecsData._id, indexName: '' }, detailsData: mockAlertDetailsDataWithIsObject, refetchFlyoutData: jest.fn(), }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx index b91f01885e9d5..9234a05bf1f07 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/footer.tsx @@ -26,11 +26,6 @@ import { OsqueryFlyout } from '../../../../../detections/components/osquery/osqu interface FlyoutFooterProps { detailsData: TimelineEventsDetailsItem[] | null; detailsEcsData: Ecs | null; - expandedEvent: { - eventId: string; - indexName: string; - refetch?: () => void; - }; handleOnEventClosed: () => void; isHostIsolationPanelOpen: boolean; isReadOnly?: boolean; @@ -52,7 +47,6 @@ export const FlyoutFooterComponent = React.memo( ({ detailsData, detailsEcsData, - expandedEvent, handleOnEventClosed, isHostIsolationPanelOpen, isReadOnly, @@ -162,7 +156,6 @@ export const FlyoutFooterComponent = React.memo( onAddIsolationStatusClick={onAddIsolationStatusClick} refetchFlyoutData={refetchFlyoutData} refetch={refetchAll} - indexName={expandedEvent.indexName} scopeId={scopeId} onOsqueryClick={setOsqueryFlyoutOpenWithAgentId} /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx index 2a9f30d0ec29b..d52fa2331e016 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/index.tsx @@ -136,7 +136,6 @@ export const useToGetInternalFlyout = () => { = ({ { status_code: 500, }); }); + + test('calls "esClient.updateByQuery" with queryId when query is defined', async () => { + await server.inject( + getSetSignalStatusByQueryRequest(), + requestContextMock.convertContext(context) + ); + expect(context.core.elasticsearch.client.asCurrentUser.updateByQuery).toHaveBeenCalledWith( + expect.objectContaining({ + body: expect.objectContaining({ + query: expect.objectContaining({ + bool: { filter: typicalSetStatusSignalByQueryPayload().query }, + }), + }), + }) + ); + }); + + test('calls "esClient.bulk" with signalIds when ids are defined', async () => { + await server.inject( + getSetSignalStatusByIdsRequest(), + requestContextMock.convertContext(context) + ); + expect(context.core.elasticsearch.client.asCurrentUser.bulk).toHaveBeenCalledWith( + expect.objectContaining({ + body: expect.arrayContaining([ + { + update: { + _id: 'somefakeid1', + _index: '.alerts-security.alerts-default', + }, + }, + { + script: expect.anything(), + }, + { + update: { + _id: 'somefakeid2', + _index: '.alerts-security.alerts-default', + }, + }, + { + script: expect.anything(), + }, + ]), + }) + ); + }); }); describe('request validation', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index 9681d22d91198..199e0c8f412f4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -8,7 +8,7 @@ import { get } from 'lodash'; import { transformError } from '@kbn/securitysolution-es-utils'; import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-data-utils'; -import type { Logger } from '@kbn/core/server'; +import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { setSignalStatusValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/set_signal_status_type_dependents'; import type { SetSignalsStatusSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/set_signal_status_schema'; import { setSignalsStatusSchema } from '../../../../../common/detection_engine/schemas/request/set_signal_status_schema'; @@ -87,40 +87,20 @@ export const setSignalsStatusRoute = ( } } - let queryObject; - if (signalIds) { - queryObject = { ids: { values: signalIds } }; - } - if (query) { - queryObject = { - bool: { - filter: query, - }, - }; - } try { - const body = await esClient.updateByQuery({ - index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, - conflicts: conflicts ?? 'abort', - // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#_refreshing_shards_2 - // Note: Before we tried to use "refresh: wait_for" but I do not think that was available and instead it defaulted to "refresh: true" - // but the tests do not pass with "refresh: false". If at some point a "refresh: wait_for" is implemented, we should use that instead. - refresh: true, - body: { - script: { - source: `if (ctx._source['${ALERT_WORKFLOW_STATUS}'] != null) { - ctx._source['${ALERT_WORKFLOW_STATUS}'] = '${status}' - } - if (ctx._source.signal != null && ctx._source.signal.status != null) { - ctx._source.signal.status = '${status}' - }`, - lang: 'painless', - }, - query: queryObject, - }, - ignore_unavailable: true, - }); - return response.ok({ body }); + if (signalIds) { + const body = await updateSignalsStatusByIds(status, signalIds, spaceId, esClient); + return response.ok({ body }); + } else { + const body = await updateSignalsStatusByQuery( + status, + query, + { conflicts: conflicts ?? 'abort' }, + spaceId, + esClient + ); + return response.ok({ body }); + } } catch (err) { // error while getting or updating signal with id: id in signal index .siem-signals const error = transformError(err); @@ -132,3 +112,62 @@ export const setSignalsStatusRoute = ( } ); }; + +const updateSignalsStatusByIds = async ( + status: SetSignalsStatusSchemaDecoded['status'], + signalsId: string[], + spaceId: string, + esClient: ElasticsearchClient +) => + esClient.bulk({ + index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, + refresh: 'wait_for', + body: signalsId.flatMap((signalId) => [ + { + update: { _id: signalId, _index: `${DEFAULT_ALERTS_INDEX}-${spaceId}` }, + }, + { + script: getUpdateSignalStatusScript(status), + }, + ]), + }); + +/** + * Please avoid using `updateSignalsStatusByQuery` when possible, use `updateSignalsStatusByIds` instead. + * + * This method calls `updateByQuery` with `refresh: true` which is expensive on serverless. + */ +const updateSignalsStatusByQuery = async ( + status: SetSignalsStatusSchemaDecoded['status'], + query: object | undefined, + options: { conflicts: 'abort' | 'proceed' }, + spaceId: string, + esClient: ElasticsearchClient +) => + esClient.updateByQuery({ + index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, + conflicts: options.conflicts, + // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#_refreshing_shards_2 + // Note: Before we tried to use "refresh: wait_for" but I do not think that was available and instead it defaulted to "refresh: true" + // but the tests do not pass with "refresh: false". If at some point a "refresh: wait_for" is implemented, we should use that instead. + refresh: true, + body: { + script: getUpdateSignalStatusScript(status), + query: { + bool: { + filter: query, + }, + }, + }, + ignore_unavailable: true, + }); + +const getUpdateSignalStatusScript = (status: SetSignalsStatusSchemaDecoded['status']) => ({ + source: `if (ctx._source['${ALERT_WORKFLOW_STATUS}'] != null) { + ctx._source['${ALERT_WORKFLOW_STATUS}'] = '${status}' + } + if (ctx._source.signal != null && ctx._source.signal.status != null) { + ctx._source.signal.status = '${status}' + }`, + lang: 'painless', +}); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts index c9fb6334ab8c5..72262b12453f8 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts @@ -20,7 +20,7 @@ import { createSignalsIndex, deleteAllAlerts, setSignalStatus, - getAlertUpdateEmptyResponse, + getAlertUpdateByQueryEmptyResponse, getQuerySignalIds, deleteAllRules, createRule, @@ -41,33 +41,106 @@ export default ({ getService }: FtrProviderContext) => { describe('open_close_signals', () => { describe('validation checks', () => { - it('should not give errors when querying and the signals index does not exist yet', async () => { - const { body } = await supertest - .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) - .set('kbn-xsrf', 'true') - .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) - .expect(200); + describe('update by ids', () => { + it('should not give errors when querying and the signals index does not exist yet', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) + .expect(200); - // remove any server generated items that are indeterministic - delete body.took; + // remove any server generated items that are nondeterministic + body.items.forEach((_: any, index: number) => { + delete body.items[index].update.error.index_uuid; + }); + delete body.took; + + expect(body).to.eql({ + errors: true, + items: [ + { + update: { + _id: '123', + _index: '.internal.alerts-security.alerts-default-000001', + error: { + index: '.internal.alerts-security.alerts-default-000001', + reason: '[123]: document missing', + shard: '0', + type: 'document_missing_exception', + }, + status: 404, + }, + }, + ], + }); + }); - expect(body).to.eql(getAlertUpdateEmptyResponse()); + it('should not give errors when querying and the signals index does exist and is empty', async () => { + await createSignalsIndex(supertest, log); + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) + .expect(200); + + // remove any server generated items that are nondeterministic + body.items.forEach((_: any, index: number) => { + delete body.items[index].update.error.index_uuid; + }); + delete body.took; + + expect(body).to.eql({ + errors: true, + items: [ + { + update: { + _id: '123', + _index: '.internal.alerts-security.alerts-default-000001', + error: { + index: '.internal.alerts-security.alerts-default-000001', + reason: '[123]: document missing', + shard: '0', + type: 'document_missing_exception', + }, + status: 404, + }, + }, + ], + }); + + await deleteAllAlerts(supertest, log, es); + }); }); - it('should not give errors when querying and the signals index does exist and is empty', async () => { - await createSignalsIndex(supertest, log); - const { body } = await supertest - .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) - .set('kbn-xsrf', 'true') - .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) - .expect(200); + describe('update by query', () => { + it('should not give errors when querying and the signals index does not exist yet', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ query: { match_all: {} }, status: 'open' })) + .expect(200); + + // remove any server generated items that are indeterministic + delete body.took; + + expect(body).to.eql(getAlertUpdateByQueryEmptyResponse()); + }); + + it('should not give errors when querying and the signals index does exist and is empty', async () => { + await createSignalsIndex(supertest, log); + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ query: { match_all: {} }, status: 'open' })) + .expect(200); - // remove any server generated items that are indeterministic - delete body.took; + // remove any server generated items that are indeterministic + delete body.took; - expect(body).to.eql(getAlertUpdateEmptyResponse()); + expect(body).to.eql(getAlertUpdateByQueryEmptyResponse()); - await deleteAllAlerts(supertest, log, es); + await deleteAllAlerts(supertest, log, es); + }); }); describe('tests with auditbeat data', () => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts index c3334cbe1c504..970d8b5426acd 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts @@ -17,7 +17,6 @@ import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, deleteAllAlerts, - getAlertUpdateEmptyResponse, getQuerySignalIds, deleteAllRules, createRule, @@ -25,6 +24,7 @@ import { getSignalsByIds, waitForRuleSuccess, getRuleForSignalTesting, + getAlertUpdateByQueryEmptyResponse, } from '../../utils'; import { buildAlertTagsQuery, setAlertTags } from '../../utils/set_alert_tags'; @@ -47,7 +47,7 @@ export default ({ getService }: FtrProviderContext) => { // remove any server generated items that are indeterministic delete body.took; - expect(body).to.eql(getAlertUpdateEmptyResponse()); + expect(body).to.eql(getAlertUpdateByQueryEmptyResponse()); }); it('should give errors when duplicate tags exist in both tags_to_add and tags_to_remove', async () => { diff --git a/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts b/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts index 3a7d612fea854..953d1ac4e77f8 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_signal_status_empty_response.ts @@ -5,7 +5,7 @@ * 2.0. */ -export const getAlertUpdateEmptyResponse = () => ({ +export const getAlertUpdateByQueryEmptyResponse = () => ({ timed_out: false, total: 0, updated: 0, diff --git a/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts b/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts index 2cd4cb557f637..37a10bd23f9a9 100644 --- a/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts +++ b/x-pack/test/detection_engine_api_integration/utils/set_signal_status.ts @@ -12,11 +12,14 @@ import type { export const setSignalStatus = ({ signalIds, + query, status, }: { - signalIds: SignalIds; + signalIds?: SignalIds; + query?: object; status: Status; }) => ({ signal_ids: signalIds, + query, status, }); From 122977ef09a523ed7545b6639480979a5eaa83c8 Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Tue, 4 Jul 2023 13:53:39 +0300 Subject: [PATCH 04/64] [Cloud Security] Fix search in benchmark page (#161093) --- .../public/pages/rules/use_csp_rules.ts | 2 +- .../routes/csp_rule_template/get_csp_rule_template.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts index a5aee47c7c1cc..e0870d1e64b01 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts @@ -27,7 +27,7 @@ export const useFindCspRuleTemplates = ( [CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE, { search, page, perPage, packagePolicyId }], () => { return http.get(FIND_CSP_RULE_TEMPLATE_ROUTE_PATH, { - query: { packagePolicyId, page, perPage }, + query: { packagePolicyId, page, perPage, search }, version: FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION, }); } diff --git a/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts b/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts index 63e2bdb6ee102..fb6e0e7c53ab0 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/csp_rule_template/get_csp_rule_template.ts @@ -60,9 +60,9 @@ const findCspRuleTemplateHandler = async ( filter: getBenchmarkTypeFilter(benchmarkId), }); - const cspRulesTemplates = cspRulesTemplatesSo.saved_objects.map((cspRuleTemplate) => { - return { ...cspRuleTemplate.attributes }; - }); + const cspRulesTemplates = cspRulesTemplatesSo.saved_objects.map( + (cspRuleTemplate) => cspRuleTemplate.attributes + ); return { items: cspRulesTemplates, From bfe6cf82e0bc47818f55203a60b381217e88b515 Mon Sep 17 00:00:00 2001 From: Giorgos Bamparopoulos Date: Tue, 4 Jul 2023 12:04:40 +0100 Subject: [PATCH 05/64] [DOCS] Update the 8.8.2 release notes (#161163) --- docs/CHANGELOG.asciidoc | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 4685d40e5ddbf..5d915c8feb6a6 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -54,7 +54,6 @@ Review the following information about the {kib} 8.8.2 release. === Bug Fixes APM:: -* Circuit breaker and performance improvements for service map {kibana-pull}159883[#159883] * Fixes the latency graph displaying all service transactions, rather than the selected one, on the transaction detail page {kibana-pull}159085[#159085] Dashboard:: From ad5930927cca5c1587eba5e944463198f044029c Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 4 Jul 2023 07:25:35 -0400 Subject: [PATCH 06/64] skip failing test suite (#161157) --- test/functional/apps/discover/group3/_request_counts.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/discover/group3/_request_counts.ts b/test/functional/apps/discover/group3/_request_counts.ts index c4f5676f357e5..24698bcb45c11 100644 --- a/test/functional/apps/discover/group3/_request_counts.ts +++ b/test/functional/apps/discover/group3/_request_counts.ts @@ -27,7 +27,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const queryBar = getService('queryBar'); const elasticChart = getService('elasticChart'); - describe('discover request counts', function describeIndexTests() { + // Failing: See https://github.com/elastic/kibana/issues/161157 + describe.skip('discover request counts', function describeIndexTests() { before(async function () { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/long_window_logstash'); From 54e613b1d9341497d40a2c671c527de18beec165 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Tue, 4 Jul 2023 05:13:54 -0700 Subject: [PATCH 07/64] [Security Solution][Fix] Alert Page Filter Controls should not ignore Invalid Selections (#160374) This PR changes how Alert Page Filter Controls Work. ## Before 1. Filter Controls use to ignore invalid Selections. For example, if User has selected `Open` as the filter, but there is actually no alert with Status `Open`, filters would ignore that selection and would proceed to show other alerts ( which are NOT `Open`) . - It seemed it was confusing users. [This bug](https://github.com/elastic/kibana/issues/159606) and [messages in community slack](https://elasticstack.slack.com/archives/CNRTGB9A4/p1686937708085629?thread_ts=1686841414.978319&cid=CNRTGB9A4) are the examples. @paulewing also emphasized this. - Below video shows what I mean. https://github.com/elastic/kibana/assets/7485038/01771587-e4e8-4331-9535-4ffa09877c02 ## After 1. With this Change Control Filters no longer ignore invalid selection. So if user has chosen to show only `Open` Alerts. Then that filter will be taken into account even though no alert with `Open` exists and a empty table will be show. - Here is a video to demonstrate it. https://github.com/elastic/kibana/assets/7485038/62b17762-16c0-471f-8480-e9f46e2ca5ef --- .../pipelines/pull_request/pipeline.ts | 1 + .../security_solution/common/constants.ts | 7 +- .../alerts/detection_page_filters.cy.ts | 98 ++++---- .../cypress/screens/common/filter_group.ts | 8 +- .../security_solution/cypress/tasks/alerts.ts | 33 +-- .../cypress/tasks/common/filter_group.ts | 12 +- .../components/filter_group/constants.ts | 19 ++ .../components/filter_group/context_menu.tsx | 10 +- .../filter_group/filter_group.test.tsx | 76 ++++-- .../common/components/filter_group/index.tsx | 210 ++++++++-------- .../common/components/filter_group/types.ts | 11 +- .../components/filter_group/utils.test.ts | 225 +++++++++++++++++- .../common/components/filter_group/utils.ts | 114 ++++++++- 13 files changed, 617 insertions(+), 207 deletions(-) diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.ts b/.buildkite/scripts/pipelines/pull_request/pipeline.ts index 70a06d1d97e8d..98bd47597bd3e 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.ts +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.ts @@ -60,6 +60,7 @@ const uploadPipeline = (pipelineContent: string | object) => { if ( (await doAnyChangesMatch([ + /^src\/plugins\/controls/, /^packages\/kbn-securitysolution-.*/, /^x-pack\/plugins\/lists/, /^x-pack\/plugins\/security_solution/, diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index a311cae265f33..7150d08da713d 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -6,6 +6,7 @@ */ import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; +import type { AddOptionsListControlProps } from '@kbn/controls-plugin/public'; import * as i18n from './translations'; /** @@ -507,19 +508,23 @@ export const MAX_NUMBER_OF_NEW_TERMS_FIELDS = 3; export const BULK_ADD_TO_TIMELINE_LIMIT = 2000; -export const DEFAULT_DETECTION_PAGE_FILTERS = [ +export const DEFAULT_DETECTION_PAGE_FILTERS: Array< + Omit & { persist?: boolean } +> = [ { title: 'Status', fieldName: 'kibana.alert.workflow_status', selectedOptions: ['open'], hideActionBar: true, persist: true, + hideExists: true, }, { title: 'Severity', fieldName: 'kibana.alert.severity', selectedOptions: [], hideActionBar: true, + hideExists: true, }, { title: 'User', diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts index 6e77002c945dd..acff1f8acb426 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts @@ -6,13 +6,13 @@ */ import { encode } from '@kbn/rison'; +import type { FilterItemObj } from '../../../../public/common/components/filter_group/types'; import { getNewRule } from '../../../objects/rule'; import { CONTROL_FRAMES, CONTROL_FRAME_TITLE, CONTROL_POPOVER, FILTER_GROUP_CHANGED_BANNER, - OPTION_IGNORED, OPTION_LIST_LABELS, OPTION_LIST_VALUES, OPTION_SELECTABLE, @@ -29,7 +29,6 @@ import { formatPageFilterSearchParam } from '../../../../common/utils/format_pag import { closePageFilterPopover, markAcknowledgedFirstAlert, - openFirstAlert, openPageFilterPopover, resetFilters, selectCountTable, @@ -38,7 +37,7 @@ import { waitForAlerts, waitForPageFilters, } from '../../../tasks/alerts'; -import { ALERTS_COUNT, ALERTS_REFRESH_BTN } from '../../../screens/alerts'; +import { ALERTS_COUNT, ALERTS_REFRESH_BTN, EMPTY_ALERT_TABLE } from '../../../screens/alerts'; import { kqlSearch, navigateFromHeaderTo } from '../../../tasks/security_header'; import { ALERTS, CASES } from '../../../screens/security_header'; import { @@ -84,7 +83,9 @@ const customFilters = [ title: 'Rule Name', }, ]; -const assertFilterControlsWithFilterObject = (filterObject = DEFAULT_DETECTION_PAGE_FILTERS) => { +const assertFilterControlsWithFilterObject = ( + filterObject: FilterItemObj[] = DEFAULT_DETECTION_PAGE_FILTERS +) => { cy.get(CONTROL_FRAMES).should((sub) => { expect(sub.length).eq(filterObject.length); }); @@ -97,18 +98,16 @@ const assertFilterControlsWithFilterObject = (filterObject = DEFAULT_DETECTION_P filterObject.forEach((filter, idx) => { cy.get(OPTION_LIST_VALUES(idx)).should((sub) => { - expect(sub.text().replace(',', '')).satisfy((txt: string) => { - return txt.startsWith( - filter.selectedOptions && filter.selectedOptions.length > 0 - ? filter.selectedOptions.join('') - : '' - ); - }); + const selectedOptionsText = + filter.selectedOptions && filter.selectedOptions.length > 0 + ? filter.selectedOptions.join('') + : ''; + expect(sub.text().replace(',', '').replace(' ', '')).to.have.string(selectedOptionsText); }); }); }; -describe('Detections : Page Filters', () => { +describe(`Detections : Page Filters`, () => { before(() => { cleanKibana(); createRule(getNewRule({ rule_id: 'custom_rule_filters' })); @@ -130,6 +129,9 @@ describe('Detections : Page Filters', () => { login(); visit(ALERTS_URL); waitForAlerts(); + }); + + afterEach(() => { resetFilters(); }); @@ -182,10 +184,11 @@ describe('Detections : Page Filters', () => { it('Page filters are loaded with custom values provided in the URL', () => { const NEW_FILTERS = DEFAULT_DETECTION_PAGE_FILTERS.filter((item) => item.persist).map( (filter) => { - if (filter.title === 'Status') { - filter.selectedOptions = ['open', 'acknowledged']; - } - return filter; + return { + ...filter, + selectedOptions: + filter.title === 'Status' ? ['open', 'acknowledged'] : filter.selectedOptions, + }; } ); @@ -231,40 +234,39 @@ describe('Detections : Page Filters', () => { cy.get(FILTER_GROUP_CHANGED_BANNER).should('be.visible'); }); - it(`Alert list is updated when the alerts are updated`, () => { - // mark status of one alert to be acknowledged - selectCountTable(); - cy.get(ALERTS_COUNT) - .invoke('text') - .then((noOfAlerts) => { - const originalAlertCount = noOfAlerts.split(' ')[0]; - markAcknowledgedFirstAlert(); - waitForAlerts(); - cy.get(OPTION_LIST_VALUES(0)).click(); - cy.get(OPTION_SELECTABLE(0, 'acknowledged')).should('be.visible').trigger('click'); - cy.get(ALERTS_COUNT) - .invoke('text') - .should((newAlertCount) => { - expect(newAlertCount.split(' ')[0]).eq(String(parseInt(originalAlertCount, 10) - 1)); - }); - }); + context('with data modificiation', () => { + after(() => { + cleanKibana(); + createRule(getNewRule({ rule_id: 'custom_rule_filters' })); + }); - // cleanup - // revert the changes so that data does not change for further tests. - // It would make sure that tests can run in any order. - cy.get(OPTION_SELECTABLE(0, 'open')).trigger('click'); - togglePageFilterPopover(0); - openFirstAlert(); - waitForAlerts(); + it(`Alert list is updated when the alerts are updated`, () => { + // mark status of one alert to be acknowledged + selectCountTable(); + cy.get(ALERTS_COUNT) + .invoke('text') + .then((noOfAlerts) => { + const originalAlertCount = noOfAlerts.split(' ')[0]; + markAcknowledgedFirstAlert(); + waitForAlerts(); + cy.get(OPTION_LIST_VALUES(0)).click(); + cy.get(OPTION_SELECTABLE(0, 'acknowledged')).should('be.visible').trigger('click'); + cy.get(ALERTS_COUNT) + .invoke('text') + .should((newAlertCount) => { + expect(newAlertCount.split(' ')[0]).eq(String(parseInt(originalAlertCount, 10) - 1)); + }); + }); + }); }); it(`URL is updated when filters are updated`, () => { cy.on('url:changed', (urlString) => { const NEW_FILTERS = DEFAULT_DETECTION_PAGE_FILTERS.map((filter) => { - if (filter.title === 'Severity') { - filter.selectedOptions = ['high']; - } - return filter; + return { + ...filter, + selectedOptions: filter.title === 'Severity' ? ['high'] : filter.selectedOptions, + }; }); const expectedVal = encode(formatPageFilterSearchParam(NEW_FILTERS)); expect(urlString).to.contain.text(expectedVal); @@ -331,7 +333,7 @@ describe('Detections : Page Filters', () => { afterEach(() => { resetFilters(); }); - it('should recover from invalide kql Query result', () => { + it('should recover from invalid kql Query result', () => { // do an invalid search // kqlSearch('\\'); @@ -350,7 +352,7 @@ describe('Detections : Page Filters', () => { waitForPageFilters(); togglePageFilterPopover(0); cy.get(CONTROL_POPOVER(0)).should('contain.text', 'No options found'); - cy.get(OPTION_IGNORED(0, 'open')).should('be.visible'); + cy.get(EMPTY_ALERT_TABLE).should('be.visible'); }); it('should take filters into account', () => { @@ -362,7 +364,7 @@ describe('Detections : Page Filters', () => { waitForPageFilters(); togglePageFilterPopover(0); cy.get(CONTROL_POPOVER(0)).should('contain.text', 'No options found'); - cy.get(OPTION_IGNORED(0, 'open')).should('be.visible'); + cy.get(EMPTY_ALERT_TABLE).should('be.visible'); }); it('should take timeRange into account', () => { const startDateWithZeroAlerts = 'Jan 1, 2002 @ 00:00:00.000'; @@ -375,7 +377,7 @@ describe('Detections : Page Filters', () => { waitForPageFilters(); togglePageFilterPopover(0); cy.get(CONTROL_POPOVER(0)).should('contain.text', 'No options found'); - cy.get(OPTION_IGNORED(0, 'open')).should('be.visible'); + cy.get(EMPTY_ALERT_TABLE).should('be.visible'); }); }); it('Number fields are not visible in field edit panel', () => { diff --git a/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts b/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts index ab56bee03a34b..a4c069c2e2467 100644 --- a/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts +++ b/x-pack/plugins/security_solution/cypress/screens/common/filter_group.ts @@ -21,6 +21,8 @@ export const OPTION_LIST_LABELS = '.controlFrame__labelToolTip'; export const OPTION_LIST_VALUES = (idx: number) => `[data-test-subj="optionsList-control-${idx}"]`; +export const OPTION_LIST_CLEAR_BTN = '.presentationUtil__floatingActions [aria-label="Clear"]'; + export const OPTION_LIST_NUMBER_OFF = '.euiFilterButton__notification'; export const OPTION_LISTS_LOADING = '.optionsList--filterBtnWrapper .euiLoadingSpinner'; @@ -48,7 +50,11 @@ export const DETECTION_PAGE_FILTERS_LOADING = '.securityPageWrapper .controlFram export const DETECTION_PAGE_FILTER_GROUP_LOADING = '[data-test-subj="filter-group__loading"]'; -export const DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU = '[data-test-subj="filter-group__context"]'; +export const DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU_BTN = + '[data-test-subj="filter-group__context"]'; + +export const DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU = + '[data-test-subj="filter-group__context-menu"]'; export const DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON = '[data-test-subj="filter-group__context--reset"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts index 67d61925fa164..0e6a152414763 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts @@ -6,6 +6,7 @@ */ import { encode } from '@kbn/rison'; +import { recurse } from 'cypress-recurse'; import { formatPageFilterSearchParam } from '../../common/utils/format_page_filter_search_param'; import { TOP_N_CONTAINER } from '../screens/network/flows'; import { @@ -63,14 +64,14 @@ import { } from '../screens/alerts_details'; import { FIELD_INPUT } from '../screens/exceptions'; import { + CONTROL_FRAME_TITLE, DETECTION_PAGE_FILTERS_LOADING, - DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU, DETECTION_PAGE_FILTER_GROUP_LOADING, DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON, DETECTION_PAGE_FILTER_GROUP_WRAPPER, - OPTION_LISTS_EXISTS, OPTION_LISTS_LOADING, OPTION_LIST_VALUES, + OPTION_LIST_CLEAR_BTN, OPTION_SELECTABLE, } from '../screens/common/filter_group'; import { LOADING_SPINNER } from '../screens/common/page'; @@ -78,6 +79,7 @@ import { ALERTS_URL } from '../urls/navigation'; import { FIELDS_BROWSER_BTN } from '../screens/rule_details'; import type { FilterItemObj } from '../../public/common/components/filter_group/types'; import { visit } from './login'; +import { openFilterGroupContextMenu } from './common/filter_group'; export const addExceptionFromFirstAlert = () => { expandFirstAlertActions(); @@ -175,23 +177,21 @@ export const closePageFilterPopover = (filterIndex: number) => { cy.get(OPTION_LIST_VALUES(filterIndex)).should('not.have.class', 'euiFilterButton-isSelected'); }; -export const clearAllSelections = () => { - cy.get(OPTION_LISTS_EXISTS).click({ force: true }); - - cy.get(OPTION_LISTS_EXISTS).then(($el) => { - if ($el.attr('aria-checked', 'false')) { - // check it - $el.click(); - } - // uncheck it - $el.click(); - }); +export const clearAllSelections = (filterIndex: number) => { + recurse( + () => { + cy.get(CONTROL_FRAME_TITLE).eq(filterIndex).realHover(); + return cy.get(OPTION_LIST_CLEAR_BTN).eq(filterIndex); + }, + ($el) => $el.is(':visible') + ); + cy.get(OPTION_LIST_CLEAR_BTN).eq(filterIndex).should('be.visible').trigger('click'); }; export const selectPageFilterValue = (filterIndex: number, ...values: string[]) => { refreshAlertPageFilter(); + clearAllSelections(filterIndex); openPageFilterPopover(filterIndex); - clearAllSelections(); values.forEach((value) => { cy.get(OPTION_SELECTABLE(filterIndex, value)).click({ force: true }); }); @@ -407,9 +407,10 @@ export const waitForPageFilters = () => { }; export const resetFilters = () => { - cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU).click({ force: true }); - cy.get(DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON).click({ force: true }); + openFilterGroupContextMenu(); + cy.get(DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON).trigger('click'); waitForPageFilters(); + cy.log('Resetting filters complete'); }; export const parseAlertsCountToInt = (count: string | number) => diff --git a/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts b/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts index b19cf2586ff78..d3b1c5857bb45 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/common/filter_group.ts @@ -5,8 +5,9 @@ * 2.0. */ +import { recurse } from 'cypress-recurse'; import { - DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU, + DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU_BTN, DETECTION_PAGE_FILTER_GROUP_RESET_BUTTON, FILTER_GROUP_ADD_CONTROL, FILTER_GROUP_CONTEXT_EDIT_CONTROLS, @@ -23,11 +24,18 @@ import { OPTION_LISTS_LOADING, FILTER_GROUP_CONTEXT_DISCARD_CHANGES, FILTER_GROUP_CONTROL_ACTION_EDIT, + DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU, } from '../../screens/common/filter_group'; import { waitForPageFilters } from '../alerts'; export const openFilterGroupContextMenu = () => { - cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU).click(); + recurse( + () => { + cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU_BTN).click(); + return cy.get(DETECTION_PAGE_FILTER_GROUP_CONTEXT_MENU).should(Cypress._.noop); + }, + ($el) => $el.length === 1 + ); }; export const waitForFilterGroups = () => { diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts b/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts index 075cbec275c9e..873355fa60a76 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts @@ -5,6 +5,8 @@ * 2.0. */ +import type { AddOptionsListControlProps } from '@kbn/controls-plugin/public'; + export const TEST_IDS = { FILTER_CONTROLS: 'filter-group__items', FILTER_LOADING: 'filter-group__loading', @@ -23,3 +25,20 @@ export const TEST_IDS = { DISCARD: `filter-group__context--discard`, }, }; + +export const COMMON_OPTIONS_LIST_CONTROL_INPUTS: Partial = { + hideExclude: true, + hideSort: true, + hidePanelTitles: true, + placeholder: '', + ignoreParentSettings: { + ignoreValidations: true, + }, +}; + +export const TIMEOUTS = { + /* because of recent changes in controls-plugin debounce time may not be needed + * still keeping the config for some time for any recent changes + * */ + FILTER_UPDATES_DEBOUNCE_TIME: 0, +}; diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx index b7dc2f6f32457..2e77a40a70a80 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/context_menu.tsx @@ -7,7 +7,7 @@ import { EuiButtonIcon, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; -import { TEST_IDS } from './constants'; +import { COMMON_OPTIONS_LIST_CONTROL_INPUTS, TEST_IDS } from './constants'; import { useFilterGroupInternalContext } from './hooks/use_filters'; import { CONTEXT_MENU_RESET, @@ -60,10 +60,7 @@ export const FilterGroupContextMenu = () => { const control = initialControls[counter]; await controlGroup?.addOptionsListControl({ controlId: String(counter), - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, // option List controls will handle an invalid dataview // & display an appropriate message dataViewId: dataViewId ?? '', @@ -139,6 +136,9 @@ export const FilterGroupContextMenu = () => { closePopover={toggleContextMenu} panelPaddingSize="none" anchorPosition="downLeft" + panelProps={{ + 'data-test-subj': TEST_IDS.CONTEXT_MENU.MENU, + }} > diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx index 5600d231df19a..7d3c961473fa9 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_group.test.tsx @@ -26,7 +26,7 @@ import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; import { initialInputData, sampleOutputData } from './mocks/data'; import { createStore } from '../../store'; import { useGetInitialUrlParamValue } from '../../utils/global_query_string/helpers'; -import { TEST_IDS } from './constants'; +import { COMMON_OPTIONS_LIST_CONTROL_INPUTS, TEST_IDS } from './constants'; import { controlGroupFilterInputMock$, controlGroupFilterOutputMock$, @@ -304,7 +304,7 @@ describe(' Filter Group Component ', () => { ); }); - it('should save controls successfully', async () => { + it('should not rebuild controls while saving controls when controls are in desired order', async () => { render(); updateControlGroupInputMock(initialInputData as ControlGroupInput); await openContextMenu(); @@ -314,7 +314,9 @@ describe(' Filter Group Component ', () => { const newInputData = { ...initialInputData, panels: { + // status as persistent controls is first in the position with order as 0 '0': initialInputData.panels['0'], + '1': initialInputData.panels['1'], }, } as ControlGroupInput; @@ -329,10 +331,51 @@ describe(' Filter Group Component ', () => { // edit model gone expect(screen.queryAllByTestId(TEST_IDS.SAVE_CONTROL)).toHaveLength(0); - // check if upsert was called correctely - expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(1); + // check if upsert was called correctly + expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(0); + }); + }); + + it('should rebuild and save controls successfully when controls are not in desired order', async () => { + render(); + updateControlGroupInputMock(initialInputData as ControlGroupInput); + await openContextMenu(); + fireEvent.click(screen.getByTestId(TEST_IDS.CONTEXT_MENU.EDIT)); + + // modify controls + const newInputData = { + ...initialInputData, + panels: { + '0': { + ...initialInputData.panels['0'], + // status is second in position. + // this will force the rebuilding of controls + order: 1, + }, + '1': { + ...initialInputData.panels['1'], + order: 0, + }, + }, + } as ControlGroupInput; + + updateControlGroupInputMock(newInputData); + + // clear any previous calls to the API + controlGroupMock.addOptionsListControl.mockClear(); + + fireEvent.click(screen.getByTestId(TEST_IDS.SAVE_CONTROL)); + + await waitFor(() => { + // edit model gone + expect(screen.queryAllByTestId(TEST_IDS.SAVE_CONTROL)).toHaveLength(0); + + // check if upsert was called correctly + expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(2); + // field id is not required to be passed when creating a control + const { id, ...expectedInputData } = initialInputData.panels['0'].explicitInput; expect(controlGroupMock.addOptionsListControl.mock.calls[0][0]).toMatchObject({ - ...initialInputData.panels['0'].explicitInput, + ...expectedInputData, }); }); }); @@ -363,17 +406,18 @@ describe(' Filter Group Component ', () => { await waitFor(() => { // edit model gone expect(screen.queryAllByTestId(TEST_IDS.SAVE_CONTROL)).toHaveLength(0); - // check if upsert was called correctely + // check if upsert was called correctly expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(2); expect(controlGroupMock.addOptionsListControl.mock.calls[0][0]).toMatchObject({ - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, ...DEFAULT_DETECTION_PAGE_FILTERS[0], }); + + // field id is not required to be passed when creating a control + const { id, ...expectedInputData } = initialInputData.panels['3'].explicitInput; + expect(controlGroupMock.addOptionsListControl.mock.calls[1][0]).toMatchObject({ - ...initialInputData.panels['3'].explicitInput, + ...expectedInputData, }); }); }); @@ -595,18 +639,12 @@ describe(' Filter Group Component ', () => { updateControlGroupInputMock(initialInputData as ControlGroupInput); expect(controlGroupMock.addOptionsListControl.mock.calls.length).toBe(2); expect(controlGroupMock.addOptionsListControl.mock.calls[0][1]).toMatchObject({ - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, ...DEFAULT_DETECTION_PAGE_FILTERS[0], }); expect(controlGroupMock.addOptionsListControl.mock.calls[1][1]).toMatchObject({ - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, fieldName: 'abc', }); diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx index 52629cc58c2b9..dd1f9109a4e1e 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx @@ -6,11 +6,7 @@ */ import type { Filter } from '@kbn/es-query'; -import type { - ControlInputTransform, - ControlPanelState, - OptionsListEmbeddableInput, -} from '@kbn/controls-plugin/common'; +import type { ControlInputTransform } from '@kbn/controls-plugin/common'; import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; import type { ControlGroupInput, @@ -18,6 +14,7 @@ import type { ControlGroupOutput, ControlGroupContainer, ControlGroupRendererProps, + DataControlInput, } from '@kbn/controls-plugin/public'; import { ControlGroupRenderer } from '@kbn/controls-plugin/public'; import type { PropsWithChildren } from 'react'; @@ -26,7 +23,7 @@ import { ViewMode } from '@kbn/embeddable-plugin/public'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import type { Subscription } from 'rxjs'; import styled from 'styled-components'; -import { cloneDeep, debounce, isEqual } from 'lodash'; +import { debounce, isEqual, isEqualWith } from 'lodash'; import type { ControlGroupCreationOptions, FieldFilterPredicate, @@ -43,11 +40,16 @@ import { useControlGroupSyncToLocalStorage } from './hooks/use_control_group_syn import { useViewEditMode } from './hooks/use_view_edit_mode'; import { FilterGroupContextMenu } from './context_menu'; import { AddControl, SaveControls } from './buttons'; -import { getFilterItemObjListFromControlInput } from './utils'; +import { + getFilterControlsComparator, + getFilterItemObjListFromControlInput, + mergeControls, + reorderControlsWithDefaultControls, +} from './utils'; import { FiltersChangedBanner } from './filters_changed_banner'; import { FilterGroupContext } from './filter_group_context'; import { NUM_OF_CONTROLS } from './config'; -import { TEST_IDS } from './constants'; +import { COMMON_OPTIONS_LIST_CONTROL_INPUTS, TEST_IDS, TIMEOUTS } from './constants'; import { URL_PARAM_ARRAY_EXCEPTION_MSG } from './translations'; import { convertToBuildEsQuery } from '../../lib/kuery'; @@ -79,6 +81,15 @@ const FilterGroupComponent = (props: PropsWithChildren) => { const filterChangedSubscription = useRef(); const inputChangedSubscription = useRef(); + const initialControlsObj = useMemo( + () => + initialControls.reduce>((prev, current) => { + prev[current.fieldName] = current; + return prev; + }, {}), + [initialControls] + ); + const [controlGroup, setControlGroup] = useState(); const localStoragePageFilterKey = useMemo( @@ -128,7 +139,9 @@ const FilterGroupComponent = (props: PropsWithChildren) => { const storedControlGroupInput = getStoredControlInput(); if (storedControlGroupInput) { const panelsFormatted = getFilterItemObjListFromControlInput(storedControlGroupInput); - if (!isEqual(panelsFormatted, param)) { + if ( + !isEqualWith(panelsFormatted, param, getFilterControlsComparator('fieldName', 'title')) + ) { setShowFiltersChangedBanner(true); switchToEditMode(); } @@ -203,8 +216,12 @@ const FilterGroupComponent = (props: PropsWithChildren) => { ); const handleOutputFilterUpdates = useCallback( - ({ filters: newFilters }: ControlGroupOutput) => { + ({ filters: newFilters, embeddableLoaded }: ControlGroupOutput) => { + const haveAllEmbeddablesLoaded = Object.values(embeddableLoaded).every((v) => + Boolean(v ?? true) + ); if (isEqual(currentFiltersRef.current, newFilters)) return; + if (!haveAllEmbeddablesLoaded) return; if (onFilterChange) onFilterChange(newFilters ?? []); currentFiltersRef.current = newFilters ?? []; }, @@ -212,7 +229,7 @@ const FilterGroupComponent = (props: PropsWithChildren) => { ); const debouncedFilterUpdates = useMemo( - () => debounce(handleOutputFilterUpdates, 500), + () => debounce(handleOutputFilterUpdates, TIMEOUTS.FILTER_UPDATES_DEBOUNCE_TIME), [handleOutputFilterUpdates] ); @@ -253,53 +270,35 @@ const FilterGroupComponent = (props: PropsWithChildren) => { * * */ - const localInitialControls = cloneDeep(initialControls).filter( - (control) => control.persist === true - ); - let resultControls = [] as FilterItemObj[]; - - let overridingControls = initialUrlParam; - if (!initialUrlParam || initialUrlParam.length === 0) { - // if nothing is found in URL Param.. read from local storage - const storedControlGroupInput = getStoredControlInput(); - if (storedControlGroupInput) { - const urlParamsFromLocalStorage: FilterItemObj[] = - getFilterItemObjListFromControlInput(storedControlGroupInput); - - overridingControls = urlParamsFromLocalStorage; - } + const controlsFromURL = initialUrlParam ?? []; + let controlsFromLocalStorage: FilterItemObj[] = []; + const storedControlGroupInput = getStoredControlInput(); + if (storedControlGroupInput) { + controlsFromLocalStorage = getFilterItemObjListFromControlInput(storedControlGroupInput); } + let overridingControls = mergeControls({ + controlsWithPriority: [controlsFromURL, controlsFromLocalStorage], + defaultControlsObj: initialControlsObj, + }); if (!overridingControls || overridingControls.length === 0) return initialControls; - // if initialUrlParam Exists... replace localInitialControls with what was provided in the Url - if (overridingControls && !urlDataApplied.current) { - if (localInitialControls.length > 0) { - localInitialControls.forEach((persistControl) => { - const doesPersistControlAlreadyExist = overridingControls?.some( - (control) => control.fieldName === persistControl.fieldName - ); - - if (!doesPersistControlAlreadyExist) { - resultControls.push(persistControl); - } - }); - } - - resultControls = [ - ...resultControls, - ...overridingControls.map((item) => ({ - fieldName: item.fieldName, - title: item.title, - selectedOptions: item.selectedOptions ?? [], - existsSelected: item.existsSelected ?? false, - exclude: item.exclude, - })), - ]; - } + overridingControls = overridingControls.map((item) => { + return { + // give default value to params which are coming from the URL + fieldName: item.fieldName, + title: item.title, + selectedOptions: item.selectedOptions ?? [], + existsSelected: item.existsSelected ?? false, + exclude: item.exclude, + }; + }); - return resultControls; - }, [initialUrlParam, initialControls, getStoredControlInput]); + return reorderControlsWithDefaultControls({ + controls: overridingControls, + defaultControls: initialControls, + }); + }, [initialUrlParam, initialControls, getStoredControlInput, initialControlsObj]); const fieldFilterPredicate: FieldFilterPredicate = useCallback((f) => f.type !== 'number', []); @@ -325,10 +324,7 @@ const FilterGroupComponent = (props: PropsWithChildren) => { finalControls.forEach((control, idx) => { addOptionsListControl(initialInput, { controlId: String(idx), - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, // option List controls will handle an invalid dataview // & display an appropriate message dataViewId: dataViewId ?? '', @@ -376,48 +372,29 @@ const FilterGroupComponent = (props: PropsWithChildren) => { }, [controlGroup, switchToViewMode, getStoredControlInput, hasPendingChanges]); const upsertPersistableControls = useCallback(async () => { - const persistableControls = initialControls.filter((control) => control.persist === true); - if (persistableControls.length > 0) { - const currentPanels = Object.values(controlGroup?.getInput().panels ?? []) as Array< - ControlPanelState - >; - const orderedPanels = currentPanels.sort((a, b) => a.order - b.order); - let filterControlsDeleted = false; - for (const control of persistableControls) { - const controlExists = currentPanels.some( - (currControl) => control.fieldName === currControl.explicitInput.fieldName - ); - if (!controlExists) { - // delete current controls - if (!filterControlsDeleted) { - controlGroup?.updateInput({ panels: {} }); - filterControlsDeleted = true; - } - - // add persitable controls - await controlGroup?.addOptionsListControl({ - title: control.title, - hideExclude: true, - hideSort: true, - hidePanelTitles: true, - placeholder: '', - // option List controls will handle an invalid dataview - // & display an appropriate message - dataViewId: dataViewId ?? '', - selectedOptions: control.selectedOptions, - ...control, - }); - } - } + if (!controlGroup) return; + const currentPanels = getFilterItemObjListFromControlInput(controlGroup.getInput()); + + const reorderedControls = reorderControlsWithDefaultControls({ + controls: currentPanels, + defaultControls: initialControls, + }); + + if (!isEqualWith(reorderedControls, currentPanels, getFilterControlsComparator('fieldName'))) { + // reorder only if fields are in different order + // or not same. + controlGroup?.updateInput({ panels: {} }); - for (const panel of orderedPanels) { - if (panel.explicitInput.fieldName) - await controlGroup?.addOptionsListControl({ - selectedOptions: [], - fieldName: panel.explicitInput.fieldName, - dataViewId: dataViewId ?? '', - ...panel.explicitInput, - }); + for (const control of reorderedControls) { + await controlGroup?.addOptionsListControl({ + title: control.title, + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, + // option List controls will handle an invalid dataview + // & display an appropriate message + dataViewId: dataViewId ?? '', + selectedOptions: control.selectedOptions, + ...control, + }); } } }, [controlGroup, dataViewId, initialControls]); @@ -428,23 +405,36 @@ const FilterGroupComponent = (props: PropsWithChildren) => { setShowFiltersChangedBanner(false); }, [switchToViewMode, upsertPersistableControls]); - const newControlInputTranform: ControlInputTransform = (newInput, controlType) => { - // for any new controls, we want to avoid - // default placeholder - if (controlType === OPTIONS_LIST_CONTROL) { - return { - ...newInput, - placeholder: '', - }; - } - return newInput; - }; + const newControlInputTranform: ControlInputTransform = useCallback( + (newInput, controlType) => { + // for any new controls, we want to avoid + // default placeholder + let result = newInput; + if (controlType === OPTIONS_LIST_CONTROL) { + result = { + ...newInput, + ...COMMON_OPTIONS_LIST_CONTROL_INPUTS, + }; + + if ((newInput as DataControlInput).fieldName in initialControlsObj) { + result = { + ...result, + ...initialControlsObj[(newInput as DataControlInput).fieldName], + // title should not be overridden by the initial controls, hence the hardcoding + title: newInput.title ?? result.title, + }; + } + } + return result; + }, + [initialControlsObj] + ); const addControlsHandler = useCallback(() => { controlGroup?.openAddDataControlFlyout({ controlInputTransform: newControlInputTranform, }); - }, [controlGroup]); + }, [controlGroup, newControlInputTranform]); return ( void; } -export type FilterItemObj = Omit & - Pick; +export type FilterItemObj = Omit & { + /* + * Determines the present and order of a control + * + * */ + persist?: boolean; +}; export type FilterGroupHandler = ControlGroupContainer; export type FilterGroupProps = { dataViewId: string | null; onFilterChange?: (newFilters: Filter[]) => void; - initialControls: Array; + initialControls: FilterItemObj[]; spaceId: string; onInit?: (controlGroupHandler: FilterGroupHandler | undefined) => void; } & Pick; diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts index edcffd7502df9..f2f860710ac84 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.test.ts @@ -6,9 +6,64 @@ */ import type { ControlGroupInput } from '@kbn/controls-plugin/common'; -import { getFilterItemObjListFromControlInput } from './utils'; +import { + getFilterItemObjListFromControlInput, + mergeControls, + reorderControlsWithDefaultControls, + getFilterControlsComparator, +} from './utils'; import { initialInputData } from './mocks/data'; +import type { FilterItemObj } from './types'; +import { isEqualWith } from 'lodash'; +const defaultControls: FilterItemObj[] = [ + { + fieldName: 'first', + hideActionBar: true, + selectedOptions: ['val1', 'val2'], + }, + + { + fieldName: 'second', + hideActionBar: true, + selectedOptions: ['val1', 'val2'], + persist: true, + }, +]; + +const firstControlsSet: FilterItemObj[] = [ + { + fieldName: 'first', + selectedOptions: ['firstVal'], + }, +]; + +const secondControlsSet: FilterItemObj[] = [ + { + fieldName: 'first', + selectedOptions: ['secondVal1', 'secondVal2'], + existsSelected: true, + }, + { + fieldName: 'second', + hideActionBar: false, + exclude: true, + }, +]; + +const thirdControlsSet: FilterItemObj[] = [ + { + fieldName: 'new', + selectedOptions: [], + }, +]; + +const emptyControlSet: FilterItemObj[] = []; + +const defaultControlsObj = defaultControls.reduce((prev, current) => { + prev[current.fieldName] = current; + return prev; +}, {} as Record); describe('utils', () => { describe('getFilterItemObjListFromControlOutput', () => { it('should return ordered filterItem where passed in order', () => { @@ -61,4 +116,172 @@ describe('utils', () => { }); }); }); + + describe('mergeControls', () => { + it('should return first controls set when it is not empty', () => { + const result = mergeControls({ + controlsWithPriority: [firstControlsSet, secondControlsSet], + defaultControlsObj, + }); + + const expectedResult = [ + { + fieldName: 'first', + selectedOptions: ['firstVal'], + hideActionBar: true, + }, + ]; + + expect(result).toMatchObject(expectedResult); + }); + + it('should return second controls set when first one is empty', () => { + const result = mergeControls({ + controlsWithPriority: [emptyControlSet, secondControlsSet], + defaultControlsObj, + }); + + const expectedResult = [ + { + fieldName: 'first', + selectedOptions: ['secondVal1', 'secondVal2'], + hideActionBar: true, + existsSelected: true, + }, + { + fieldName: 'second', + selectedOptions: ['val1', 'val2'], + hideActionBar: false, + exclude: true, + persist: true, + }, + ]; + + expect(result).toMatchObject(expectedResult); + }); + + it('should return controls as it is when default control for a field does not exist', () => { + const result = mergeControls({ + controlsWithPriority: [emptyControlSet, emptyControlSet, thirdControlsSet], + defaultControlsObj, + }); + const expectedResult = thirdControlsSet; + expect(result).toMatchObject(expectedResult); + }); + + it('should return default controls if no priority controls are given', () => { + const result = mergeControls({ + controlsWithPriority: [emptyControlSet, emptyControlSet, emptyControlSet], + defaultControlsObj, + }); + + expect(result).toBeUndefined(); + }); + }); + + describe('reorderControls', () => { + it('should add persist controls in order if they are not available in the given controls', () => { + const newControlsSet: FilterItemObj[] = [ + { + fieldName: 'new', + }, + ]; + + const result = reorderControlsWithDefaultControls({ + controls: newControlsSet, + defaultControls, + }); + + const expectedResult = [ + { + fieldName: 'second', + hideActionBar: true, + selectedOptions: ['val1', 'val2'], + persist: true, + }, + { + fieldName: 'new', + }, + ]; + + expect(result).toMatchObject(expectedResult); + }); + it('should change controls order if they are available in the given controls', () => { + const newControlsSet: FilterItemObj[] = [ + { + fieldName: 'new', + }, + { + fieldName: 'second', + selectedOptions: ['val2'], + hideActionBar: false, + }, + { + fieldName: 'first', + selectedOptions: [], + }, + ]; + + const expectedResult = [ + { + fieldName: 'second', + selectedOptions: ['val2'], + hideActionBar: false, + persist: true, + }, + { + fieldName: 'new', + }, + { + fieldName: 'first', + selectedOptions: [], + hideActionBar: true, + }, + ]; + + const result = reorderControlsWithDefaultControls({ + controls: newControlsSet, + defaultControls, + }); + + expect(result).toMatchObject(expectedResult); + }); + }); + + describe('getFilterControlsComparator', () => { + it('should return true when controls are equal and and list of field is empty', () => { + const comparator = getFilterControlsComparator(); + const result = isEqualWith(defaultControls, defaultControls, comparator); + + expect(result).toBe(true); + }); + it('should return false when arrays of different length', () => { + const comparator = getFilterControlsComparator(); + const result = isEqualWith(defaultControls, thirdControlsSet, comparator); + + expect(result).toBe(false); + }); + it('should return true when given set of fields match ', () => { + const comparator = getFilterControlsComparator('fieldName'); + const result = isEqualWith(defaultControls, secondControlsSet, comparator); + + expect(result).toBe(true); + }); + it("should return false when given set of fields don't match ", () => { + const comparator = getFilterControlsComparator('fieldName', 'selectedOptions'); + const result = isEqualWith(defaultControls, secondControlsSet, comparator); + expect(result).toBe(false); + }); + + it('should return true when comparing empty set of filter controls', () => { + const comparator = getFilterControlsComparator('fieldName', 'selectedOptions'); + const result = isEqualWith([], [], comparator); + expect(result).toBe(true); + }); + it('should return false when comparing one empty and one non-empty set of filter controls', () => { + const comparator = getFilterControlsComparator('fieldName', 'selectedOptions'); + const result = isEqualWith(defaultControls, [], comparator); + expect(result).toBe(false); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts index 6523ff61b2060..c005621831d5b 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/utils.ts @@ -11,6 +11,9 @@ import type { OptionsListEmbeddableInput, } from '@kbn/controls-plugin/common'; +import { isEmpty, isEqual, pick } from 'lodash'; +import type { FilterItemObj } from './types'; + export const getPanelsInOrderFromControlsInput = (controlInput: ControlGroupInput) => { const panels = controlInput.panels; @@ -21,7 +24,7 @@ export const getFilterItemObjListFromControlInput = (controlInput: ControlGroupI const panels = getPanelsInOrderFromControlsInput(controlInput); return panels.map((panel) => { const { - explicitInput: { fieldName, selectedOptions, title, existsSelected, exclude }, + explicitInput: { fieldName, selectedOptions, title, existsSelected, exclude, hideActionBar }, } = panel as ControlPanelState; return { @@ -30,6 +33,115 @@ export const getFilterItemObjListFromControlInput = (controlInput: ControlGroupI title, existsSelected: existsSelected ?? false, exclude: exclude ?? false, + hideActionBar: hideActionBar ?? false, }; }); }; + +interface MergableControlsArgs { + /* + * Set of controls that need be merged with priority + * Set of controls with lower index take priority over the next one. + * + * Final set of controls is merged with the defaulControls + * + */ + controlsWithPriority: FilterItemObj[][]; + defaultControlsObj: Record; +} + +/* + * mergeControls merges controls based on priority with the default controls + * + * @return undefined if all provided controls are empty + * */ +export const mergeControls = ({ + controlsWithPriority, + defaultControlsObj, +}: MergableControlsArgs) => { + const highestPriorityControlSet = controlsWithPriority.find((control) => !isEmpty(control)); + + return highestPriorityControlSet?.map((singleControl) => { + if (singleControl.fieldName in defaultControlsObj) { + return { + ...defaultControlsObj[singleControl.fieldName], + ...singleControl, + }; + } + return singleControl; + }); +}; + +interface ReorderControlsArgs { + /* + * Ordered Controls + * + * */ + controls: FilterItemObj[]; + /* + * default controls in order + * */ + defaultControls: FilterItemObj[]; +} + +/** + * reorderControlsWithPersistentControls reorders the controls such that controls which + * are persistent in default controls should be upserted in given order + * + * */ +export const reorderControlsWithDefaultControls = (args: ReorderControlsArgs) => { + const { controls, defaultControls } = args; + const controlsObject = controls.reduce((prev, current) => { + prev[current.fieldName] = current; + return prev; + }, {} as Record); + + const defaultControlsObj = defaultControls.reduce((prev, current) => { + prev[current.fieldName] = current; + return prev; + }, {} as Record); + + const resultDefaultControls: FilterItemObj[] = defaultControls + .filter((defaultControl) => defaultControl.persist) + .map((defaultControl) => { + return { + ...defaultControl, + ...(controlsObject[defaultControl.fieldName] ?? {}), + }; + }); + + const resultNonPersitantControls = controls + .filter( + // filter out persisting controls since we have already taken + // in account above + (control) => !defaultControlsObj[control.fieldName]?.persist + ) + .map((control) => ({ + // insert some default properties from default controls + // irrespective of whether they are persistent or not. + ...(defaultControlsObj[control.fieldName] ?? {}), + ...control, + })); + + return [...resultDefaultControls, ...resultNonPersitantControls]; +}; + +/* + * getFilterControlsComparator provides a comparator that can be used with `isEqualWith` to compare + * 2 instances of FilterItemObj + * + * */ +export const getFilterControlsComparator = + (...fieldsToCompare: Array) => + (filterItemObject1: FilterItemObj[], filterItemObject2: FilterItemObj[]) => { + if (filterItemObject1.length !== filterItemObject2.length) return false; + const filterItemObjectWithSelectedKeys1 = filterItemObject1.map((v) => { + return pick(v, fieldsToCompare); + }); + + const filterItemObjectWithSelectedKeys2 = filterItemObject2.map((v) => { + return pick(v, fieldsToCompare); + }); + + return isEqual(filterItemObjectWithSelectedKeys1, filterItemObjectWithSelectedKeys2); + }; From 472d843fbc81ba386b273c71dd3c4bfc4784518b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Tue, 4 Jul 2023 14:45:57 +0200 Subject: [PATCH 08/64] [Enterprise Search] Remove access control as well if exists (#161122) ## Summary - Add access control remove - Deletes access control index too after content index is deleted. ### Checklist Delete any items that are not applicable to this PR. - [ ] [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> --- .../indices/delete_access_control_index.ts | 22 +++++++++++++++++++ .../routes/enterprise_search/indices.ts | 2 ++ .../plugins/enterprise_search/tsconfig.json | 1 + 3 files changed, 25 insertions(+) create mode 100644 x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts new file mode 100644 index 0000000000000..2df773b1af30e --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isIndexNotFoundException } from '@kbn/core-saved-objects-migration-server-internal'; +import { IScopedClusterClient } from '@kbn/core/server'; + +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../..'; + +export const deleteAccessControlIndex = async (client: IScopedClusterClient, index: string) => { + try { + await client.asCurrentUser.indices.delete({ + index: index.replace('search-', CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX), + }); + } catch (e) { + // Gracefully exit if index not found. This is a valid case. + if (!isIndexNotFoundException(e)) throw e; + } +}; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts index 81233d842d629..5b5a0c7e99b9b 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts @@ -26,6 +26,7 @@ import { fetchConnectorByIndexName, fetchConnectors } from '../../lib/connectors import { fetchCrawlerByIndexName, fetchCrawlers } from '../../lib/crawler/fetch_crawlers'; import { createIndex } from '../../lib/indices/create_index'; +import { deleteAccessControlIndex } from '../../lib/indices/delete_access_control_index'; import { indexOrAliasExists } from '../../lib/indices/exists_index'; import { fetchIndex } from '../../lib/indices/fetch_index'; import { fetchIndices, fetchSearchIndices } from '../../lib/indices/fetch_indices'; @@ -201,6 +202,7 @@ export function registerIndexRoutes({ } await deleteIndexPipelines(client, indexName); + await deleteAccessControlIndex(client, indexName); await client.asCurrentUser.indices.delete({ index: indexName }); diff --git a/x-pack/plugins/enterprise_search/tsconfig.json b/x-pack/plugins/enterprise_search/tsconfig.json index 0ea008f3691f5..f8407385478f5 100644 --- a/x-pack/plugins/enterprise_search/tsconfig.json +++ b/x-pack/plugins/enterprise_search/tsconfig.json @@ -61,5 +61,6 @@ "@kbn/shared-ux-link-redirect-app", "@kbn/global-search-plugin", "@kbn/share-plugin", + "@kbn/core-saved-objects-migration-server-internal", ] } From 2a71469894af46716e5b40cfff981a0fb3448901 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Tue, 4 Jul 2023 15:43:47 +0200 Subject: [PATCH 09/64] [Deployment Management] Add landing page redirect feature and implement in security solution (#161060) --- src/plugins/management/README.md | 12 ++- .../management_app/management_app.tsx | 8 +- .../management_app/management_router.tsx | 96 ++++++++++++------- src/plugins/management/public/mocks/index.ts | 1 + src/plugins/management/public/plugin.ts | 4 + src/plugins/management/public/types.ts | 1 + src/plugins/management/tsconfig.json | 4 +- .../plugins/serverless_security/kibana.jsonc | 1 + .../public/common/services.mock.tsx | 2 + .../serverless_security/public/plugin.ts | 4 +- .../serverless_security/public/types.ts | 3 + .../plugins/serverless_security/tsconfig.json | 1 + .../test_serverless/functional/config.base.ts | 3 + .../functional/test_suites/security/index.ts | 1 + .../test_suites/security/management.ts | 25 +++++ 15 files changed, 126 insertions(+), 40 deletions(-) create mode 100644 x-pack/test_serverless/functional/test_suites/security/management.ts diff --git a/src/plugins/management/README.md b/src/plugins/management/README.md index 354fe766d473a..828715235b1b9 100644 --- a/src/plugins/management/README.md +++ b/src/plugins/management/README.md @@ -38,4 +38,14 @@ If card needs to be hidden from the navigation you can specify that by using the }); ``` -More specifics about the `setupCardsNavigation` can be found in `packages/kbn-management/cards_navigation/readme.mdx`. \ No newline at end of file +More specifics about the `setupCardsNavigation` can be found in `packages/kbn-management/cards_navigation/readme.mdx`. + +## Landing page redirect + +If the consumer wants to have a separate landing page for the management section, they can use the `setLandingPageRedirect` +method to specify the path to the landing page: + + +``` + management.setLandingPageRedirect('/app/security/management'); +``` \ No newline at end of file diff --git a/src/plugins/management/public/components/management_app/management_app.tsx b/src/plugins/management/public/components/management_app/management_app.tsx index 133d19250085a..538da6045255a 100644 --- a/src/plugins/management/public/components/management_app/management_app.tsx +++ b/src/plugins/management/public/components/management_app/management_app.tsx @@ -43,6 +43,7 @@ export interface ManagementAppDependencies { setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void; isSidebarEnabled$: BehaviorSubject; cardsNavigationConfig$: BehaviorSubject; + landingPageRedirect$: BehaviorSubject; } export const ManagementApp = ({ @@ -51,11 +52,13 @@ export const ManagementApp = ({ theme$, appBasePath, }: ManagementAppProps) => { - const { setBreadcrumbs, isSidebarEnabled$, cardsNavigationConfig$ } = dependencies; + const { setBreadcrumbs, isSidebarEnabled$, cardsNavigationConfig$, landingPageRedirect$ } = + dependencies; const [selectedId, setSelectedId] = useState(''); const [sections, setSections] = useState(); const isSidebarEnabled = useObservable(isSidebarEnabled$); const cardsNavigationConfig = useObservable(cardsNavigationConfig$); + const landingPageRedirect = useObservable(landingPageRedirect$); const onAppMounted = useCallback((id: string) => { setSelectedId(id); @@ -131,6 +134,9 @@ export const ManagementApp = ({ setBreadcrumbs={setBreadcrumbsScoped} onAppMounted={onAppMounted} sections={sections} + landingPageRedirect={landingPageRedirect} + navigateToUrl={dependencies.coreStart.application.navigateToUrl} + basePath={dependencies.coreStart.http.basePath} /> diff --git a/src/plugins/management/public/components/management_app/management_router.tsx b/src/plugins/management/public/components/management_app/management_router.tsx index ad9a6e41989ce..9335af3bf5b78 100644 --- a/src/plugins/management/public/components/management_app/management_router.tsx +++ b/src/plugins/management/public/components/management_app/management_router.tsx @@ -6,10 +6,12 @@ * Side Public License, v 1. */ -import React, { memo } from 'react'; +import React, { memo, useEffect } from 'react'; import { Redirect } from 'react-router-dom'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { AppMountParameters, ChromeBreadcrumb, ScopedHistory } from '@kbn/core/public'; +import type { ApplicationStart } from '@kbn/core-application-browser'; +import type { HttpStart } from '@kbn/core-http-browser'; import { ManagementAppWrapper } from '../management_app_wrapper'; import { ManagementLandingPage } from '../landing'; import { ManagementSection } from '../../utils'; @@ -20,43 +22,65 @@ interface ManagementRouterProps { setBreadcrumbs: (crumbs?: ChromeBreadcrumb[], appHistory?: ScopedHistory) => void; onAppMounted: (id: string) => void; sections: ManagementSection[]; + landingPageRedirect: string | undefined; + navigateToUrl: ApplicationStart['navigateToUrl']; + basePath: HttpStart['basePath']; } export const ManagementRouter = memo( - ({ history, setBreadcrumbs, onAppMounted, sections, theme$ }: ManagementRouterProps) => ( - - - {sections.map((section) => - section - .getAppsEnabled() - .map((app) => ( - ( - - )} - /> - )) - )} - {sections.map((section) => - section - .getAppsEnabled() - .filter((app) => app.redirectFrom) - .map((app) => ) - )} - ( - + ({ + history, + setBreadcrumbs, + onAppMounted, + sections, + theme$, + landingPageRedirect, + navigateToUrl, + basePath, + }: ManagementRouterProps) => { + // Redirect the user to the configured landing page if there is one + useEffect(() => { + if (landingPageRedirect) { + navigateToUrl(basePath.prepend(landingPageRedirect)); + } + }, [landingPageRedirect, navigateToUrl, basePath]); + + return ( + + + {sections.map((section) => + section + .getAppsEnabled() + .map((app) => ( + ( + + )} + /> + )) + )} + {sections.map((section) => + section + .getAppsEnabled() + .filter((app) => app.redirectFrom) + .map((app) => ) )} - /> - - - ) + + ( + + )} + /> + + + ); + } ); diff --git a/src/plugins/management/public/mocks/index.ts b/src/plugins/management/public/mocks/index.ts index 93ccefbe5130f..bc6bdcdc46814 100644 --- a/src/plugins/management/public/mocks/index.ts +++ b/src/plugins/management/public/mocks/index.ts @@ -44,6 +44,7 @@ const createSetupContract = (): ManagementSetup => ({ const createStartContract = (): ManagementStart => ({ setIsSidebarEnabled: jest.fn(), setupCardsNavigation: jest.fn(), + setLandingPageRedirect: jest.fn(), }); export const managementPluginMock = { diff --git a/src/plugins/management/public/plugin.ts b/src/plugins/management/public/plugin.ts index 712799de2f65c..445a9b3a3db0a 100644 --- a/src/plugins/management/public/plugin.ts +++ b/src/plugins/management/public/plugin.ts @@ -72,6 +72,7 @@ export class ManagementPlugin private hasAnyEnabledApps = true; private isSidebarEnabled$ = new BehaviorSubject(true); + private landingPageRedirect$ = new BehaviorSubject(undefined); private cardsNavigationConfig$ = new BehaviorSubject({ enabled: false, hideLinksTo: [], @@ -124,6 +125,7 @@ export class ManagementPlugin setBreadcrumbs: coreStart.chrome.setBreadcrumbs, isSidebarEnabled$: managementPlugin.isSidebarEnabled$, cardsNavigationConfig$: managementPlugin.cardsNavigationConfig$, + landingPageRedirect$: managementPlugin.landingPageRedirect$, }); }, }); @@ -154,6 +156,8 @@ export class ManagementPlugin this.isSidebarEnabled$.next(isSidebarEnabled), setupCardsNavigation: ({ enabled, hideLinksTo }) => this.cardsNavigationConfig$.next({ enabled, hideLinksTo }), + setLandingPageRedirect: (landingPageRedirect: string) => + this.landingPageRedirect$.next(landingPageRedirect), }; } } diff --git a/src/plugins/management/public/types.ts b/src/plugins/management/public/types.ts index e2b5353d8995c..52e66698629fd 100644 --- a/src/plugins/management/public/types.ts +++ b/src/plugins/management/public/types.ts @@ -30,6 +30,7 @@ export interface DefinedSections { export interface ManagementStart { setIsSidebarEnabled: (enabled: boolean) => void; + setLandingPageRedirect: (landingPageRedirect: string) => void; setupCardsNavigation: ({ enabled, hideLinksTo }: NavigationCardsSubject) => void; } diff --git a/src/plugins/management/tsconfig.json b/src/plugins/management/tsconfig.json index 019867f387387..aeb231f2ea9ed 100644 --- a/src/plugins/management/tsconfig.json +++ b/src/plugins/management/tsconfig.json @@ -22,7 +22,9 @@ "@kbn/shared-ux-router", "@kbn/management-cards-navigation", "@kbn/shared-ux-link-redirect-app", - "@kbn/test-jest-helpers" + "@kbn/test-jest-helpers", + "@kbn/core-application-browser", + "@kbn/core-http-browser" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/serverless_security/kibana.jsonc b/x-pack/plugins/serverless_security/kibana.jsonc index daa7490a38651..306918ed70697 100644 --- a/x-pack/plugins/serverless_security/kibana.jsonc +++ b/x-pack/plugins/serverless_security/kibana.jsonc @@ -14,6 +14,7 @@ ], "requiredPlugins": [ "kibanaReact", + "management", "ml", "security", "securitySolution", diff --git a/x-pack/plugins/serverless_security/public/common/services.mock.tsx b/x-pack/plugins/serverless_security/public/common/services.mock.tsx index 70f024842a340..a3aba806af18c 100644 --- a/x-pack/plugins/serverless_security/public/common/services.mock.tsx +++ b/x-pack/plugins/serverless_security/public/common/services.mock.tsx @@ -12,6 +12,7 @@ import { serverlessMock } from '@kbn/serverless/public/mocks'; import { securityMock } from '@kbn/security-plugin/public/mocks'; import { securitySolutionMock } from '@kbn/security-solution-plugin/public/mocks'; import { BehaviorSubject } from 'rxjs'; +import { managementPluginMock } from '@kbn/management-plugin/public/mocks'; import type { ProjectNavigationLink } from './navigation/links'; import type { Services } from './services'; @@ -23,6 +24,7 @@ export const servicesMocks: Services = { security: securityMock.createStart(), securitySolution: securitySolutionMock.createStart(), getProjectNavLinks$: jest.fn(() => new BehaviorSubject(mockProjectNavLinks())), + management: managementPluginMock.createStartContract(), }; export const KibanaServicesProvider = React.memo(({ children }) => ( diff --git a/x-pack/plugins/serverless_security/public/plugin.ts b/x-pack/plugins/serverless_security/public/plugin.ts index 356aea4f2c345..acc7854a363b0 100644 --- a/x-pack/plugins/serverless_security/public/plugin.ts +++ b/x-pack/plugins/serverless_security/public/plugin.ts @@ -48,7 +48,7 @@ export class ServerlessSecurityPlugin core: CoreStart, startDeps: ServerlessSecurityPluginStartDependencies ): ServerlessSecurityPluginStart { - const { securitySolution, serverless } = startDeps; + const { securitySolution, serverless, management } = startDeps; const { productTypes } = this.config; const services = createServices(core, startDeps); @@ -62,6 +62,8 @@ export class ServerlessSecurityPlugin subscribeNavigationTree(services); subscribeBreadcrumbs(services); + management.setLandingPageRedirect('/app/security/manage'); + return {}; } diff --git a/x-pack/plugins/serverless_security/public/types.ts b/x-pack/plugins/serverless_security/public/types.ts index 3954183cc9749..73052810127ad 100644 --- a/x-pack/plugins/serverless_security/public/types.ts +++ b/x-pack/plugins/serverless_security/public/types.ts @@ -11,6 +11,7 @@ import type { PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/public'; import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public'; +import { ManagementSetup, ManagementStart } from '@kbn/management-plugin/public'; import type { SecurityProductTypes } from '../common/config'; // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -23,12 +24,14 @@ export interface ServerlessSecurityPluginSetupDependencies { security: SecurityPluginSetup; securitySolution: SecuritySolutionPluginSetup; serverless: ServerlessPluginSetup; + management: ManagementSetup; } export interface ServerlessSecurityPluginStartDependencies { security: SecurityPluginStart; securitySolution: SecuritySolutionPluginStart; serverless: ServerlessPluginStart; + management: ManagementStart; } export interface ServerlessSecurityPublicConfig { diff --git a/x-pack/plugins/serverless_security/tsconfig.json b/x-pack/plugins/serverless_security/tsconfig.json index 69d976d324105..2d2d3b8d34e6a 100644 --- a/x-pack/plugins/serverless_security/tsconfig.json +++ b/x-pack/plugins/serverless_security/tsconfig.json @@ -17,6 +17,7 @@ "kbn_references": [ "@kbn/core", "@kbn/config-schema", + "@kbn/management-plugin", "@kbn/security-plugin", "@kbn/security-solution-plugin", "@kbn/serverless", diff --git a/x-pack/test_serverless/functional/config.base.ts b/x-pack/test_serverless/functional/config.base.ts index 81a3f197a0ec0..23739a9615e69 100644 --- a/x-pack/test_serverless/functional/config.base.ts +++ b/x-pack/test_serverless/functional/config.base.ts @@ -52,6 +52,9 @@ export function createTestConfig(options: CreateTestConfigOptions) { observability: { pathname: '/app/observability', }, + management: { + pathname: '/app/management', + }, }, // choose where screenshots should be saved screenshots: { diff --git a/x-pack/test_serverless/functional/test_suites/security/index.ts b/x-pack/test_serverless/functional/test_suites/security/index.ts index 470f1e98082e8..4d31c06188bcf 100644 --- a/x-pack/test_serverless/functional/test_suites/security/index.ts +++ b/x-pack/test_serverless/functional/test_suites/security/index.ts @@ -10,5 +10,6 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless security UI', function () { loadTestFile(require.resolve('./landing_page')); + loadTestFile(require.resolve('./management')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/security/management.ts b/x-pack/test_serverless/functional/test_suites/security/management.ts new file mode 100644 index 0000000000000..f610e7b25ca73 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/security/management.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getPageObject }: FtrProviderContext) { + const PageObject = getPageObject('common'); + + describe('Management', function () { + it('redirects from common management url to security specific page', async () => { + const SUB_URL = ''; + await PageObject.navigateToUrl('management', SUB_URL, { + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + shouldUseHashForSubUrl: false, + }); + + await PageObject.waitUntilUrlIncludes('/security/manage'); + }); + }); +} From b340cb301bd47c6ba3fd13873c901ac01a5bf717 Mon Sep 17 00:00:00 2001 From: Stef Nestor <26751266+stefnestor@users.noreply.github.com> Date: Tue, 4 Jul 2023 09:26:43 -0500 Subject: [PATCH 10/64] [DOC+] License not available is KB-ES connection error (#161176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 👋🏼 howdy, team! When Kibana can't connect to Elasticsearch (past finding master / network issue, just unhealthy cluster ballpark), its code logic cascades into first tripping warn/error log `license is not available`. This is a red-herring in that the license can not be determined and user should investigate the network connection / Elasticsearch health rather than investigating for lapsed licenses. Adding this into the "Kibana not ready" docs since it raises at this point in the flow to hopefully allow users to search-find it in our official docs rather than e.g. top-goggle-results: [Elastic Discuss](https://discuss.elastic.co/t/license-not-available/265931), [external Github](https://github.com/spujadas/elk-docker/issues/349). --- docs/setup/access.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/setup/access.asciidoc b/docs/setup/access.asciidoc index 2b76843b5964d..631fa22d711dd 100644 --- a/docs/setup/access.asciidoc +++ b/docs/setup/access.asciidoc @@ -61,5 +61,5 @@ curl -XGET elasticsearch_ip_or_hostname:9200/_cat/indices/.kibana,.kibana_task_m + For example: -* When {kib} is unable to connect to a healthy {es} cluster, the `master_not_discovered_exception` or `Unable to revive connection` errors appear. +* When {kib} is unable to connect to a healthy {es} cluster, errors like `master_not_discovered_exception` or `unable to revive connection` or `license is not available` errors appear. * When one or more {kib}-backing indices are unhealthy, the `index_not_green_timeout` error appears. From 50e015e4ff9b52cf7e537366373d357c95f5d628 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 4 Jul 2023 10:50:18 -0400 Subject: [PATCH 11/64] chore(slo): use doclinks (#160673) --- packages/kbn-doc-links/src/get_doc_links.ts | 1 + packages/kbn-doc-links/src/types.ts | 1 + .../public/rules/register_observability_rule_types.ts | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index b47b0ab86ac3b..304c249c7e2d4 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -521,6 +521,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { syntheticsCommandReference: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetics-configuration.html#synthetics-configuration-playwright-options`, syntheticsProjectMonitors: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetic-run-tests.html#synthetic-monitor-choose-project`, syntheticsMigrateFromIntegration: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetics-migrate-from-integration.html`, + sloBurnRateRule: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/slo-burn-rate-alert.html`, }, alerting: { guide: `${KIBANA_DOCS}create-and-manage-rules.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index 5f6b92ebd2a44..0fe2e7b30047f 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -401,6 +401,7 @@ export interface DocLinks { syntheticsCommandReference: string; syntheticsProjectMonitors: string; syntheticsMigrateFromIntegration: string; + sloBurnRateRule: string; }>; readonly alerting: Readonly<{ guide: string; diff --git a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts index e6e5412cc046e..8e28412050920 100644 --- a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts +++ b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts @@ -70,7 +70,7 @@ export const registerObservabilityRuleTypes = ( }, iconClass: 'bell', documentationUrl(docLinks) { - return 'https://www.elastic.co/guide/en/observability/current/slo-burn-rate-alert.html'; + return `${docLinks.links.observability.sloBurnRateRule}`; }, ruleParamsExpression: lazy(() => import('../components/burn_rate_rule_editor')), validate: validateBurnRateRule, @@ -78,6 +78,7 @@ export const registerObservabilityRuleTypes = ( defaultActionMessage: sloBurnRateDefaultActionMessage, defaultRecoveryMessage: sloBurnRateDefaultRecoveryMessage, }); + if (config.unsafe.thresholdRule.enabled) { observabilityRuleTypeRegistry.register({ id: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, From 72719a5013b0c60f7f4a68106c1c8db4eba272d1 Mon Sep 17 00:00:00 2001 From: Gerard Soldevila Date: Tue, 4 Jul 2023 17:01:31 +0200 Subject: [PATCH 12/64] [ZDT] Pickup updated types only (#161123) Part of https://github.com/elastic/kibana/issues/161067 Same idea as https://github.com/elastic/kibana/pull/159962, but applied to ZDT. When "picking up" the updated mappings, we add a "query" in order to select and update only the SO types that have been updated, compared to the previous version. --- .../src/actions/check_target_mappings.test.ts | 11 +--- .../src/actions/check_target_mappings.ts | 10 +-- .../core/build_pickup_mappings_query.test.ts | 31 +++++++++ .../src/core/build_pickup_mappings_query.ts | 30 +++++++++ .../src/model/model.test.ts | 6 +- .../src/model/model.ts | 20 +++--- .../src/next.ts | 2 - .../src/zdt/next.test.ts | 64 +++++++++++++++++++ .../src/zdt/next.ts | 2 + 9 files changed, 143 insertions(+), 33 deletions(-) create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.test.ts create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts index 17c55102a3cc7..4e04cc2a70539 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.test.ts @@ -20,8 +20,6 @@ jest.mock('../core/build_active_mappings'); const getUpdatedHashesMock = getUpdatedHashes as jest.MockedFn; -const indexTypes = ['type1', 'type2']; - const properties: SavedObjectsMappingProperties = { type1: { type: 'long' }, type2: { type: 'long' }, @@ -48,7 +46,6 @@ describe('checkTargetMappings', () => { describe('when actual mappings are incomplete', () => { it("returns 'actual_mappings_incomplete' if actual mappings are not defined", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, }); @@ -58,7 +55,6 @@ describe('checkTargetMappings', () => { it("returns 'actual_mappings_incomplete' if actual mappings do not define _meta", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: { properties, @@ -72,7 +68,6 @@ describe('checkTargetMappings', () => { it("returns 'actual_mappings_incomplete' if actual mappings do not define migrationMappingPropertyHashes", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: { properties, @@ -87,7 +82,6 @@ describe('checkTargetMappings', () => { it("returns 'actual_mappings_incomplete' if actual mappings define a different value for 'dynamic' property", async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: { properties, @@ -105,7 +99,6 @@ describe('checkTargetMappings', () => { describe('and mappings do not match', () => { it('returns the lists of changed root fields and types', async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: expectedMappings, }); @@ -115,8 +108,7 @@ describe('checkTargetMappings', () => { const result = await task(); const expected: ComparedMappingsChanged = { type: 'compared_mappings_changed' as const, - updatedRootFields: ['someRootField'], - updatedTypes: ['type1', 'type2'], + updatedHashes: ['type1', 'type2', 'someRootField'], }; expect(result).toEqual(Either.left(expected)); }); @@ -125,7 +117,6 @@ describe('checkTargetMappings', () => { describe('and mappings match', () => { it('returns a compared_mappings_match response', async () => { const task = checkTargetMappings({ - indexTypes, expectedMappings, actualMappings: expectedMappings, }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts index 26e0f074f43cb..576459beadd74 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions/check_target_mappings.ts @@ -13,7 +13,6 @@ import { getUpdatedHashes } from '../core/build_active_mappings'; /** @internal */ export interface CheckTargetMappingsParams { - indexTypes: string[]; actualMappings?: IndexMapping; expectedMappings: IndexMapping; } @@ -29,13 +28,11 @@ export interface ActualMappingsIncomplete { export interface ComparedMappingsChanged { type: 'compared_mappings_changed'; - updatedRootFields: string[]; - updatedTypes: string[]; + updatedHashes: string[]; } export const checkTargetMappings = ({ - indexTypes, actualMappings, expectedMappings, }: CheckTargetMappingsParams): TaskEither.TaskEither< @@ -56,12 +53,9 @@ export const checkTargetMappings = }); if (updatedHashes.length) { - const updatedTypes = updatedHashes.filter((field) => indexTypes.includes(field)); - const updatedRootFields = updatedHashes.filter((field) => !indexTypes.includes(field)); return Either.left({ type: 'compared_mappings_changed' as const, - updatedRootFields, - updatedTypes, + updatedHashes, }); } else { return Either.right({ type: 'compared_mappings_match' as const }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.test.ts new file mode 100644 index 0000000000000..3895bd9314df3 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.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 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 { buildPickupMappingsQuery } from './build_pickup_mappings_query'; + +describe('buildPickupMappingsQuery', () => { + describe('when no root fields have been updated', () => { + it('builds a boolean query to select the updated types', () => { + const query = buildPickupMappingsQuery(['type1', 'type2']); + + expect(query).toEqual({ + bool: { + should: [{ term: { type: 'type1' } }, { term: { type: 'type2' } }], + }, + }); + }); + }); + + describe('when some root fields have been updated', () => { + it('returns undefined', () => { + const query = buildPickupMappingsQuery(['type1', 'type2', 'namespaces']); + + expect(query).toBeUndefined(); + }); + }); +}); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts new file mode 100644 index 0000000000000..ce110f72f66c1 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/core/build_pickup_mappings_query.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 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 { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import { getBaseMappings } from './build_active_mappings'; + +export const buildPickupMappingsQuery = ( + updatedFields: string[] +): QueryDslQueryContainer | undefined => { + const rootFields = Object.keys(getBaseMappings().properties); + + if (updatedFields.some((field) => rootFields.includes(field))) { + // we are updating some root fields, update ALL documents (no filter query) + return undefined; + } + + // at this point, all updated fields correspond to SO types + const updatedTypes = updatedFields; + + return { + bool: { + should: updatedTypes.map((type) => ({ term: { type } })), + }, + }; +}; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts index 39a03e1e28d47..7039ce1cd1afa 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts @@ -2615,8 +2615,7 @@ describe('migrations v2 model', () => { it('CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_PROPERTIES if core fields have been updated', () => { const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.left({ type: 'compared_mappings_changed' as const, - updatedRootFields: ['namespaces'], - updatedTypes: ['dashboard', 'lens'], + updatedHashes: ['dashboard', 'lens', 'namespaces'], }); const newState = model( checkTargetMappingsState, @@ -2631,8 +2630,7 @@ describe('migrations v2 model', () => { it('CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_PROPERTIES if only SO types have changed', () => { const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.left({ type: 'compared_mappings_changed' as const, - updatedRootFields: [], - updatedTypes: ['dashboard', 'lens'], + updatedHashes: ['dashboard', 'lens'], }); const newState = model( checkTargetMappingsState, diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts index 2505581c6bc3d..2264ca388c975 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts @@ -54,6 +54,8 @@ import { CLUSTER_SHARD_LIMIT_EXCEEDED_REASON, FATAL_REASON_REQUEST_ENTITY_TOO_LARGE, } from '../common/constants'; +import { getBaseMappings } from '../core'; +import { buildPickupMappingsQuery } from '../core/build_pickup_mappings_query'; export const model = (currentState: State, resW: ResponseType): State => { // The action response `resW` is weakly typed, the type includes all action @@ -1439,18 +1441,22 @@ export const model = (currentState: State, resW: ResponseType): updatedTypesQuery: Option.none, }; } else if (isTypeof(left, 'compared_mappings_changed')) { - if (left.updatedRootFields.length) { + const rootFields = Object.keys(getBaseMappings().properties); + const updatedRootFields = left.updatedHashes.filter((field) => rootFields.includes(field)); + const updatedTypesQuery = Option.fromNullable(buildPickupMappingsQuery(left.updatedHashes)); + + if (updatedRootFields.length) { // compatible migration: some core fields have been updated return { ...stateP, controlState: 'UPDATE_TARGET_MAPPINGS_PROPERTIES', // we must "pick-up" all documents on the index (by not providing a query) - updatedTypesQuery: Option.none, + updatedTypesQuery, logs: [ ...stateP.logs, { level: 'info', - message: `Kibana is performing a compatible upgrade and the mappings of some root fields have been changed. For Elasticsearch to pickup these mappings, all saved objects need to be updated. Updated root fields: ${left.updatedRootFields}.`, + message: `Kibana is performing a compatible upgrade and the mappings of some root fields have been changed. For Elasticsearch to pickup these mappings, all saved objects need to be updated. Updated root fields: ${updatedRootFields}.`, }, ], }; @@ -1460,16 +1466,12 @@ export const model = (currentState: State, resW: ResponseType): ...stateP, controlState: 'UPDATE_TARGET_MAPPINGS_PROPERTIES', // we can "pick-up" only the SO types that have changed - updatedTypesQuery: Option.some({ - bool: { - should: left.updatedTypes.map((type) => ({ term: { type } })), - }, - }), + updatedTypesQuery, logs: [ ...stateP.logs, { level: 'info', - message: `Kibana is performing a compatible upgrade and NO root fields have been udpated. Kibana will update the following SO types so that ES can pickup the updated mappings: ${left.updatedTypes}.`, + message: `Kibana is performing a compatible upgrade and NO root fields have been udpated. Kibana will update the following SO types so that ES can pickup the updated mappings: ${left.updatedHashes}.`, }, ], }; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts index df7e0c23fbc20..b8d4afc55631d 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/next.ts @@ -58,7 +58,6 @@ import { createDelayFn } from './common/utils'; import type { TransformRawDocs } from './types'; import * as Actions from './actions'; import { REMOVED_TYPES } from './core'; -import { getIndexTypes } from './model/helpers'; type ActionMap = ReturnType; @@ -202,7 +201,6 @@ export const nextActionMap = ( Actions.checkTargetMappings({ actualMappings: Option.toUndefined(state.sourceIndexMappings), expectedMappings: state.targetIndexMappings, - indexTypes: getIndexTypes(state), }), UPDATE_TARGET_MAPPINGS_PROPERTIES: (state: UpdateTargetMappingsPropertiesState) => Actions.updateAndPickupMappings({ diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts index 00684ec46f85c..6c2f90155ac76 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.test.ts @@ -22,6 +22,7 @@ import type { SetDocMigrationStartedState, UpdateMappingModelVersionState, UpdateDocumentModelVersionsState, + UpdateIndexMappingsState, } from './state'; describe('actions', () => { @@ -147,4 +148,67 @@ describe('actions', () => { }); }); }); + + describe('UPDATE_INDEX_MAPPINGS', () => { + describe('when only SO types have been updated', () => { + it('calls updateAndPickupMappings with the correct parameters', () => { + const state: UpdateIndexMappingsState = { + ...createPostDocInitState(), + controlState: 'UPDATE_INDEX_MAPPINGS', + additiveMappingChanges: { + someToken: {}, + }, + }; + const action = actionMap.UPDATE_INDEX_MAPPINGS; + + action(state); + + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledTimes(1); + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledWith({ + client: context.elasticsearchClient, + index: state.currentIndex, + mappings: { + properties: { + someToken: {}, + }, + }, + batchSize: context.batchSize, + query: { + bool: { + should: [{ term: { type: 'someToken' } }], + }, + }, + }); + }); + }); + + describe('when core properties have been updated', () => { + it('calls updateAndPickupMappings with the correct parameters', () => { + const state: UpdateIndexMappingsState = { + ...createPostDocInitState(), + controlState: 'UPDATE_INDEX_MAPPINGS', + additiveMappingChanges: { + managed: {}, // this is a root field + someToken: {}, + }, + }; + const action = actionMap.UPDATE_INDEX_MAPPINGS; + + action(state); + + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledTimes(1); + expect(ActionMocks.updateAndPickupMappings).toHaveBeenCalledWith({ + client: context.elasticsearchClient, + index: state.currentIndex, + mappings: { + properties: { + managed: {}, + someToken: {}, + }, + }, + batchSize: context.batchSize, + }); + }); + }); + }); }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts index 17749104d18fe..fe1093b0f4978 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/next.ts @@ -39,6 +39,7 @@ import { setMetaDocMigrationComplete, setMetaDocMigrationStarted, } from './utils'; +import { buildPickupMappingsQuery } from '../core/build_pickup_mappings_query'; export type ActionMap = ReturnType; @@ -72,6 +73,7 @@ export const nextActionMap = (context: MigratorContext) => { index: state.currentIndex, mappings: { properties: state.additiveMappingChanges }, batchSize: context.batchSize, + query: buildPickupMappingsQuery(Object.keys(state.additiveMappingChanges)), }), UPDATE_INDEX_MAPPINGS_WAIT_FOR_TASK: (state: UpdateIndexMappingsWaitForTaskState) => Actions.waitForPickupUpdatedMappingsTask({ From e53ac35745da6f971594ad32c6e5c9a418cf8807 Mon Sep 17 00:00:00 2001 From: Elastic Machine Date: Tue, 4 Jul 2023 10:06:04 -0500 Subject: [PATCH 13/64] [main] Sync bundled packages with Package Storage (#161188) Automated by https://internal-ci.elastic.co/job/package_storage/job/sync-bundled-packages-job/job/main/5214/ Co-authored-by: apmmachine --- fleet_packages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fleet_packages.json b/fleet_packages.json index e35f69b4dbc17..c4fbbc9750147 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -24,7 +24,7 @@ [ { "name": "apm", - "version": "8.10.0-preview-1687509840", + "version": "8.10.0-preview-1688475406", "forceAlignStackVersion": true, "allowSyncToPrerelease": true }, From 9de4cc5f46092b1fbf2b3d31e00e2d18b2b324f4 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 4 Jul 2023 17:09:56 +0100 Subject: [PATCH 14/64] skip flaky suite (#151981) --- .../case_view/components/case_view_activity.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx index bd604514b4cfa..1ef1d870daf77 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx @@ -566,7 +566,8 @@ describe('Case View Page activity tab', () => { }); }); - describe('User actions', () => { + // FLAKY: https://github.com/elastic/kibana/issues/151981 + describe.skip('User actions', () => { it('renders the description correctly', async () => { appMockRender = createAppMockRenderer(); appMockRender.render(); From 8a95bf7fabe34c601725313c922f95ee0fa641e5 Mon Sep 17 00:00:00 2001 From: Dzmitry Lemechko Date: Tue, 4 Jul 2023 18:26:57 +0200 Subject: [PATCH 15/64] [ftr] Improve FTR error handling for NoSuchSessionError (#161025) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Sometimes browser/driver process dies during test run on CI and FTR fails with errors cascade, good example is [here](https://buildkite.com/elastic/kibana-pull-request/builds/138535#0188fd74-9adf-4011-8168-1bdc6e3d0f17) Current behaviour on `main`: FTR lifecycle hooks, defined in [remote](https://github.com/elastic/kibana/blob/57aea91fae4f2d0a047ff9e2339eb61352f1d73d/test/functional/services/remote/remote.ts) service, has no access to the information about test suite run and particular test failure. These hooks are related to WebDriver (browser) state management and suppose to reset it to default state. Currently we silently fail screenshot taking which means tests execution is continued even if `--bail` flag is passed. It ends with cascade of failures with the same error `NoSuchSessionError: invalid session id`
FTR output on failure ``` └- ✖ fail: discover/group1 discover test query should show correct time range string by timepicker │ Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' │ at Assertion.assert (expect.js:100:11) │ at Assertion.apply (expect.js:227:8) │ at Assertion.be (expect.js:69:22) │ at Context. (_discover.ts:53:31) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Object.apply (wrap_function.js:73:16) │ │ └-> "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count" └- ✖ fail: discover/group1 discover test query "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count" │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ └-> "after all" hook in "discover test" │ debg Cleaning all saved objects { space: undefined } │ succ deleted 2 objects └-> "after all" hook: afterTestSuite.trigger in "discover test" └- ✖ fail: discover/group1 discover test "after all" hook: afterTestSuite.trigger in "discover test" │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ └-> "after all" hook: unloadMakelogs in "discover/group1" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "mappings.json" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.22" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.20" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.21" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "data.json.gz" └-> "after all" hook: afterTestSuite.trigger in "discover/group1" └- ✖ fail: discover/group1 "after all" hook: afterTestSuite.trigger in "discover/group1" │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at runMicrotasks () │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ │ │0 passing (15.7s) │4 failing │ │1) discover/group1 │ discover test │ query │ should show correct time range string by timepicker: │ │ Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' │ at Assertion.assert (expect.js:100:11) │ at Assertion.apply (expect.js:227:8) │ at Assertion.be (expect.js:69:22) │ at Context. (_discover.ts:53:31) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Object.apply (wrap_function.js:73:16) │ │ │2) discover/group1 │ discover test │ query │ "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count": │ │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ │3) discover/group1 │ discover test │ "after all" hook: afterTestSuite.trigger in "discover test": │ │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) │ │ │4) discover/group1 │ "after all" hook: afterTestSuite.trigger in "discover/group1": │ │ NoSuchSessionError: invalid session id │ at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:524:15) │ at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:601:13) │ at Executor.execute (node_modules/selenium-webdriver/lib/http.js:529:28) │ at runMicrotasks () │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Task.exec (prevent_parallel_calls.ts:28:20) ```
This PR change: I didn't find a good reason why we need to fail silently on screenshot taking. I added a check WebDriver session status with `hasOpenWindow` and take failure artefacts only if is still valid. Next change is to fail FTR after hooks related to WebDriver silently: there is no help having cascade of the repeated stacktrace so I wrap WebDriver call in hooks with `tryWebDriverCall` that catches the error and only prints it for visibility.
FTR new output on failure ``` │ERROR WebDriver session is no longer valid. │ Probably Chrome process crashed when it tried to use more memory than what was available. │ERROR Browser is closed, no artifacts were captured for the failure └- ✖ fail: discover/group1 discover test query should show correct time range string by timepicker │ Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' │ at Assertion.assert (expect.js:100:11) │ at Assertion.apply (expect.js:227:8) │ at Assertion.be (expect.js:69:22) │ at Context. (_discover.ts:53:31) │ at processTicksAndRejections (node:internal/process/task_queues:96:5) │ at Object.apply (wrap_function.js:73:16) │ │ └-> "after all" hook: afterTestSuite.trigger for "should reload the saved search with persisted query to show the initial hit count" │ERROR WebDriver session is no longer valid └-> "after all" hook in "discover test" │ debg Cleaning all saved objects { space: undefined } │ warn browser[SEVERE] ERROR FETCHING BROWSR LOGS: This driver instance does not have a valid session ID (did you call WebDriver.quit()?) and may no longer be used. │ succ deleted 2 objects └-> "after all" hook: afterTestSuite.trigger in "discover test" │ERROR WebDriver session is no longer valid └-> "after all" hook: unloadMakelogs in "discover/group1" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "mappings.json" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.22" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.20" │ info [test/functional/fixtures/es_archiver/logstash_functional] Deleted existing index "logstash-2015.09.21" │ info [test/functional/fixtures/es_archiver/logstash_functional] Unloading indices from "data.json.gz" └-> "after all" hook: afterTestSuite.trigger in "discover/group1" │ERROR WebDriver session is no longer valid 0 passing (16.2s) 1 failing 1) discover/group1 discover test query should show correct time range string by timepicker: Error: expected 'Sep 19, 2015 @ 06:31:44.000' to equal 'Sep 23, 2015 @ 18:31:44.000' at Assertion.assert (expect.js:100:11) at Assertion.apply (expect.js:227:8) at Assertion.be (expect.js:69:22) at Context. (_discover.ts:53:31) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.apply (wrap_function.js:73:16) ```
Flaky-test-runner verification: started 100x to hopefully catch invalid session on CI https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2539 Note: locally I was simulating it by calling `this.driver.close()` to close browser before screenshot taking --- test/functional/services/common/browser.ts | 30 +++++++++++++++++-- .../services/common/failure_debugging.ts | 7 ++++- .../functional/services/common/screenshots.ts | 20 +++---------- test/functional/services/remote/remote.ts | 30 +++++++++++++++---- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/test/functional/services/common/browser.ts b/test/functional/services/common/browser.ts index 9de8ba0d569f0..393f093d54189 100644 --- a/test/functional/services/common/browser.ts +++ b/test/functional/services/common/browser.ts @@ -12,6 +12,7 @@ import { Key, Origin, WebDriver } from 'selenium-webdriver'; import { modifyUrl } from '@kbn/std'; import sharp from 'sharp'; +import { NoSuchSessionError } from 'selenium-webdriver/lib/error'; import { WebElementWrapper } from '../lib/web_element_wrapper'; import { FtrProviderContext, FtrService } from '../../ftr_provider_context'; import { Browsers } from '../remote/browsers'; @@ -632,8 +633,33 @@ class BrowserService extends FtrService { return Boolean(result?.state === 'granted'); } - public getClipboardValue(): Promise { - return this.driver.executeAsyncScript('navigator.clipboard.readText().then(arguments[0])'); + public async getClipboardValue(): Promise { + return await this.driver.executeAsyncScript( + 'navigator.clipboard.readText().then(arguments[0])' + ); + } + + /** + * Checks if browser session is active and any browser window exists + * @returns {Promise} + */ + public async hasOpenWindow(): Promise { + if (this.driver == null) { + return false; + } else { + try { + const windowHandles = await this.driver.getAllWindowHandles(); + return windowHandles.length > 0; + } catch (err) { + if (err instanceof NoSuchSessionError) { + // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidSessionID + this.log.error( + `WebDriver session is no longer valid.\nProbably Chrome process crashed when it tried to use more memory than what was available.` + ); + } + return false; + } + } } } diff --git a/test/functional/services/common/failure_debugging.ts b/test/functional/services/common/failure_debugging.ts index 5555ae78bccf8..f269a83359da0 100644 --- a/test/functional/services/common/failure_debugging.ts +++ b/test/functional/services/common/failure_debugging.ts @@ -50,7 +50,12 @@ export async function FailureDebuggingProvider({ getService }: FtrProviderContex async function onFailure(_: any, test: Test) { const name = FtrScreenshotFilename.create(test.fullTitle(), { ext: false }); - await Promise.all([screenshots.takeForFailure(name), logCurrentUrl(), savePageHtml(name)]); + const hasOpenWindow = await browser.hasOpenWindow(); + if (hasOpenWindow) { + await Promise.all([screenshots.takeForFailure(name), logCurrentUrl(), savePageHtml(name)]); + } else { + log.error('Browser is closed, no artifacts were captured for the failure'); + } } lifecycle.testFailure.add(onFailure); diff --git a/test/functional/services/common/screenshots.ts b/test/functional/services/common/screenshots.ts index 191fc5202c417..50421e480dd9c 100644 --- a/test/functional/services/common/screenshots.ts +++ b/test/functional/services/common/screenshots.ts @@ -9,7 +9,6 @@ import { resolve, dirname } from 'path'; import { writeFile, readFileSync, mkdir } from 'fs'; import { promisify } from 'util'; -import { NoSuchSessionError } from 'selenium-webdriver/lib/error'; import del from 'del'; @@ -85,20 +84,9 @@ export class ScreenshotsService extends FtrService { } private async capture(path: string, el?: WebElementWrapper) { - try { - this.log.info(`Taking screenshot "${path}"`); - const screenshot = await (el ? el.takeScreenshot() : this.browser.takeScreenshot()); - await mkdirAsync(dirname(path), { recursive: true }); - await writeFileAsync(path, screenshot, 'base64'); - } catch (err) { - this.log.error('SCREENSHOT FAILED'); - this.log.error(err); - if (err instanceof NoSuchSessionError) { - // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidSessionID - this.log.error( - `WebDriver session is no longer valid.\nProbably Chrome process crashed when it tried to use more memory than what was available.` - ); - } - } + this.log.info(`Taking ${el ? 'element' : 'window'} screenshot "${path}"`); + const screenshot = await (el ? el.takeScreenshot() : this.browser.takeScreenshot()); + await mkdirAsync(dirname(path), { recursive: true }); + await writeFileAsync(path, screenshot, 'base64'); } } diff --git a/test/functional/services/remote/remote.ts b/test/functional/services/remote/remote.ts index 284029514606f..b3038130b0187 100644 --- a/test/functional/services/remote/remote.ts +++ b/test/functional/services/remote/remote.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { NoSuchSessionError } from 'selenium-webdriver/lib/error'; import { FtrProviderContext } from '../../ftr_provider_context'; import { initWebDriver, BrowserConfig } from './webdriver'; import { Browsers } from './browsers'; @@ -27,6 +28,21 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { } }; + const tryWebDriverCall = async (command: () => Promise) => { + // Since WebDriver session may be deleted, we fail silently. Use only in after hooks. + try { + await command(); + } catch (error) { + if (error instanceof NoSuchSessionError) { + // Avoid duplicating NoSuchSessionError error output on each hook + // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidSessionID + log.error('WebDriver session is no longer valid'); + } else { + throw error; + } + } + }; + const browserConfig: BrowserConfig = { logPollingMs: config.get('browser.logPollingMs'), acceptInsecureCerts: config.get('browser.acceptInsecureCerts'), @@ -72,14 +88,18 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { }); lifecycle.afterTestSuite.add(async () => { - const { width, height } = windowSizeStack.shift()!; - await driver.manage().window().setRect({ width, height }); - await clearBrowserStorage('sessionStorage'); - await clearBrowserStorage('localStorage'); + await tryWebDriverCall(async () => { + const { width, height } = windowSizeStack.shift()!; + await driver.manage().window().setRect({ width, height }); + await clearBrowserStorage('sessionStorage'); + await clearBrowserStorage('localStorage'); + }); }); lifecycle.cleanup.add(async () => { - await driver.quit(); + await tryWebDriverCall(async () => { + await driver.quit(); + }); }); return { driver, browserType, consoleLog$ }; From bfab1b0659269cf67d6a864d6a80ee29632b4b4c Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Tue, 4 Jul 2023 18:46:47 +0200 Subject: [PATCH 16/64] [Discover] Fix shared links flaky test (#161172) - Closes https://github.com/elastic/kibana/issues/158465 100x https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2550 --- .../apps/discover/group1/_shared_links.ts | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/test/functional/apps/discover/group1/_shared_links.ts b/test/functional/apps/discover/group1/_shared_links.ts index 11e92297aad99..30626d9d42576 100644 --- a/test/functional/apps/discover/group1/_shared_links.ts +++ b/test/functional/apps/discover/group1/_shared_links.ts @@ -8,6 +8,7 @@ import { DISCOVER_APP_LOCATOR } from '@kbn/discover-plugin/common'; import expect from '@kbn/expect'; +import { decompressFromBase64 } from 'lz-string'; import { FtrProviderContext } from '../ftr_provider_context'; @@ -21,8 +22,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const toasts = getService('toasts'); const deployment = getService('deployment'); - // Failing: See https://github.com/elastic/kibana/issues/158465 - describe.skip('shared links', function describeIndexTests() { + describe('shared links', function describeIndexTests() { let baseUrl: string; async function setup({ storeStateInSessionStorage }: { storeStateInSessionStorage: boolean }) { @@ -75,14 +75,29 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('permalink', function () { it('should allow for copying the snapshot URL', async function () { - const lz = - 'N4IgjgrgpgTgniAXKSsGJCANCANgQwDsBzCfYqJEAa2nhAF8cBnAexgBckBtbkAAQ4BLALZRmHfCIAO2EABNxAYxABdVTiWtcEEYWY8N' + - 'IIYUUAPKrlbEJ%2BZgAsAtACo5JjrABu%2BXFXwQOVjkAMyFcDxgDRG4jeXxJADUhKAB3AEl5S2tbBxc5YTEAJSIKJFBgmFYRKgAmAAY' + - 'ARgBWRzqATkcGtoAVOoA2RABmBsQAFlGAOjrpgC18oIx65taOmsHuhoAOIZHxqdnGHBgoCvF7NMII719kEGvoJD7p6Zxpf2ZKRA4YaAY' + - 'GIA%3D'; const actualUrl = await PageObjects.share.getSharedUrl(); expect(actualUrl).to.contain(`?l=${DISCOVER_APP_LOCATOR}`); - expect(actualUrl).to.contain(`&lz=${lz}`); + const urlSearchParams = new URLSearchParams(actualUrl); + expect(JSON.parse(decompressFromBase64(urlSearchParams.get('lz')!)!)).to.eql({ + query: { + language: 'kuery', + query: '', + }, + sort: [['@timestamp', 'desc']], + columns: [], + index: 'logstash-*', + interval: 'auto', + filters: [], + dataViewId: 'logstash-*', + timeRange: { + from: '2015-09-19T06:31:44.000Z', + to: '2015-09-23T18:31:44.000Z', + }, + refreshInterval: { + value: 60000, + pause: true, + }, + }); }); it('should allow for copying the snapshot URL as a short URL', async function () { From b128f268d9450f007fbc15dc7c1bc066c7e36b65 Mon Sep 17 00:00:00 2001 From: Coen Warmer Date: Tue, 4 Jul 2023 19:25:12 +0200 Subject: [PATCH 17/64] Have SLO routes return a 403 instead of a 400 when user has an insufficient license (#161193) --- .../observability/docs/openapi/slo/README.md | 26 +- .../docs/openapi/slo/bundled.json | 2259 +++++++++++++++++ .../docs/openapi/slo/bundled.yaml | 107 +- .../slo/components/schemas/403_response.yaml | 16 + .../paths/s@{spaceid}@api@composite_slos.yaml | 24 +- ...}@api@composite_slos@{compositesloid}.yaml | 36 +- .../slo/paths/s@{spaceid}@api@slos.yaml | 28 +- ...spaceid}@api@slos@_historical_summary.yaml | 12 +- .../paths/s@{spaceid}@api@slos@{sloid}.yaml | 38 +- ...@{spaceid}@api@slos@{sloid}@{disable}.yaml | 14 +- ...s@{spaceid}@api@slos@{sloid}@{enable}.yaml | 14 +- .../slo_details/components/header_control.tsx | 2 +- .../pages/slos/components/slo_list_item.tsx | 2 +- .../observability/server/routes/slo/route.ts | 22 +- 14 files changed, 2524 insertions(+), 76 deletions(-) create mode 100644 x-pack/plugins/observability/docs/openapi/slo/bundled.json create mode 100644 x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml diff --git a/x-pack/plugins/observability/docs/openapi/slo/README.md b/x-pack/plugins/observability/docs/openapi/slo/README.md index e128dd32a38b9..440e560bf62f1 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/README.md +++ b/x-pack/plugins/observability/docs/openapi/slo/README.md @@ -7,28 +7,28 @@ A guide about the OpenApi specification can be found at [https://swagger.io/docs ## The `openapi/slo` folder -* `entrypoint.yaml` is the overview file which pulls together all the paths and components. -* [Paths](paths/README.md): this defines each endpoint. A path can have one operation per http method. -* [Components](components/README.md): Reusable components +- `entrypoint.yaml` is the overview file which pulls together all the paths and components. +- [Paths](paths/README.md): this defines each endpoint. A path can have one operation per http method. +- [Components](components/README.md): Reusable components ## Tools It is possible to validate the docs before bundling them with the following command in the `x-pack/plugins/observability/docs/openapi/slo` folder: - ```bash - npx swagger-cli validate entrypoint.yaml - ``` +```bash + npx swagger-cli validate entrypoint.yaml +``` Then you can generate the `bundled` files by running the following commands: - ```bash - npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml - npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json - ``` +```bash + npx @redocly/cli bundle entrypoint.yaml --output bundled.yaml --ext yaml + npx @redocly/cli bundle entrypoint.yaml --output bundled.json --ext json +``` After generating the json bundle ensure that it is also valid by running the following command: - ```bash - npx @redocly/cli lint bundled.json - ``` +```bash + npx @redocly/cli lint bundled.json +``` diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.json b/x-pack/plugins/observability/docs/openapi/slo/bundled.json new file mode 100644 index 0000000000000..09295ed296678 --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.json @@ -0,0 +1,2259 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "SLOs", + "description": "OpenAPI schema for SLOs endpoints", + "version": "1.0", + "contact": { + "name": "Actionable Observability Team" + }, + "license": { + "name": "Elastic License 2.0", + "url": "https://www.elastic.co/licensing/elastic-license" + } + }, + "servers": [ + { + "url": "http://localhost:5601", + "description": "local" + } + ], + "security": [ + { + "basicAuth": [] + }, + { + "apiKeyAuth": [] + } + ], + "tags": [ + { + "name": "slo", + "description": "SLO APIs enable you to define, manage and track service-level objectives" + }, + { + "name": "composite slo", + "description": "Composite SLO APIs enable you to define, manage and track a group of SLOs." + } + ], + "paths": { + "/s/{spaceId}/api/observability/composite_slos": { + "post": { + "summary": "Creates a Composite SLO", + "operationId": "createCompositeSlo", + "description": "You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_composite_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "409": { + "description": "Conflict - The Composite SLO id already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/409_response" + } + } + } + } + } + }, + "get": { + "summary": "Retrieves a paginated list of composite SLOs with summary", + "operationId": "findCompositeSlo", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "name": "page", + "in": "query", + "description": "The page number to return", + "schema": { + "type": "integer", + "default": 1 + }, + "example": 1 + }, + { + "name": "perPage", + "in": "query", + "description": "The number of SLOs to return per page", + "schema": { + "type": "integer", + "default": 25 + }, + "example": 20 + }, + { + "name": "sortBy", + "in": "query", + "description": "Sort by field", + "schema": { + "type": "string", + "enum": [ + "creationTime" + ], + "default": "creationTime" + }, + "example": "creationTime" + }, + { + "name": "sortDirection", + "in": "query", + "description": "Sort order", + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "default": "asc" + }, + "example": "asc" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/find_composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/composite_slos/{compositeSloId}": { + "get": { + "summary": "Retrieves a composite SLO", + "operationId": "getCompositeSlo", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/composite_slo_id" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "put": { + "summary": "Updates a composite SLO", + "operationId": "updateCompositeSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/composite_slo_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/update_composite_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/base_composite_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "delete": { + "summary": "Deletes a composite SLO", + "operationId": "deleteCompositeSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "composite slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/composite_slo_id" + } + ], + "responses": { + "204": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos": { + "post": { + "summary": "Creates an SLO.", + "operationId": "createSlo", + "description": "You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/create_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "409": { + "description": "Conflict - The SLO id already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/409_response" + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "get": { + "summary": "Retrieves a paginated list of SLOs", + "operationId": "findSlos", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "name": "name", + "in": "query", + "description": "Filter by name", + "schema": { + "type": "string" + }, + "example": "awesome-service" + }, + { + "name": "indicatorTypes", + "in": "query", + "description": "Filter by indicator type", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "example": [ + "sli.kql.custom" + ] + }, + { + "name": "page", + "in": "query", + "description": "The page number to return", + "schema": { + "type": "integer", + "default": 1 + }, + "example": 1 + }, + { + "name": "perPage", + "in": "query", + "description": "The number of SLOs to return per page", + "schema": { + "type": "integer", + "default": 25 + }, + "example": 20 + }, + { + "name": "sortBy", + "in": "query", + "description": "Sort by field", + "schema": { + "type": "string", + "enum": [ + "creationTime", + "indicatorType" + ], + "default": "creationTime" + }, + "example": "creationTime" + }, + { + "name": "sortDirection", + "in": "query", + "description": "Sort order", + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "default": "asc" + }, + "example": "asc" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/find_slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos/{sloId}": { + "get": { + "summary": "Retrieves a SLO", + "operationId": "getSlo", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "put": { + "summary": "Updates an SLO", + "operationId": "updateSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/update_slo_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/slo_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + }, + "delete": { + "summary": "Deletes an SLO", + "operationId": "deleteSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "204": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos/{sloId}/enable": { + "post": { + "summary": "Enables an SLO", + "operationId": "enableSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "204": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/api/observability/slos/{sloId}/disable": { + "post": { + "summary": "Disables an SLO", + "operationId": "disableSlo", + "description": "You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + }, + { + "$ref": "#/components/parameters/slo_id" + } + ], + "responses": { + "200": { + "description": "Successful request" + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + }, + "404": { + "description": "Not found response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } + } + } + } + }, + "/s/{spaceId}/internal/observability/slos/_historical_summary": { + "post": { + "summary": "Retrieves the historical summary for a list of SLOs", + "operationId": "historicalSummary", + "description": "You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges.\n", + "tags": [ + "slo" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/historical_summary_request" + } + } + } + }, + "responses": { + "200": { + "description": "Successful request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/historical_summary_response" + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/400_response" + } + } + } + }, + "401": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "403": { + "description": "Unauthorized response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/403_response" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "basic" + }, + "apiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "ApiKey" + } + }, + "parameters": { + "kbn_xsrf": { + "schema": { + "type": "string" + }, + "in": "header", + "name": "kbn-xsrf", + "description": "Cross-site request forgery protection", + "required": true + }, + "space_id": { + "in": "path", + "name": "spaceId", + "description": "An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used.", + "required": true, + "schema": { + "type": "string", + "example": "default" + } + }, + "composite_slo_id": { + "in": "path", + "name": "compositeSloId", + "description": "An identifier for the composite slo.", + "required": true, + "schema": { + "type": "string", + "example": "9c235211-6834-11ea-a78c-6feb38a34414" + } + }, + "slo_id": { + "in": "path", + "name": "sloId", + "description": "An identifier for the slo.", + "required": true, + "schema": { + "type": "string", + "example": "9c235211-6834-11ea-a78c-6feb38a34414" + } + } + }, + "schemas": { + "time_window_rolling": { + "title": "Rolling", + "required": [ + "duration", + "isRolling" + ], + "description": "Defines properties for rolling time window", + "type": "object", + "properties": { + "duration": { + "description": "the duration formatted as {duration}{unit}", + "type": "string", + "example": "28d" + }, + "isRolling": { + "description": "Indicates a rolling time window", + "type": "boolean", + "example": true + } + } + }, + "budgeting_method": { + "title": "Budgeting method", + "type": "string", + "description": "The budgeting method to use when computing the rollup data.", + "enum": [ + "occurrences", + "timeslices" + ], + "example": "occurrences" + }, + "composite_method": { + "title": "Composite method", + "type": "string", + "description": "The composite method to use for the composite SLO.", + "enum": [ + "weightedAverage" + ], + "example": "weightedAverage" + }, + "objective": { + "title": "Objective", + "required": [ + "target" + ], + "description": "Defines properties for the SLO objective", + "type": "object", + "properties": { + "target": { + "description": "the target objective between 0 and 1 excluded", + "type": "number", + "example": 0.99 + }, + "timeslicesTarget": { + "description": "the target objective for each slice when using a timeslices budgeting method", + "type": "number", + "example": 0.995 + }, + "timeslicesWindow": { + "description": "the duration of each slice when using a timeslices budgeting method, as {duraton}{unit}", + "type": "string", + "example": "5m" + } + } + }, + "weighted_composite_sources": { + "title": "Weighted sources", + "description": "An array of source SLO to use for the weighted average composite.", + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "revision", + "weight" + ], + "properties": { + "id": { + "description": "The id of the SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "revision": { + "description": "The revision number of the SLO.", + "type": "number", + "example": 2 + }, + "weight": { + "description": "The weight to apply to this SLO.", + "type": "number", + "example": 3 + } + } + } + }, + "error_budget": { + "title": "Error budget", + "type": "object", + "properties": { + "initial": { + "type": "number", + "description": "The initial error budget, as 1 - objective", + "example": 0.02 + }, + "consumed": { + "type": "number", + "description": "The error budget consummed, as a percentage of the initial value.", + "example": 0.8 + }, + "remaining": { + "type": "number", + "description": "The error budget remaining, as a percentage of the initial value.", + "example": 0.2 + }, + "isEstimated": { + "type": "boolean", + "description": "Only for SLO defined with occurrences budgeting method and calendar aligned time window.", + "example": true + } + } + }, + "summary": { + "title": "Summary", + "type": "object", + "description": "The SLO computed data", + "properties": { + "status": { + "type": "string", + "enum": [ + "NO_DATA", + "HEALTHY", + "DEGRADING", + "VIOLATED" + ], + "example": "HEALTHY" + }, + "sliValue": { + "type": "number", + "example": 0.9836 + }, + "errorBudget": { + "$ref": "#/components/schemas/error_budget" + } + } + }, + "composite_slo_response": { + "title": "Composite SLO with summary response", + "type": "object", + "properties": { + "id": { + "description": "The identifier of the composite SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "name": { + "description": "The name of the composite SLO.", + "type": "string", + "example": "My Service SLO" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + }, + "summary": { + "$ref": "#/components/schemas/summary" + }, + "createdAt": { + "description": "The creation date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + }, + "updatedAt": { + "description": "The last update date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + } + } + }, + "find_composite_slo_response": { + "title": "Find composite SLO response", + "description": "A paginated response of composite SLOs matching the query.", + "type": "object", + "properties": { + "page": { + "type": "number", + "example": 1 + }, + "perPage": { + "type": "number", + "example": 25 + }, + "total": { + "type": "number", + "example": 34 + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/composite_slo_response" + } + } + } + }, + "400_response": { + "title": "Bad request", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 400 + }, + "error": { + "type": "string", + "example": "Bad Request" + }, + "message": { + "type": "string", + "example": "Invalid value 'foo' supplied to: [...]" + } + } + }, + "401_response": { + "title": "Unauthorized", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 401 + }, + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string", + "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + } + } + }, + "403_response": { + "title": "Unauthorized", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 403 + }, + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string", + "example": "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + } + } + }, + "404_response": { + "title": "Not found", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 404 + }, + "error": { + "type": "string", + "example": "Not Found" + }, + "message": { + "type": "string", + "example": "SLO [3749f390-03a3-11ee-8139-c7ff60a1692d] not found" + } + } + }, + "create_composite_slo_request": { + "title": "Create composite SLO request", + "description": "The create Composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO.\n", + "type": "object", + "required": [ + "name", + "timeWindow", + "budgetingMethod", + "compositeMethod", + "objective", + "sources" + ], + "properties": { + "id": { + "description": "A unique identifier for the composite SLO. Must be between 8 and 36 chars", + "type": "string", + "example": "my-super-composite-slo-id" + }, + "name": { + "description": "A name for the composite SLO.", + "type": "string" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + } + } + }, + "create_composite_slo_response": { + "title": "Create composite SLO response", + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + } + } + }, + "409_response": { + "title": "Conflict", + "type": "object", + "required": [ + "statusCode", + "error", + "message" + ], + "properties": { + "statusCode": { + "type": "number", + "example": 409 + }, + "error": { + "type": "string", + "example": "Conflict" + }, + "message": { + "type": "string", + "example": "SLO [d077e940-1515-11ee-9c50-9d096392f520] already exists" + } + } + }, + "update_composite_slo_request": { + "title": "Update composite SLO request", + "description": "The update composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO.\n", + "type": "object", + "properties": { + "id": { + "description": "A unique identifier for the composite SLO. Must be between 8 and 36 chars", + "type": "string", + "example": "my-super-composite-slo-id" + }, + "name": { + "description": "A name for the composite SLO.", + "type": "string" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + } + } + }, + "base_composite_slo_response": { + "title": "Composite SLO response", + "type": "object", + "properties": { + "id": { + "description": "The identifier of the composite SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "name": { + "description": "The name of the composite SLO.", + "type": "string", + "example": "My Service SLO" + }, + "timeWindow": { + "$ref": "#/components/schemas/time_window_rolling" + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "compositeMethod": { + "$ref": "#/components/schemas/composite_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "sources": { + "oneOf": [ + { + "$ref": "#/components/schemas/weighted_composite_sources" + } + ] + }, + "createdAt": { + "description": "The creation date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + }, + "updatedAt": { + "description": "The last update date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + } + } + }, + "indicator_properties_custom_kql": { + "title": "Custom KQL", + "required": [ + "type", + "params" + ], + "description": "Defines properties for a custom KQL indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "index", + "timestampField" + ], + "properties": { + "index": { + "description": "The index or index pattern to use", + "type": "string", + "example": "my-service-*" + }, + "filter": { + "description": "the KQL query to filter the documents with.", + "type": "string", + "example": "field.environment : \"production\" and service.name : \"my-service\"" + }, + "good": { + "description": "the KQL query used to define the good events.", + "type": "string", + "example": "request.latency <= 150 and request.status_code : \"2xx\"" + }, + "total": { + "description": "the KQL query used to define all events.", + "type": "string", + "example": "" + }, + "timestampField": { + "description": "The timestamp field used in the source indice.\n", + "type": "string", + "example": "timestamp" + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.kql.custom" + } + } + }, + "indicator_properties_apm_availability": { + "title": "APM availability", + "required": [ + "type", + "params" + ], + "description": "Defines properties for the APM availability indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "service", + "environment", + "transactionType", + "transactionName", + "index" + ], + "properties": { + "service": { + "description": "The APM service name", + "type": "string", + "example": "o11y-app" + }, + "environment": { + "description": "The APM service environment or \"*\"", + "type": "string", + "example": "production" + }, + "transactionType": { + "description": "The APM transaction type or \"*\"", + "type": "string", + "example": "request" + }, + "transactionName": { + "description": "The APM transaction name or \"*\"", + "type": "string", + "example": "GET /my/api" + }, + "filter": { + "description": "KQL query used for filtering the data", + "type": "string", + "example": "service.foo : \"bar\"" + }, + "index": { + "description": "The index used by APM metrics", + "type": "string", + "example": "metrics-apm*,apm*" + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.apm.transactionDuration" + } + } + }, + "indicator_properties_apm_latency": { + "title": "APM latency", + "required": [ + "type", + "params" + ], + "description": "Defines properties for the APM latency indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "service", + "environment", + "transactionType", + "transactionName", + "index", + "threshold" + ], + "properties": { + "service": { + "description": "The APM service name", + "type": "string", + "example": "o11y-app" + }, + "environment": { + "description": "The APM service environment or \"*\"", + "type": "string", + "example": "production" + }, + "transactionType": { + "description": "The APM transaction type or \"*\"", + "type": "string", + "example": "request" + }, + "transactionName": { + "description": "The APM transaction name or \"*\"", + "type": "string", + "example": "GET /my/api" + }, + "filter": { + "description": "KQL query used for filtering the data", + "type": "string", + "example": "service.foo : \"bar\"" + }, + "index": { + "description": "The index used by APM metrics", + "type": "string", + "example": "metrics-apm*,apm*" + }, + "threshold": { + "description": "The latency threshold in milliseconds", + "type": "number", + "example": 250 + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.apm.transactionDuration" + } + } + }, + "indicator_properties_custom_metric": { + "title": "Custom metric", + "required": [ + "type", + "params" + ], + "description": "Defines properties for a custom metric indicator type", + "type": "object", + "properties": { + "params": { + "description": "An object containing the indicator parameters.", + "type": "object", + "nullable": false, + "required": [ + "index", + "timestampField", + "good", + "total" + ], + "properties": { + "index": { + "description": "The index or index pattern to use", + "type": "string", + "example": "my-service-*" + }, + "filter": { + "description": "the KQL query to filter the documents with.", + "type": "string", + "example": "field.environment : \"production\" and service.name : \"my-service\"" + }, + "timestampField": { + "description": "The timestamp field used in the source indice.\n", + "type": "string", + "example": "timestamp" + }, + "good": { + "description": "An object defining the \"good\" metrics and equation\n", + "type": "object", + "required": [ + "metrics", + "equation" + ], + "properties": { + "metrics": { + "description": "List of metrics with their name, aggregation type, and field.", + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "aggregation", + "field" + ], + "properties": { + "name": { + "description": "The name of the metric. Only valid options are A-Z", + "type": "string", + "example": "A", + "pattern": "^[A-Z]$" + }, + "aggregation": { + "description": "The aggregation type of the metric. Only valid option is \"sum\"", + "type": "string", + "example": "sum", + "enum": [ + "sum" + ] + }, + "field": { + "description": "The field of the metric.", + "type": "string", + "example": "processor.processed" + } + } + } + }, + "equation": { + "description": "The equation to calculate the \"good\" metric.", + "type": "string", + "example": "A" + } + } + }, + "total": { + "description": "An object defining the \"total\" metrics and equation\n", + "type": "object", + "required": [ + "metrics", + "equation" + ], + "properties": { + "metrics": { + "description": "List of metrics with their name, aggregation type, and field.", + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "aggregation", + "field" + ], + "properties": { + "name": { + "description": "The name of the metric. Only valid options are A-Z", + "type": "string", + "example": "A", + "pattern": "^[A-Z]$" + }, + "aggregation": { + "description": "The aggregation type of the metric. Only valid option is \"sum\"", + "type": "string", + "example": "sum", + "enum": [ + "sum" + ] + }, + "field": { + "description": "The field of the metric.", + "type": "string", + "example": "processor.processed" + } + } + } + }, + "equation": { + "description": "The equation to calculate the \"total\" metric.", + "type": "string", + "example": "A" + } + } + } + } + }, + "type": { + "description": "The type of indicator.", + "type": "string", + "example": "sli.metric.custom" + } + } + }, + "time_window_calendar_aligned": { + "title": "Calendar aligned", + "required": [ + "duration", + "isCalendar" + ], + "description": "Defines properties for calendar aligned time window", + "type": "object", + "properties": { + "duration": { + "description": "the duration formatted as {duration}{unit}, accept '1w' (weekly calendar) or '1M' (monthly calendar) only", + "type": "string", + "example": "1M" + }, + "isCalendar": { + "description": "Indicates a calendar aligned time window", + "type": "boolean", + "example": true + } + } + }, + "settings": { + "title": "Settings", + "description": "Defines properties for SLO settings.", + "type": "object", + "properties": { + "syncDelay": { + "description": "The synch delay to apply to the transform. Default 1m", + "type": "string", + "example": "5m" + }, + "frequency": { + "description": "Configure how often the transform runs, default 1m", + "type": "string", + "example": "5m" + } + } + }, + "slo_response": { + "title": "SLO response", + "type": "object", + "properties": { + "id": { + "description": "The identifier of the SLO.", + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + }, + "name": { + "description": "The name of the SLO.", + "type": "string", + "example": "My Service SLO" + }, + "description": { + "description": "The description of the SLO.", + "type": "string", + "example": "My SLO description" + }, + "indicator": { + "oneOf": [ + { + "$ref": "#/components/schemas/indicator_properties_custom_kql" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_availability" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_latency" + }, + { + "$ref": "#/components/schemas/indicator_properties_custom_metric" + } + ] + }, + "timeWindow": { + "oneOf": [ + { + "$ref": "#/components/schemas/time_window_rolling" + }, + { + "$ref": "#/components/schemas/time_window_calendar_aligned" + } + ] + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "settings": { + "$ref": "#/components/schemas/settings" + }, + "revision": { + "description": "The SLO revision", + "type": "number", + "example": 2 + }, + "summary": { + "$ref": "#/components/schemas/summary" + }, + "enabled": { + "description": "Indicate if the SLO is enabled", + "type": "boolean", + "example": true + }, + "createdAt": { + "description": "The creation date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + }, + "updatedAt": { + "description": "The last update date", + "type": "string", + "example": "2023-01-12T10:03:19.000Z" + } + } + }, + "find_slo_response": { + "title": "Find SLO response", + "description": "A paginated response of SLOs matching the query.\n", + "type": "object", + "properties": { + "page": { + "type": "number", + "example": 1 + }, + "perPage": { + "type": "number", + "example": 25 + }, + "total": { + "type": "number", + "example": 34 + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/slo_response" + } + } + } + }, + "create_slo_request": { + "title": "Create SLO request", + "description": "The create SLO API request body varies depending on the type of indicator, time window and budgeting method.\n", + "type": "object", + "required": [ + "name", + "description", + "indicator", + "timeWindow", + "budgetingMethod", + "objective" + ], + "properties": { + "id": { + "description": "A optional and unique identifier for the SLO. Must be between 8 and 36 chars", + "type": "string", + "example": "my-super-slo-id" + }, + "name": { + "description": "A name for the SLO.", + "type": "string" + }, + "description": { + "description": "A description for the SLO.", + "type": "string" + }, + "indicator": { + "oneOf": [ + { + "$ref": "#/components/schemas/indicator_properties_custom_kql" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_availability" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_latency" + }, + { + "$ref": "#/components/schemas/indicator_properties_custom_metric" + } + ] + }, + "timeWindow": { + "oneOf": [ + { + "$ref": "#/components/schemas/time_window_rolling" + }, + { + "$ref": "#/components/schemas/time_window_calendar_aligned" + } + ] + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "settings": { + "$ref": "#/components/schemas/settings" + } + } + }, + "create_slo_response": { + "title": "Create SLO response", + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + } + } + }, + "update_slo_request": { + "title": "Update SLO request", + "description": "The update SLO API request body varies depending on the type of indicator, time window and budgeting method. Partial update is handled.\n", + "type": "object", + "properties": { + "name": { + "description": "A name for the SLO.", + "type": "string" + }, + "description": { + "description": "A description for the SLO.", + "type": "string" + }, + "indicator": { + "oneOf": [ + { + "$ref": "#/components/schemas/indicator_properties_custom_kql" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_availability" + }, + { + "$ref": "#/components/schemas/indicator_properties_apm_latency" + }, + { + "$ref": "#/components/schemas/indicator_properties_custom_metric" + } + ] + }, + "timeWindow": { + "oneOf": [ + { + "$ref": "#/components/schemas/time_window_rolling" + }, + { + "$ref": "#/components/schemas/time_window_calendar_aligned" + } + ] + }, + "budgetingMethod": { + "$ref": "#/components/schemas/budgeting_method" + }, + "objective": { + "$ref": "#/components/schemas/objective" + }, + "settings": { + "$ref": "#/components/schemas/settings" + } + } + }, + "historical_summary_request": { + "title": "Historical summary request", + "type": "object", + "required": [ + "sloIds" + ], + "properties": { + "sloIds": { + "description": "The list of SLO identifiers to get the historical summary for", + "type": "array", + "items": { + "type": "string", + "example": "8853df00-ae2e-11ed-90af-09bb6422b258" + } + } + } + }, + "historical_summary_response": { + "title": "Historical summary response", + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "date": { + "type": "string", + "example": "2022-01-01T00:00:00.000Z" + }, + "status": { + "type": "string", + "enum": [ + "NO_DATA", + "HEALTHY", + "DEGRADING", + "VIOLATED" + ], + "example": "HEALTHY" + }, + "sliValue": { + "type": "number", + "example": 0.9836 + }, + "errorBudget": { + "$ref": "#/components/schemas/error_budget" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml index 59d600a9e1375..f4ef3a5991387 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml @@ -8,14 +8,17 @@ info: license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license +servers: + - url: http://localhost:5601 + description: local +security: + - basicAuth: [] + - apiKeyAuth: [] tags: - name: slo description: SLO APIs enable you to define, manage and track service-level objectives - name: composite slo description: Composite SLO APIs enable you to define, manage and track a group of SLOs. -servers: - - url: http://localhost:5601 - description: local paths: /s/{spaceId}/api/observability/composite_slos: post: @@ -53,6 +56,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '409': description: Conflict - The Composite SLO id already exists content: @@ -121,6 +130,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -158,6 +173,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -200,6 +221,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -232,6 +259,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -274,6 +307,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '409': description: Conflict - The SLO id already exists content: @@ -360,6 +399,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -397,6 +442,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -439,6 +490,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -471,6 +528,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -504,6 +567,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -537,6 +606,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' '404': description: Not found response content: @@ -579,6 +654,12 @@ paths: application/json: schema: $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' components: securitySchemes: basicAuth: @@ -817,6 +898,23 @@ components: message: type: string example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + 403_response: + title: Unauthorized + type: object + required: + - statusCode + - error + - message + properties: + statusCode: + type: number + example: 403 + error: + type: string + example: Unauthorized + message: + type: string + example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" 404_response: title: Not found type: object @@ -1405,6 +1503,3 @@ components: example: 0.9836 errorBudget: $ref: '#/components/schemas/error_budget' -security: - - basicAuth: [] - - apiKeyAuth: [] diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml new file mode 100644 index 0000000000000..24fcbad202a83 --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/403_response.yaml @@ -0,0 +1,16 @@ +title: Unauthorized +type: object +required: + - statusCode + - error + - message +properties: + statusCode: + type: number + example: 403 + error: + type: string + example: Unauthorized + message: + type: string + example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml index e8e3cf75decc3..d77431452136a 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos.yaml @@ -24,16 +24,22 @@ post: $ref: '../components/schemas/create_composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '409': description: Conflict - The Composite SLO id already exists content: @@ -91,19 +97,25 @@ get: $ref: '../components/schemas/find_composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml index 54b3613c7a5c4..bca3976b80fcd 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml @@ -19,19 +19,25 @@ get: $ref: '../components/schemas/composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -63,19 +69,25 @@ put: $ref: '../components/schemas/base_composite_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -97,19 +109,25 @@ delete: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml index 47fec9eee6494..68c0c602448dc 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml @@ -24,16 +24,22 @@ post: $ref: '../components/schemas/create_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '409': description: Conflict - The SLO id already exists content: @@ -65,9 +71,9 @@ get: description: Filter by indicator type schema: type: array - items: + items: type: string - example: ["sli.kql.custom"] + example: ['sli.kql.custom'] - name: page in: query description: The page number to return @@ -107,19 +113,25 @@ get: $ref: '../components/schemas/find_slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml index 48ffe492a5a2b..6ce99505894cf 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@_historical_summary.yaml @@ -18,19 +18,25 @@ post: responses: '200': description: Successful request - content: + content: application/json: schema: $ref: '../components/schemas/historical_summary_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml index cf31ccb2de8bf..66a5ddd7825a8 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}.yaml @@ -19,19 +19,25 @@ get: $ref: '../components/schemas/slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -63,19 +69,25 @@ put: $ref: '../components/schemas/slo_response.yaml' '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: $ref: '../components/schemas/404_response.yaml' @@ -97,19 +109,25 @@ delete: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml index ace5b805cf92f..4932e9cf78c36 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml @@ -15,19 +15,25 @@ post: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml index d751535fe365a..4ddda2bc94b60 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml @@ -15,19 +15,25 @@ post: description: Successful request '400': description: Bad request - content: + content: application/json: schema: $ref: '../components/schemas/400_response.yaml' '401': description: Unauthorized response - content: + content: application/json: schema: $ref: '../components/schemas/401_response.yaml' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '../components/schemas/403_response.yaml' '404': description: Not found response - content: + content: application/json: schema: - $ref: '../components/schemas/404_response.yaml' \ No newline at end of file + $ref: '../components/schemas/404_response.yaml' diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx index 2d71fca18eede..6e73398527523 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx @@ -76,7 +76,7 @@ export function HeaderControl({ isLoading, slo }: Props) { params: { sloId: slo.id }, }, { - replace: true, + replace: false, } ); } diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx index 3d9e70f68dc6e..374b64b567404 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx @@ -106,7 +106,7 @@ export function SloListItem({ params: { sloId: slo.id }, }, { - replace: true, + replace: false, } ); }; diff --git a/x-pack/plugins/observability/server/routes/slo/route.ts b/x-pack/plugins/observability/server/routes/slo/route.ts index 52c6aa3cff0d4..f41d37d4fc573 100644 --- a/x-pack/plugins/observability/server/routes/slo/route.ts +++ b/x-pack/plugins/observability/server/routes/slo/route.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { badRequest, forbidden, failedDependency } from '@hapi/boom'; +import { forbidden, failedDependency } from '@hapi/boom'; import { createSLOParamsSchema, deleteSLOParamsSchema, @@ -68,7 +68,7 @@ const createSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -95,7 +95,7 @@ const updateSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -127,7 +127,7 @@ const deleteSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -153,7 +153,7 @@ const getSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -178,7 +178,7 @@ const enableSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -204,7 +204,7 @@ const disableSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -230,7 +230,7 @@ const findSLORoute = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -255,7 +255,7 @@ const fetchHistoricalSummary = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const soClient = (await context.core).savedObjects.client; @@ -317,7 +317,7 @@ const getSloBurnRates = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; @@ -340,7 +340,7 @@ const getPreviewData = createObservabilityServerRoute({ const hasCorrectLicense = await isLicenseAtLeastPlatinum(context); if (!hasCorrectLicense) { - throw badRequest('Platinum license or higher is needed to make use of this feature.'); + throw forbidden('Platinum license or higher is needed to make use of this feature.'); } const esClient = (await context.core).elasticsearch.client.asCurrentUser; From cd04cd305a29431200f9f8e08211ee0065fcfaca Mon Sep 17 00:00:00 2001 From: Rickyanto Ang Date: Tue, 4 Jul 2023 10:51:09 -0700 Subject: [PATCH 18/64] [Cloud Security][FTR]Refactor API FTR to use .to.eql instead of .to.be (#160694) ## Summary This PR is for refactoring current API FTR to use .to.eql instead of .to.be for more understandable error message when an error occurs. Currently when test fail due to unmatched value, the error message can be quite confusing as we don't know which one is the expected and actual value from current error message. With this change from this PR it's easier to see which is the expected value and which is the actual value Screenshot 2023-06-27 at 7 49 07 PM --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../get_csp_rule_template.ts | 35 +++++-- .../apis/cloud_security_posture/helper.ts | 14 +++ .../status/status_index_timeout.ts | 15 ++- .../status/status_indexed.ts | 15 ++- .../status/status_indexing.ts | 15 ++- .../status_not_deployed_not_installed.ts | 75 ++++++++++++--- .../status/status_unprivileged.ts | 94 ++++++++++++++----- .../status/status_waiting_for_results.ts | 15 ++- 8 files changed, 217 insertions(+), 61 deletions(-) diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts b/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts index 1d91efdc7fe89..99fa403c22635 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/get_csp_rule_template.ts @@ -55,8 +55,9 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(500); - expect(body.message).to.be( - 'Please provide either benchmarkId or packagePolicyId, but not both' + expect(body.message).to.eql( + 'Please provide either benchmarkId or packagePolicyId, but not both', + `expected message to be 'Please provide either benchmarkId or packagePolicyId, but not both' but got ${body.message} instead` ); }); @@ -80,8 +81,9 @@ export default function ({ getService }: FtrProviderContext) { }) .expect(500); - expect(body.message).to.be( - 'Please provide either benchmarkId or packagePolicyId, but not both' + expect(body.message).to.eql( + 'Please provide either benchmarkId or packagePolicyId, but not both', + `expected message to be 'Please provide either benchmarkId or packagePolicyId, but not both' but got ${body.message} instead` ); }); @@ -95,8 +97,14 @@ export default function ({ getService }: FtrProviderContext) { }) .expect(404); - expect(body.statusCode).to.be(404); - expect(body.error).to.be('Not Found'); + expect(body.statusCode).to.eql( + 404, + `expected status code to be 404 but got ${body.statusCode} instead` + ); + expect(body.error).to.eql( + 'Not Found', + `expected error message to be 'Not Found' but got ${body.error} instead` + ); }); it(`Should return 200 status code and filter rules by benchmarkId`, async () => { @@ -124,7 +132,10 @@ export default function ({ getService }: FtrProviderContext) { (rule: CspRuleTemplate) => rule.metadata.benchmark.id === 'cis_k8s' ); - expect(allRulesHaveCorrectBenchmarkId).to.be(true); + expect(allRulesHaveCorrectBenchmarkId).to.eql( + true, + `expected true but got ${allRulesHaveCorrectBenchmarkId} instead` + ); }); it(`Should return 200 status code, and only requested fields in the response`, async () => { @@ -157,7 +168,7 @@ export default function ({ getService }: FtrProviderContext) { ); }); - expect(fieldsMatched).to.be(true); + expect(fieldsMatched).to.eql(true, `expected true but got ${fieldsMatched} instead`); }); it(`Should return 200 status code, items sorted by metadata.section field`, async () => { @@ -188,7 +199,8 @@ export default function ({ getService }: FtrProviderContext) { const isSorted = sections.every( (section, index) => index === 0 || section >= sections[index - 1] ); - expect(isSorted).to.be(true); + + expect(isSorted).to.eql(true, `expected true but got ${isSorted} instead`); }); it(`Should return 200 status code and paginate rules with a limit of PerPage`, async () => { @@ -213,7 +225,10 @@ export default function ({ getService }: FtrProviderContext) { }) .expect(200); - expect(body.items.length).to.be(perPage); + expect(body.items.length).to.eql( + perPage, + `expected length to be ${perPage} but got ${body.items.length} instead` + ); }); }); } diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts b/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts index b659153b1bf69..79aede12385db 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/helper.ts @@ -7,6 +7,8 @@ import type { SuperTest, Test } from 'supertest'; import { Client } from '@elastic/elasticsearch'; +import expect from '@kbn/expect'; +import type { IndexDetails } from '@kbn/cloud-security-posture-plugin/common/types'; import { SecurityService } from '../../../../../test/common/services/security/security'; export const deleteIndex = (es: Client, indexToBeDeleted: string[]) => { @@ -141,3 +143,15 @@ export const deleteRole = async (security: SecurityService, roleName: string) => export const deleteUser = async (security: SecurityService, userName: string) => { await security.user.delete(userName); }; + +export const assertIndexStatus = ( + indicesDetails: IndexDetails[], + indexName: string, + expectedStatus: string +) => { + const actualValue = indicesDetails.find((idx) => idx.index === indexName)?.status; + expect(actualValue).to.eql( + expectedStatus, + `expected ${indexName} status to be ${expectedStatus} but got ${actualValue} instead` + ); +}; diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts index fe52d8d3a0773..2203a6374db70 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_index_timeout.ts @@ -110,7 +110,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('index-timeout'); + expect(res.kspm.status).to.eql( + 'index-timeout', + `expected kspm status to be index-timeout but got ${res.kspm.status} instead` + ); }); it(`Should return index-timeout when installed cspm, has findings only on logs-cloud_security_posture.findings-default* and it has been more than 10 minutes since the installation`, async () => { @@ -137,7 +140,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('index-timeout'); + expect(res.cspm.status).to.eql( + 'index-timeout', + `expected cspm status to be index-timeout but got ${res.cspm.status} instead` + ); }); it(`Should return index-timeout when installed cnvm, has findings only on logs-cloud_security_posture.vulnerabilities-default* and it has been more than 4 hours minutes since the installation`, async () => { @@ -164,7 +170,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('index-timeout'); + expect(res.vuln_mgmt.status).to.eql( + 'index-timeout', + `expected vuln_mgmt status to be index-timeout but got ${res.vuln_mgmt.status} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts index aa9d6d3289e95..594babe643b05 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexed.ts @@ -76,7 +76,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('indexed'); + expect(res.kspm.status).to.eql( + 'indexed', + `expected kspm status to be indexed but got ${res.kspm.status} instead` + ); }); it(`Return cspm status indexed when logs-cloud_security_posture.findings_latest-default contains new cspm documents`, async () => { @@ -95,7 +98,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('indexed'); + expect(res.cspm.status).to.eql( + 'indexed', + `expected cspm status to be indexed but got ${res.cspm.status} instead` + ); }); it(`Return vuln status indexed when logs-cloud_security_posture.vulnerabilities_latest-default contains new documents`, async () => { @@ -114,7 +120,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('indexed'); + expect(res.vuln_mgmt.status).to.eql( + 'indexed', + `expected vuln_mgmt status to be indexed but got ${res.vuln_mgmt.status} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts index ef16eb94d8a33..ef38ab85efb04 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_indexing.ts @@ -75,7 +75,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('indexing'); + expect(res.kspm.status).to.eql( + 'indexing', + `expected kspm status to be indexing but got ${res.kspm.status} instead` + ); }); it(`Return cspm status indexing when logs-cloud_security_posture.findings_latest-default doesn't contain new cspm documents, but has newly connected agents `, async () => { @@ -94,7 +97,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('indexing'); + expect(res.cspm.status).to.eql( + 'indexing', + `expected cspm status to be indexing but got ${res.cspm.status} instead` + ); }); it(`Return vuln status indexing when logs-cloud_security_posture.vulnerabilities_latest-default doesn't contain vuln new documents, but has newly connected agents`, async () => { @@ -113,7 +119,10 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('indexing'); + expect(res.vuln_mgmt.status).to.eql( + 'indexing', + `expected vuln_mgmt status to be indexing but got ${res.vuln_mgmt.status} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts index d7d77c93ecad4..dcfbedae15741 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_not_deployed_not_installed.ts @@ -55,11 +55,26 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('not-deployed'); - expect(res.cspm.status).to.be('not-installed'); - expect(res.vuln_mgmt.status).to.be('not-installed'); - expect(res.kspm.healthyAgents).to.be(0); - expect(res.kspm.installedPackagePolicies).to.be(1); + expect(res.kspm.status).to.eql( + 'not-deployed', + `expected kspm status to be not-deployed but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'not-installed', + `expected cspm status to be not-installed but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-installed', + `expected vuln_mgmt status to be not-installed but got ${res.vuln_mgmt.status} instead` + ); + expect(res.kspm.healthyAgents).to.eql( + 0, + `expected number of kspm healthy agents to be 0 but got ${res.kspm.healthyAgents} instead` + ); + expect(res.kspm.installedPackagePolicies).to.eql( + 1, + `expected number of kspm installed package policies to be 1 but got ${res.kspm.installedPackagePolicies} instead` + ); }); it(`Should return not-deployed when installed cspm, no findings on either indices and no healthy agents`, async () => { @@ -78,11 +93,26 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('not-deployed'); - expect(res.kspm.status).to.be('not-installed'); - expect(res.vuln_mgmt.status).to.be('not-installed'); - expect(res.cspm.healthyAgents).to.be(0); - expect(res.cspm.installedPackagePolicies).to.be(1); + expect(res.cspm.status).to.eql( + 'not-deployed', + `expected cspm status to be not-deployed but got ${res.cspm.status} instead` + ); + expect(res.kspm.status).to.eql( + 'not-installed', + `expected kspm status to be not-installed but got ${res.kspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-installed', + `expected vuln_mgmt status to be not-installed but got ${res.vuln_mgmt.status} instead` + ); + expect(res.cspm.healthyAgents).to.eql( + 0, + `expected number of cspm healthy agents to be 0 but got ${res.cspm.healthyAgents} instead` + ); + expect(res.cspm.installedPackagePolicies).to.eql( + 1, + `expected number of cspm installed package policies to be 1 but got ${res.cspm.installedPackagePolicies} instead` + ); }); it(`Should return not-deployed when installed cnvm, no findings on either indices and no healthy agents`, async () => { @@ -101,11 +131,26 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('not-installed'); - expect(res.kspm.status).to.be('not-installed'); - expect(res.vuln_mgmt.status).to.be('not-deployed'); - expect(res.vuln_mgmt.healthyAgents).to.be(0); - expect(res.vuln_mgmt.installedPackagePolicies).to.be(1); + expect(res.cspm.status).to.eql( + 'not-installed', + `expected cspm status to be not-installed but got ${res.cspm.status} instead` + ); + expect(res.kspm.status).to.eql( + 'not-installed', + `expected kspm status to be not-installed but got ${res.kspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-deployed', + `expected vuln_mgmt status to be not-deployed but got ${res.vuln_mgmt.status} instead` + ); + expect(res.vuln_mgmt.healthyAgents).to.eql( + 0, + `expected number of vuln_mgmt healthy agents to be 0 but got ${res.vuln_mgmt.healthyAgents} instead` + ); + expect(res.vuln_mgmt.installedPackagePolicies).to.eql( + 1, + `expected number of vuln_mgmt installed package policies to be 1 but got ${res.vuln_mgmt.installedPackagePolicies} instead` + ); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts index 2432165566de8..7d1445932fa6c 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_unprivileged.ts @@ -11,6 +11,7 @@ import { BENCHMARK_SCORE_INDEX_DEFAULT_NS, LATEST_FINDINGS_INDEX_DEFAULT_NS, LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, + FINDINGS_INDEX_PATTERN, } from '@kbn/cloud-security-posture-plugin/common/constants'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { @@ -20,6 +21,7 @@ import { deleteRole, deleteUser, deleteIndex, + assertIndexStatus, } from '../helper'; const UNPRIVILEGED_ROLE = 'unprivileged_test_role'; @@ -85,9 +87,18 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('unprivileged'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.vuln_mgmt.status} instead` + ); }); }); @@ -134,14 +145,27 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('unprivileged'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.vuln_mgmt.status} instead` + ); - expect(res.indicesDetails[0].status).to.be('empty'); - expect(res.indicesDetails[1].status).to.be('empty'); - expect(res.indicesDetails[2].status).to.be('unprivileged'); - expect(res.indicesDetails[3].status).to.be('unprivileged'); + assertIndexStatus(res.indicesDetails, LATEST_FINDINGS_INDEX_DEFAULT_NS, 'empty'); + assertIndexStatus(res.indicesDetails, FINDINGS_INDEX_PATTERN, 'empty'); + assertIndexStatus(res.indicesDetails, BENCHMARK_SCORE_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus( + res.indicesDetails, + LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, + 'unprivileged' + ); }); it(`Return unprivileged when missing access to score index`, async () => { @@ -165,14 +189,27 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('unprivileged'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.vuln_mgmt.status} instead` + ); - expect(res.indicesDetails[0].status).to.be('unprivileged'); - expect(res.indicesDetails[1].status).to.be('empty'); - expect(res.indicesDetails[2].status).to.be('empty'); - expect(res.indicesDetails[3].status).to.be('unprivileged'); + assertIndexStatus(res.indicesDetails, LATEST_FINDINGS_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus(res.indicesDetails, FINDINGS_INDEX_PATTERN, 'empty'); + assertIndexStatus(res.indicesDetails, BENCHMARK_SCORE_INDEX_DEFAULT_NS, 'empty'); + assertIndexStatus( + res.indicesDetails, + LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, + 'unprivileged' + ); }); it(`Return unprivileged when missing access to vulnerabilities_latest index`, async () => { @@ -199,14 +236,23 @@ export default function (providerContext: FtrProviderContext) { .auth(UNPRIVILEGED_USERNAME, 'changeme') .expect(200); - expect(res.kspm.status).to.be('unprivileged'); - expect(res.cspm.status).to.be('unprivileged'); - expect(res.vuln_mgmt.status).to.be('not-installed'); + expect(res.kspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.kspm.status} instead` + ); + expect(res.cspm.status).to.eql( + 'unprivileged', + `expected unprivileged but got ${res.cspm.status} instead` + ); + expect(res.vuln_mgmt.status).to.eql( + 'not-installed', + `expected not-installed but got ${res.vuln_mgmt.status} instead` + ); - expect(res.indicesDetails[0].status).to.be('unprivileged'); - expect(res.indicesDetails[1].status).to.be('empty'); - expect(res.indicesDetails[2].status).to.be('unprivileged'); - expect(res.indicesDetails[3].status).to.be('empty'); + assertIndexStatus(res.indicesDetails, LATEST_FINDINGS_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus(res.indicesDetails, FINDINGS_INDEX_PATTERN, 'empty'); + assertIndexStatus(res.indicesDetails, BENCHMARK_SCORE_INDEX_DEFAULT_NS, 'unprivileged'); + assertIndexStatus(res.indicesDetails, LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, 'empty'); }); }); }); diff --git a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts index 53692014f767a..bc6a44100dab0 100644 --- a/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts +++ b/x-pack/test/api_integration/apis/cloud_security_posture/status/status_waiting_for_results.ts @@ -91,7 +91,10 @@ export default function (providerContext: FtrProviderContext) { .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.kspm.status).to.be('waiting_for_results'); + expect(res.kspm.status).to.eql( + 'waiting_for_results', + `expected kspm status to be waiting_for_results but got ${res.kspm.status} instead` + ); }); it(`Should return waiting_for_result when installed cspm, has no findings and it has been less than 10 minutes since the installation`, async () => { @@ -117,7 +120,10 @@ export default function (providerContext: FtrProviderContext) { .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.cspm.status).to.be('waiting_for_results'); + expect(res.cspm.status).to.eql( + 'waiting_for_results', + `expected cspm status to be waiting_for_results but got ${res.cspm.status} instead` + ); }); it(`Should return waiting_for_result when installed cnvm, has no findings and it has been less than 4 hours minutes since the installation`, async () => { @@ -143,7 +149,10 @@ export default function (providerContext: FtrProviderContext) { .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set('kbn-xsrf', 'xxxx') .expect(200); - expect(res.vuln_mgmt.status).to.be('waiting_for_results'); + expect(res.vuln_mgmt.status).to.eql( + 'waiting_for_results', + `expected vuln_mgmt status to be waiting_for_results but got ${res.vuln_mgmt.status} instead` + ); }); }); }); From 6731eb300846fc25440d30ec32c296139175bacc Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 4 Jul 2023 13:55:05 -0400 Subject: [PATCH 19/64] [Synthetics] Perform params API HTTP migration (#160575) Co-authored-by: shahzad31 --- .../monitor_management/synthetics_params.ts | 22 ++++++- .../global_params/add_param_flyout.tsx | 6 +- .../settings/global_params/add_param_form.tsx | 6 +- .../settings/global_params/delete_param.tsx | 4 +- .../settings/global_params/params_list.tsx | 4 +- .../settings/hooks/use_params_list.ts | 7 +-- .../apps/synthetics/state/certs/index.ts | 4 +- .../synthetics/state/global_params/actions.ts | 9 ++- .../synthetics/state/global_params/api.ts | 49 +++++++-------- .../synthetics/state/global_params/index.ts | 7 +-- .../public/utils/api_service/api_service.ts | 59 +++++++------------ .../server/routes/settings/add_param.ts | 41 +++++++++++-- .../server/routes/settings/delete_param.ts | 13 +++- .../server/routes/settings/edit_param.ts | 23 ++++++-- .../server/routes/settings/params.ts | 50 ++++++++++------ .../synthetics_service/synthetics_service.ts | 4 +- .../apis/synthetics/add_edit_params.ts | 54 +++++++++-------- .../apis/synthetics/sync_global_params.ts | 17 +++--- 18 files changed, 222 insertions(+), 157 deletions(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts index 078dfa7b45d04..9c2a5b1eb4ff1 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_params.ts @@ -7,10 +7,10 @@ import * as t from 'io-ts'; -export const SyntheticsParamSOCodec = t.intersection([ +export const SyntheticsParamsReadonlyCodec = t.intersection([ t.interface({ + id: t.string, key: t.string, - value: t.string, }), t.partial({ description: t.string, @@ -19,7 +19,23 @@ export const SyntheticsParamSOCodec = t.intersection([ }), ]); -export type SyntheticsParamSO = t.TypeOf; +export type SyntheticsParamsReadonly = t.TypeOf; + +export const SyntheticsParamsCodec = t.intersection([ + SyntheticsParamsReadonlyCodec, + t.interface({ value: t.string }), +]); + +export type SyntheticsParams = t.TypeOf; + +export type SyntheticsParamSOAttributes = t.TypeOf; + +export const DeleteParamsResponseCodec = t.interface({ + id: t.string, + deleted: t.boolean, +}); + +export type DeleteParamsResponse = t.TypeOf; export const SyntheticsParamRequestCodec = t.intersection([ t.interface({ diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx index 4181afdfd6a3e..c79e5aec2177a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_flyout.tsx @@ -31,7 +31,7 @@ import { } from '../../../state/global_params'; import { ClientPluginsStart } from '../../../../../plugin'; import { ListParamItem } from './params_list'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { useFormWrapped } from '../../../../../hooks/use_form_wrapped'; import { AddParamForm } from './add_param_form'; import { syncGlobalParamsAction } from '../../../state/settings'; @@ -49,7 +49,7 @@ export const AddParamFlyout = ({ const { id, ...dataToSave } = isEditingItem ?? {}; - const form = useFormWrapped({ + const form = useFormWrapped({ mode: 'onSubmit', reValidateMode: 'onChange', shouldFocusError: true, @@ -77,7 +77,7 @@ export const AddParamFlyout = ({ const { isSaving, savedData } = useSelector(selectGlobalParamState); - const onSubmit = (formData: SyntheticsParamSO) => { + const onSubmit = (formData: SyntheticsParams) => { const { namespaces, ...paramRequest } = formData; const shareAcrossSpaces = namespaces?.includes(ALL_SPACES_ID); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx index 240314dc3b06f..1b219a0f6fec4 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/add_param_form.tsx @@ -16,7 +16,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Controller, useFormContext, useFormState } from 'react-hook-form'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { ListParamItem } from './params_list'; export const AddParamForm = ({ @@ -26,8 +26,8 @@ export const AddParamForm = ({ items: ListParamItem[]; isEditingItem: ListParamItem | null; }) => { - const { register, control } = useFormContext(); - const { errors } = useFormState(); + const { register, control } = useFormContext(); + const { errors } = useFormState(); const tagsList = items.reduce((acc, item) => { const tags = item.tags || []; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx index 21d3c158c3326..aa89829380044 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/delete_param.tsx @@ -35,14 +35,14 @@ export const DeleteParam = ({ const { status } = useFetcher(() => { if (isDeleting) { - return deleteGlobalParams({ ids: items.map(({ id }) => id) }); + return deleteGlobalParams(items.map(({ id }) => id)); } }, [items, isDeleting]); const name = items .map(({ key }) => key) .join(', ') - .substr(0, 50); + .slice(0, 50); useEffect(() => { if (!isDeleting) { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx index fc8aef5d56732..58769a7e688fe 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/global_params/params_list.tsx @@ -24,12 +24,12 @@ import { EuiBasicTableColumn } from '@elastic/eui/src/components/basic_table/bas import { useDebounce } from 'react-use'; import { TableTitle } from '../../common/components/table_title'; import { ParamsText } from './params_text'; -import { SyntheticsParamSO } from '../../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../../common/runtime_types'; import { useParamsList } from '../hooks/use_params_list'; import { AddParamFlyout } from './add_param_flyout'; import { DeleteParam } from './delete_param'; -export interface ListParamItem extends SyntheticsParamSO { +export interface ListParamItem extends SyntheticsParams { id: string; } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts index 4f86ca5eb8d80..40006c262923e 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/settings/hooks/use_params_list.ts @@ -20,12 +20,7 @@ export const useParamsList = () => { return useMemo(() => { return { - items: - listOfParams?.map((item) => ({ - id: item.id, - ...item.attributes, - namespaces: item.namespaces, - })) ?? [], + items: listOfParams ?? [], isLoading, }; }, [listOfParams, isLoading]); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts index f21df69bcbbce..708e1bb004a74 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/certs/index.ts @@ -6,7 +6,7 @@ */ import { createReducer } from '@reduxjs/toolkit'; -import { CertResult, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { CertResult, SyntheticsParams } from '../../../../../common/runtime_types'; import { IHttpSerializedFetchError } from '..'; import { getCertsListAction } from './actions'; @@ -15,7 +15,7 @@ export interface CertsListState { data?: CertResult; error: IHttpSerializedFetchError | null; isSaving?: boolean; - savedData?: SyntheticsParamSO; + savedData?: SyntheticsParams; } const initialState: CertsListState = { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts index 14b5040282f52..b1388bc2674b9 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts @@ -5,15 +5,14 @@ * 2.0. */ -import { SavedObject } from '@kbn/core-saved-objects-common'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { SyntheticsParamRequest, SyntheticsParams } from '../../../../../common/runtime_types'; import { createAsyncAction } from '../utils/actions'; -export const getGlobalParamAction = createAsyncAction>>( +export const getGlobalParamAction = createAsyncAction( 'GET GLOBAL PARAMS' ); -export const addNewGlobalParamAction = createAsyncAction( +export const addNewGlobalParamAction = createAsyncAction( 'ADD NEW GLOBAL PARAM' ); @@ -22,5 +21,5 @@ export const editGlobalParamAction = createAsyncAction< id: string; paramRequest: SyntheticsParamRequest; }, - SyntheticsParamSO + SyntheticsParams >('EDIT GLOBAL PARAM'); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts index 3fd5e8678d94b..528921f1d5bf4 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts @@ -5,23 +5,28 @@ * 2.0. */ -import { SavedObject } from '@kbn/core-saved-objects-common'; import { SYNTHETICS_API_URLS } from '../../../../../common/constants'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { + DeleteParamsResponse, + SyntheticsParamRequest, + SyntheticsParams, + SyntheticsParamsCodec, + SyntheticsParamsReadonlyCodec, +} from '../../../../../common/runtime_types'; import { apiService } from '../../../../utils/api_service/api_service'; -export const getGlobalParams = async (): Promise>> => { - const result = (await apiService.get(SYNTHETICS_API_URLS.PARAMS)) as { - data: Array>; - }; - return result.data; +export const getGlobalParams = async (): Promise => { + return apiService.get( + SYNTHETICS_API_URLS.PARAMS, + undefined, + SyntheticsParamsReadonlyCodec + ); }; export const addGlobalParam = async ( paramRequest: SyntheticsParamRequest -): Promise => { - return apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest); -}; +): Promise => + apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest, SyntheticsParamsCodec); export const editGlobalParam = async ({ paramRequest, @@ -29,19 +34,17 @@ export const editGlobalParam = async ({ }: { id: string; paramRequest: SyntheticsParamRequest; -}): Promise => { - return apiService.put(SYNTHETICS_API_URLS.PARAMS, { - id, - ...paramRequest, - }); -}; +}): Promise => + apiService.put( + SYNTHETICS_API_URLS.PARAMS, + { + id, + ...paramRequest, + }, + SyntheticsParamsCodec + ); -export const deleteGlobalParams = async ({ - ids, -}: { - ids: string[]; -}): Promise => { - return apiService.delete(SYNTHETICS_API_URLS.PARAMS, { +export const deleteGlobalParams = async (ids: string[]): Promise => + apiService.delete(SYNTHETICS_API_URLS.PARAMS, { ids: JSON.stringify(ids), }); -}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts index 6555518b6c505..89b3a0b7e1904 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts @@ -6,18 +6,17 @@ */ import { createReducer } from '@reduxjs/toolkit'; -import { SavedObject } from '@kbn/core-saved-objects-common'; -import { SyntheticsParamSO } from '../../../../../common/runtime_types'; +import { SyntheticsParams } from '../../../../../common/runtime_types'; import { IHttpSerializedFetchError } from '..'; import { addNewGlobalParamAction, editGlobalParamAction, getGlobalParamAction } from './actions'; export interface GlobalParamsState { isLoading?: boolean; - listOfParams?: Array>; + listOfParams?: SyntheticsParams[]; addError: IHttpSerializedFetchError | null; editError: IHttpSerializedFetchError | null; isSaving?: boolean; - savedData?: SyntheticsParamSO; + savedData?: SyntheticsParams; } const initialState: GlobalParamsState = { diff --git a/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts b/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts index b73b353f708f2..9dead89809ee9 100644 --- a/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts +++ b/x-pack/plugins/synthetics/public/utils/api_service/api_service.ts @@ -41,20 +41,7 @@ class ApiService { return ApiService.instance; } - public async get( - apiUrl: string, - params?: HttpFetchQuery, - decodeType?: any, - asResponse = false - ) { - const response = await this._http!.fetch({ - path: apiUrl, - query: params, - asResponse, - }); - - this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); - + private parseResponse(response: Awaited, apiUrl: string, decodeType?: any): T { if (decodeType) { const decoded = decodeType.decode(response); if (isRight(decoded)) { @@ -69,10 +56,26 @@ class ApiService { ); } } - return response; } + public async get( + apiUrl: string, + params?: HttpFetchQuery, + decodeType?: any, + asResponse = false + ) { + const response = await this._http!.fetch({ + path: apiUrl, + query: params, + asResponse, + }); + + this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); + + return this.parseResponse(response, apiUrl, decodeType); + } + public async post(apiUrl: string, data?: any, decodeType?: any, params?: HttpFetchQuery) { const response = await this._http!.post(apiUrl, { method: 'POST', @@ -82,18 +85,7 @@ class ApiService { this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false }); - if (decodeType) { - const decoded = decodeType.decode(response); - if (isRight(decoded)) { - return decoded.right as T; - } else { - // eslint-disable-next-line no-console - console.warn( - `API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}` - ); - } - } - return response; + return this.parseResponse(response, apiUrl, decodeType); } public async put(apiUrl: string, data?: any, decodeType?: any) { @@ -102,18 +94,7 @@ class ApiService { body: JSON.stringify(data), }); - if (decodeType) { - const decoded = decodeType.decode(response); - if (isRight(decoded)) { - return decoded.right as T; - } else { - // eslint-disable-next-line no-console - console.warn( - `API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}` - ); - } - } - return response; + return this.parseResponse(response, apiUrl, decodeType); } public async delete(apiUrl: string, params?: HttpFetchQuery) { diff --git a/x-pack/plugins/synthetics/server/routes/settings/add_param.ts b/x-pack/plugins/synthetics/server/routes/settings/add_param.ts index b27ddf27a88b3..875e4da8694e1 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/add_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/add_param.ts @@ -8,8 +8,13 @@ import { schema } from '@kbn/config-schema'; import { ALL_SPACES_ID } from '@kbn/security-plugin/common/constants'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; +import { IKibanaResponse } from '@kbn/core/server'; import { SyntheticsRestApiRouteFactory } from '../types'; -import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../common/runtime_types'; +import { + SyntheticsParamRequest, + SyntheticsParams, + SyntheticsParamSOAttributes, +} from '../../../common/runtime_types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; @@ -26,7 +31,12 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ }), }, writeAccess: true, - handler: async ({ request, response, server, savedObjectsClient }): Promise => { + handler: async ({ + request, + response, + server, + savedObjectsClient, + }): Promise> => { try { const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { id: DEFAULT_SPACE_ID, @@ -34,14 +44,33 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ const { share_across_spaces: shareAcrossSpaces, ...data } = request.body as SyntheticsParamRequest; - const result = await savedObjectsClient.create(syntheticsParamType, data, { - initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId], + const { + attributes: { key, tags, description }, + id, + namespaces, + } = await savedObjectsClient.create>( + syntheticsParamType, + data, + { + initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId], + } + ); + return response.ok({ + body: { + id, + description, + key, + namespaces, + tags, + value: data.value, + }, }); - return { data: result }; } catch (error) { if (error.output?.statusCode === 404) { const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; - return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } }); + return response.notFound({ + body: { message: `Kibana space '${spaceId}' does not exist` }, + }); } throw error; diff --git a/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts b/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts index 7dd839a321088..dc529902b730f 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/delete_param.ts @@ -5,10 +5,12 @@ * 2.0. */ +import { IKibanaResponse } from '@kbn/core/server'; import { schema } from '@kbn/config-schema'; import { SyntheticsRestApiRouteFactory } from '../types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; +import { DeleteParamsResponse } from '../../../common/runtime_types'; export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ method: 'DELETE', @@ -19,7 +21,11 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => }), }, writeAccess: true, - handler: async ({ savedObjectsClient, request }): Promise => { + handler: async ({ + savedObjectsClient, + request, + response, + }): Promise> => { const { ids } = request.query as { ids: string }; const parsedIds = JSON.parse(ids) as string[]; @@ -27,7 +33,8 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => parsedIds.map((id) => ({ type: syntheticsParamType, id })), { force: true } ); - - return { data: result }; + return response.ok({ + body: result.statuses.map(({ id, success }) => ({ id, deleted: success })), + }); }, }); diff --git a/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts b/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts index 0201f350249c6..b235d0b323c8b 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/edit_param.ts @@ -6,9 +6,10 @@ */ import { schema } from '@kbn/config-schema'; +import { IKibanaResponse, SavedObject } from '@kbn/core/server'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SyntheticsRestApiRouteFactory } from '../types'; -import { SyntheticsParamRequest } from '../../../common/runtime_types'; +import { SyntheticsParamRequest, SyntheticsParams } from '../../../common/runtime_types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; @@ -26,7 +27,12 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ }), }, writeAccess: true, - handler: async ({ savedObjectsClient, request, response, server }): Promise => { + handler: async ({ + savedObjectsClient, + request, + response, + server, + }): Promise> => { try { const { id: _spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { id: DEFAULT_SPACE_ID, @@ -39,9 +45,18 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ id: string; }; - const result = await savedObjectsClient.update(syntheticsParamType, id, data); + const { value } = data; + const { + id: responseId, + attributes: { key, tags, description }, + namespaces, + } = (await savedObjectsClient.update( + syntheticsParamType, + id, + data + )) as SavedObject; - return { data: result }; + return response.ok({ body: { id: responseId, key, tags, description, namespaces, value } }); } catch (error) { if (error.output?.statusCode === 404) { const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; diff --git a/x-pack/plugins/synthetics/server/routes/settings/params.ts b/x-pack/plugins/synthetics/server/routes/settings/params.ts index 5622438ab47c0..789761c529e84 100644 --- a/x-pack/plugins/synthetics/server/routes/settings/params.ts +++ b/x-pack/plugins/synthetics/server/routes/settings/params.ts @@ -5,52 +5,66 @@ * 2.0. */ +import { IKibanaResponse } from '@kbn/core/server'; import { SavedObjectsFindResult } from '@kbn/core-saved-objects-api-server'; -import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SyntheticsRestApiRouteFactory } from '../types'; import { syntheticsParamType } from '../../../common/types/saved_objects'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; +import { SyntheticsParams, SyntheticsParamsReadonly } from '../../../common/runtime_types'; -export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({ +type SyntheticsParamsResponse = + | IKibanaResponse + | IKibanaResponse; +export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory< + SyntheticsParamsResponse +> = () => ({ method: 'GET', path: SYNTHETICS_API_URLS.PARAMS, validate: {}, - handler: async ({ savedObjectsClient, request, response, server }): Promise => { + handler: async ({ savedObjectsClient, request, response, server, spaceId }) => { try { const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); - const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? { - id: DEFAULT_SPACE_ID, - }; - const canSave = (await server.coreStart?.capabilities.resolveCapabilities(request)).uptime.save ?? false; if (canSave) { const finder = - await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({ - type: syntheticsParamType, - perPage: 1000, - namespaces: [spaceId], - }); + await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( + { + type: syntheticsParamType, + perPage: 1000, + namespaces: [spaceId], + } + ); - const hits: SavedObjectsFindResult[] = []; + const hits: Array> = []; for await (const result of finder.find()) { hits.push(...result.saved_objects); } - return { data: hits }; + return response.ok({ + body: hits.map(({ id, attributes, namespaces }) => ({ + ...attributes, + id, + namespaces, + })), + }); } else { - const data = await savedObjectsClient.find({ + const data = await savedObjectsClient.find({ type: syntheticsParamType, perPage: 10000, }); - - return { data: data.saved_objects }; + return response.ok({ + body: data.saved_objects.map(({ id, attributes, namespaces }) => ({ + ...attributes, + namespaces, + id, + })), + }); } } catch (error) { if (error.output?.statusCode === 404) { - const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID; return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } }); } diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index a464e4ea0f971..ecfb10cc1632f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -36,7 +36,7 @@ import { ServiceLocations, SyntheticsMonitorWithId, SyntheticsMonitorWithSecrets, - SyntheticsParamSO, + SyntheticsParams, ThrottlingOptions, } from '../../common/runtime_types'; import { getServiceLocations } from './get_service_locations'; @@ -599,7 +599,7 @@ export class SyntheticsService { const paramsBySpace: Record> = Object.create(null); const finder = - await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser({ + await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser({ type: syntheticsParamType, perPage: 1000, namespaces: spaceId ? [spaceId] : undefined, diff --git a/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts b/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts index b052a06e8bf52..f5d9256a13b4d 100644 --- a/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts +++ b/x-pack/test/api_integration/apis/synthetics/add_edit_params.ts @@ -4,13 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { v4 as uuidv4 } from 'uuid'; +import { pick } from 'lodash'; import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; import expect from '@kbn/expect'; import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects'; import { FtrProviderContext } from '../../ftr_provider_context'; import { PrivateLocationTestService } from './services/private_location_test_service'; +function assertHas(actual: unknown, expected: object) { + expect(pick(actual, Object.keys(expected))).eql(expected); +} + export default function ({ getService }: FtrProviderContext) { describe('AddEditParams', function () { this.tags('skipCloud'); @@ -40,7 +46,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].attributes).eql(testParam); + assertHas(getResponse.body[0], testParam); }); it('handles tags and description', async () => { @@ -63,11 +69,11 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].attributes).eql(testParam2); + assertHas(getResponse.body[0], testParam2); }); it('handles editing a param', async () => { - const updatedParam = { + const expectedUpdatedParam = { key: 'testUpdated', value: 'testUpdated', tags: ['a tag'], @@ -84,21 +90,21 @@ export default function ({ getService }: FtrProviderContext) { .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') - .send({ ...updatedParam, id: param.id }) + .send({ ...expectedUpdatedParam, id: param.id }) .expect(200); const updatedGetResponse = await supertestAPI .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const updatedParamSO = updatedGetResponse.body.data[0]; - expect(updatedParamSO.attributes).eql(updatedParam); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, expectedUpdatedParam); }); it('handles spaces', async () => { @@ -118,8 +124,8 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].namespaces).eql([SPACE_ID]); - expect(getResponse.body.data[0].attributes).eql(testParam); + expect(getResponse.body[0].namespaces).eql([SPACE_ID]); + assertHas(getResponse.body[0], testParam); }); it('handles editing a param in spaces', async () => { @@ -128,7 +134,7 @@ export default function ({ getService }: FtrProviderContext) { await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); - const updatedParam = { + const expectedUpdatedParam = { key: 'testUpdated', value: 'testUpdated', tags: ['a tag'], @@ -145,21 +151,21 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') - .send({ ...updatedParam, id: param.id }) + .send({ ...expectedUpdatedParam, id: param.id }) .expect(200); const updatedGetResponse = await supertestAPI .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const updatedParamSO = updatedGetResponse.body.data[0]; - expect(updatedParamSO.attributes).eql(updatedParam); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, expectedUpdatedParam); }); it('does not allow editing a param in created in one space in a different space', async () => { @@ -188,8 +194,8 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); // space does exist so get request should be 200 await supertestAPI @@ -207,8 +213,8 @@ export default function ({ getService }: FtrProviderContext) { .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`) .set('kbn-xsrf', 'true') .expect(200); - const updatedParamSO = updatedGetResponse.body.data[0]; - expect(updatedParamSO.attributes).eql(testParam); + const actualUpdatedParam = updatedGetResponse.body[0]; + assertHas(actualUpdatedParam, testParam); }); it('handles invalid spaces', async () => { @@ -241,8 +247,8 @@ export default function ({ getService }: FtrProviderContext) { .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - const param = getResponse.body.data[0]; - expect(param.attributes).eql(testParam); + const param = getResponse.body[0]; + assertHas(param, testParam); await supertestAPI .put(`/s/doesnotexist${SYNTHETICS_API_URLS.PARAMS}`) @@ -268,8 +274,8 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data[0].namespaces).eql(['*']); - expect(getResponse.body.data[0].attributes).eql(testParam); + expect(getResponse.body[0].namespaces).eql(['*']); + assertHas(getResponse.body[0], testParam); }); }); } diff --git a/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts b/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts index 2840f8f3935f6..e8182d97e0fee 100644 --- a/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts +++ b/x-pack/test/api_integration/apis/synthetics/sync_global_params.ts @@ -7,7 +7,7 @@ import { ConfigKey, HTTPFields, - SyntheticsParamSO, + SyntheticsParams, } from '@kbn/synthetics-plugin/common/runtime_types'; import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; import { omit } from 'lodash'; @@ -15,7 +15,6 @@ import { secretKeys } from '@kbn/synthetics-plugin/common/constants/monitor_mana import { PackagePolicy } from '@kbn/fleet-plugin/common'; import expect from '@kbn/expect'; import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects'; -import { SavedObject } from '@kbn/core-saved-objects-server'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getFixtureJson } from './helper/get_fixture_json'; import { PrivateLocationTestService } from './services/private_location_test_service'; @@ -157,8 +156,8 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.status).eql(200); - apiResponse.body.data.forEach(({ attributes }: SavedObject) => { - params[attributes.key] = attributes.value; + apiResponse.body.forEach(({ key, value }: SyntheticsParams) => { + params[key] = value; }); }); @@ -257,23 +256,25 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'true') .expect(200); - expect(getResponse.body.data.length).eql(2); + expect(getResponse.body.length).eql(2); - const paramsResponse = getResponse.body.data || []; + const paramsResponse = getResponse.body || []; const ids = paramsResponse.map((param: any) => param.id); - await supertestAPI + const deleteResponse = await supertestAPI .delete(SYNTHETICS_API_URLS.PARAMS) .query({ ids: JSON.stringify(ids) }) .set('kbn-xsrf', 'true') .expect(200); + expect(deleteResponse.body).to.have.length(2); + const getResponseAfterDelete = await supertestAPI .get(SYNTHETICS_API_URLS.PARAMS) .set('kbn-xsrf', 'true') .expect(200); - expect(getResponseAfterDelete.body.data.length).eql(0); + expect(getResponseAfterDelete.body.length).eql(0); await supertestAPI .get(SYNTHETICS_API_URLS.SYNC_GLOBAL_PARAMS) From 803d139adc0df932146c6e21c2814c4fc2921bd3 Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Tue, 4 Jul 2023 15:35:40 -0500 Subject: [PATCH 20/64] [data views] Fix overwrite param for create (#160953) ## Summary Under some circumstances passing `override` to `POST /api/data_views/data_view` would fail. Its now fixed. To test - Try using the override param from the Kibana dev console. I found it reproduced the problem before the fix and shows its resolved after the fix. The problem did not appear in the integration tests. I suspect the problem had to do with how quickly the delete was performed - if it completed before the create command then everything was fine. If it didn't then the error would appear. Passing the overwrite param to the saved object client eliminates the possibility of the delete failing to complete. Closes https://github.com/elastic/kibana/issues/161016 --- .../common/content_management/v1/cm_services.ts | 1 + .../common/content_management/v1/types.ts | 1 + .../data_views/common/data_views/data_views.ts | 15 ++++++++++----- src/plugins/data_views/common/types.ts | 2 +- .../data_views/fields_api/update_fields/main.ts | 1 + 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/plugins/data_views/common/content_management/v1/cm_services.ts b/src/plugins/data_views/common/content_management/v1/cm_services.ts index 7ff2d135a9d90..e425a40cce433 100644 --- a/src/plugins/data_views/common/content_management/v1/cm_services.ts +++ b/src/plugins/data_views/common/content_management/v1/cm_services.ts @@ -54,6 +54,7 @@ const dataViewSavedObjectSchema = savedObjectSchema(dataViewAttributesSchema); const dataViewCreateOptionsSchema = schema.object({ id: createOptionsSchemas.id, initialNamespaces: createOptionsSchemas.initialNamespaces, + overwrite: schema.maybe(createOptionsSchemas.overwrite), }); const dataViewSearchOptionsSchema = schema.object({ diff --git a/src/plugins/data_views/common/content_management/v1/types.ts b/src/plugins/data_views/common/content_management/v1/types.ts index 1bada30b8dd94..19637bb17e8c5 100644 --- a/src/plugins/data_views/common/content_management/v1/types.ts +++ b/src/plugins/data_views/common/content_management/v1/types.ts @@ -18,6 +18,7 @@ import { DataViewContentType } from './constants'; interface DataViewCreateOptions { id?: SavedObjectCreateOptions['id']; initialNamespaces?: SavedObjectCreateOptions['initialNamespaces']; + overwrite?: SavedObjectCreateOptions['overwrite']; } interface DataViewUpdateOptions { diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts index 947e8884bc7cc..f51189f2409ea 100644 --- a/src/plugins/data_views/common/data_views/data_views.ts +++ b/src/plugins/data_views/common/data_views/data_views.ts @@ -167,7 +167,7 @@ export interface DataViewsServicePublicMethods { */ createSavedObject: ( indexPattern: DataView, - override?: boolean, + overwrite?: boolean, displayErrors?: boolean ) => Promise; /** @@ -964,12 +964,16 @@ export class DataViewsService { async createAndSave( spec: DataViewSpec, - override = false, + overwrite = false, skipFetchFields = false, displayErrors = true ) { const indexPattern = await this.createFromSpec(spec, skipFetchFields, displayErrors); - const createdIndexPattern = await this.createSavedObject(indexPattern, override, displayErrors); + const createdIndexPattern = await this.createSavedObject( + indexPattern, + overwrite, + displayErrors + ); await this.setDefault(createdIndexPattern.id!); return createdIndexPattern!; } @@ -981,14 +985,14 @@ export class DataViewsService { * @param displayErrors - If set false, API consumer is responsible for displaying and handling errors. */ - async createSavedObject(dataView: DataView, override = false, displayErrors = true) { + async createSavedObject(dataView: DataView, overwrite = false, displayErrors = true) { if (!(await this.getCanSave())) { throw new DataViewInsufficientAccessError(); } const dupe = await findByName(this.savedObjectsClient, dataView.getName()); if (dupe) { - if (override) { + if (overwrite) { await this.delete(dupe.id); } else { throw new DuplicateDataViewError(`Duplicate data view: ${dataView.getName()}`); @@ -1000,6 +1004,7 @@ export class DataViewsService { const response: SavedObject = (await this.savedObjectsClient.create(body, { id: dataView.id, initialNamespaces: dataView.namespaces.length > 0 ? dataView.namespaces : undefined, + overwrite, })) as SavedObject; const createdIndexPattern = await this.initFromSavedObject(response, displayErrors); diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts index 6c42664c90ffb..aa157d5336685 100644 --- a/src/plugins/data_views/common/types.ts +++ b/src/plugins/data_views/common/types.ts @@ -297,7 +297,7 @@ export interface SavedObjectsClientCommon { create: ( attributes: DataViewAttributes, // SavedObjectsCreateOptions - options: { id?: string; initialNamespaces?: string[] } + options: { id?: string; initialNamespaces?: string[]; overwrite?: boolean } ) => Promise; /** * Delete a saved object by id diff --git a/test/api_integration/apis/data_views/fields_api/update_fields/main.ts b/test/api_integration/apis/data_views/fields_api/update_fields/main.ts index d48dd90396e16..40c03bbec46c1 100644 --- a/test/api_integration/apis/data_views/fields_api/update_fields/main.ts +++ b/test/api_integration/apis/data_views/fields_api/update_fields/main.ts @@ -437,6 +437,7 @@ export default function ({ getService }: FtrProviderContext) { const title = indexPattern.title; await supertest.delete(`${config.path}/${indexPattern.id}`); const response1 = await supertest.post(config.path).send({ + override: true, [config.serviceKey]: { title, fields: { From 38abb33c35473f42ef324508ae217b9c7748ef4e Mon Sep 17 00:00:00 2001 From: Nick Clark Date: Wed, 5 Jul 2023 12:27:46 +1000 Subject: [PATCH 21/64] Fix errors in custom metric payload in SLO dev docs (#161141) --- x-pack/plugins/observability/dev_docs/slo.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/observability/dev_docs/slo.md b/x-pack/plugins/observability/dev_docs/slo.md index 908bf0a031be4..ab605e51ffd27 100644 --- a/x-pack/plugins/observability/dev_docs/slo.md +++ b/x-pack/plugins/observability/dev_docs/slo.md @@ -337,17 +337,17 @@ curl --request POST \ "field": "processor.processed" } ], - equation: 'A' + "equation": "A" }, "total": { "metrics": [ { "name": "A", "aggregation": "sum", - "processor.accepted" + "field": "processor.accepted" } ], - equation: 'A' + "equation": "A" }, "filter": "", "timestampField": "@timestamp" From 74c3658dd6625a15899210fb83b6ad980f955e10 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 5 Jul 2023 00:52:31 -0400 Subject: [PATCH 22/64] [api-docs] 2023-07-05 Daily api_docs build (#161225) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/389 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 4 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- 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_chat_provider.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/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 44 ++----- api_docs/data.mdx | 4 +- api_docs/data_query.mdx | 4 +- api_docs/data_search.mdx | 4 +- 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.devdocs.json | 120 ++++++++++-------- api_docs/data_views.mdx | 4 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 10 +- 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/ecs_data_quality_dashboard.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/ess_security.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.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.mdx | 2 +- 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_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.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.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- 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_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.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 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.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 +- 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 +- ...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 +- ...kbn_core_saved_objects_common.devdocs.json | 28 ---- 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_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_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_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.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.devdocs.json | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.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_expandable_flyout.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_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- 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_infra_forge.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_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.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_random_sampling.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_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../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 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- 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_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.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_chrome_navigation.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_types.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_text_based_editor.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_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.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.mdx | 2 +- api_docs/management.devdocs.json | 32 +++++ api_docs/management.mdx | 4 +- 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/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 10 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.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/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/serverless_security.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/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- 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_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/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 549 files changed, 673 insertions(+), 669 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index ad17a9658141d..458a5e8c9a600 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-07-04 +date: 2023-07-05 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 d34f6b34e8a88..d9b48790601d4 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-07-04 +date: 2023-07-05 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 5d81becf0cec8..af01029abd03c 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-07-04 +date: 2023-07-05 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 67ed79d64cdc4..c967aa3c52c1b 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -3152,7 +3152,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -3168,7 +3168,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 83e91fe75b1de..e676fa9012982 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index db7a984011e21..bb1ae41c78010 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index f40dd13702525..ab465634b7fad 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 7d6e5adc83ee9..02eaf1c996052 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-07-04 +date: 2023-07-05 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 2a2fb8a2a5798..88a9a1a56b539 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-07-04 +date: 2023-07-05 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 a87c0da4c59a7..33b9d541849d5 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-07-04 +date: 2023-07-05 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 6a2cd6b198323..732a105f75e1a 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-07-04 +date: 2023-07-05 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 48885ef8148b9..7ec5590bc8cea 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-07-04 +date: 2023-07-05 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 2700c0dafcff8..750dbc1f0843d 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-07-04 +date: 2023-07-05 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 9f18be8b202d4..d1e2e01d8026d 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index 6506992af3dbb..d56a91c08416a 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 7fabe7cee93bd..0f5aa80fa2e39 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-07-04 +date: 2023-07-05 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 bc999ca7a36e4..bbab50b2fcb67 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-07-04 +date: 2023-07-05 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 73b6bdc2b3fed..864b49b9dca8d 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-07-04 +date: 2023-07-05 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 6a25bf5adb97a..30f67a44a0545 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-07-04 +date: 2023-07-05 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 2529761f7d5dd..758799ddfb73f 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 2318d55651cf4..d191620df4054 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 040339a191968..1a6ed1ab648bf 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 409fc55ae8097..48fb0d4a13824 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-07-04 +date: 2023-07-05 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 2d9cce85dce5a..5ad5c977a1182 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-07-04 +date: 2023-07-05 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 7a9159bc2af6c..9899d1c60a960 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 6e1ba8e0ec9f5..d46b463e72cfa 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -13292,10 +13292,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -16822,7 +16818,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -16864,10 +16860,8 @@ "id": "def-server.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -16931,7 +16925,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -16973,10 +16967,8 @@ "id": "def-server.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -20951,10 +20943,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -25352,7 +25340,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25394,10 +25382,8 @@ "id": "def-common.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -25461,7 +25447,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25503,10 +25489,8 @@ "id": "def-common.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -28342,7 +28326,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -28358,7 +28342,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index e102c339d573d..604c99e7e8a77 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2579 | 27 | +| 3303 | 119 | 2583 | 27 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index ce23f808c4b9b..6e46268866697 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2579 | 27 | +| 3303 | 119 | 2583 | 27 | ## Client diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 5ecdb2c2554a4..9806722c48786 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2579 | 27 | +| 3303 | 119 | 2583 | 27 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index d8be969b12b09..1f9bc9babfa75 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-07-04 +date: 2023-07-05 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 937820ce7b332..b9fa2718553ca 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-07-04 +date: 2023-07-05 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 b01a33cf59a80..4d03b9127920b 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index c88fad679a3bb..96ce68eb2e53c 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -111,10 +111,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -4926,7 +4922,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -4968,10 +4964,8 @@ "id": "def-public.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -5035,7 +5029,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -5077,10 +5071,8 @@ "id": "def-public.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -7804,7 +7796,7 @@ "section": "def-common.DataViewAttributes", "text": "DataViewAttributes" }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; }) => Promise<", + ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -7879,6 +7871,20 @@ "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-public.SavedObjectsClientCommon.create.$2.overwrite", + "type": "CompoundType", + "tags": [], + "label": "overwrite", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false } ] } @@ -8420,10 +8426,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -12276,7 +12278,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -12318,10 +12320,8 @@ "id": "def-server.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -12385,7 +12385,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -12427,10 +12427,8 @@ "id": "def-server.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -13877,7 +13875,7 @@ "section": "def-common.DataViewAttributes", "text": "DataViewAttributes" }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; }) => Promise<", + ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -13952,6 +13950,20 @@ "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-server.SavedObjectsClientCommon.create.$2.overwrite", + "type": "CompoundType", + "tags": [], + "label": "overwrite", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false } ] } @@ -15784,10 +15796,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts" @@ -20304,7 +20312,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -20346,10 +20354,8 @@ "id": "def-common.DataViewsService.createAndSave.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists." - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -20413,7 +20419,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -20455,10 +20461,8 @@ "id": "def-common.DataViewsService.createSavedObject.$2", "type": "boolean", "tags": [], - "label": "override", - "description": [ - "Overwrite if existing index pattern exists" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean" ], @@ -22201,7 +22205,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean | undefined, displayErrors?: boolean | undefined) => Promise<", + ", overwrite?: boolean | undefined, displayErrors?: boolean | undefined) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -22241,10 +22245,8 @@ "id": "def-common.DataViewsServicePublicMethods.createSavedObject.$2", "type": "CompoundType", "tags": [], - "label": "override", - "description": [ - "- If true, save over existing data view" - ], + "label": "overwrite", + "description": [], "signature": [ "boolean | undefined" ], @@ -25117,7 +25119,7 @@ "section": "def-common.DataViewAttributes", "text": "DataViewAttributes" }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; }) => Promise<", + ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -25192,6 +25194,20 @@ "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.SavedObjectsClientCommon.create.$2.overwrite", + "type": "CompoundType", + "tags": [], + "label": "overwrite", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false } ] } @@ -25877,7 +25893,7 @@ "section": "def-common.DataViewSpec", "text": "DataViewSpec" }, - ", override?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, skipFetchFields?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", @@ -25893,7 +25909,7 @@ "section": "def-common.DataView", "text": "DataView" }, - ", override?: boolean, displayErrors?: boolean) => Promise<", + ", overwrite?: boolean, displayErrors?: boolean) => Promise<", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index c1758ac2dd805..eaa8b1d45813e 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1048 | 0 | 258 | 2 | +| 1051 | 0 | 268 | 2 | ## Client diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index e5645a3a53631..80d4eef21696b 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-07-04 +date: 2023-07-05 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 06e28d8a7044c..1308d5a4c7eca 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 1b374e702fef3..9b3c748b49241 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -1141,12 +1141,12 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion)+ 12 more | - | | | [dependencies_start_mock.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts#:~:text=indexPatterns) | - | | | [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion), [host_risk_score_dashboards.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts#:~:text=migrationVersion)+ 78 more | - | -| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [alerts_sub_grouping.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title)+ 24 more | - | +| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title), [index_pattern.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/index_pattern.ts#:~:text=title)+ 22 more | - | | | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.ts#:~:text=create) | - | | | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch) | - | | | [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/hooks/eql/api.ts#:~:text=options) | - | -| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [alerts_sub_grouping.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title)+ 24 more | - | -| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [alerts_sub_grouping.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_sub_grouping.tsx#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title)+ 7 more | - | +| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title), [index_pattern.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/index_pattern.ts#:~:text=title)+ 22 more | - | +| | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=title), [use_rule_from_timeline.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx#:~:text=title), [get_es_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts#:~:text=title), [utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts#:~:text=title), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/filter_group/index.tsx#:~:text=title), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx#:~:text=title), [get_query_filter.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/get_query_filter.ts#:~:text=title), [index_pattern.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/mock/index_pattern.ts#:~:text=title)+ 6 more | - | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | | | [query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/query.ts#:~:text=license%24) | 8.8.0 | @@ -1219,7 +1219,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [message_utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/tls_rule/message_utils.ts#:~:text=alertFactory), [common.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/common.ts#:~:text=alertFactory), [tls_rule.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule.ts#:~:text=alertFactory), [monitor_status_rule.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts#:~:text=alertFactory) | - | | | [stderr_logs.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/stderr_logs.tsx#:~:text=indexPatternId) | - | | | [synthetics_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks), [synthetics_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks), [synthetics_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks) | - | -| | [actions.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts#:~:text=SavedObject), [actions.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts#:~:text=SavedObject), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts#:~:text=SavedObject), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [effects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/effects.ts#:~:text=SavedObject)+ 1 more | - | +| | [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts#:~:text=SavedObject), [effects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/effects.ts#:~:text=SavedObject), [effects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/effects.ts#:~:text=SavedObject) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 4bcdd17947c73..dcd422b44a67f 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 52b9af51f2c7b..1290792db63e6 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-07-04 +date: 2023-07-05 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 418852fb9f653..894901004224e 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-07-04 +date: 2023-07-05 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 e2972d0dfd69a..545838989fcef 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index c7bac8be8e9b6..456815253add3 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index ff9c75066c3b2..3c60597cb2aa2 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-07-04 +date: 2023-07-05 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 ddce516c012ff..3edd67dc167ff 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-07-04 +date: 2023-07-05 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 b30797a3f95f0..ab3b8aef1a4aa 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-07-04 +date: 2023-07-05 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 7572712578fac..99cf9558d581d 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-07-04 +date: 2023-07-05 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 1585b322a90b5..3ce1723b5ef7d 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/ess_security.mdx b/api_docs/ess_security.mdx index 6eb352855c17e..34a28e08b34e8 100644 --- a/api_docs/ess_security.mdx +++ b/api_docs/ess_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/essSecurity title: "essSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the essSecurity plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'essSecurity'] --- import essSecurityObj from './ess_security.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index ebcaea8eb22de..44608654af5f9 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-07-04 +date: 2023-07-05 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 44e2bd875b10f..e194316b7cea7 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index 7bc6143ad981f..3f0fc93227986 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index a7de02f274013..6f91122bf3972 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-07-04 +date: 2023-07-05 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 cc271283bf098..8f1352f3dd437 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-07-04 +date: 2023-07-05 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 9f75050ead27a..1b2d4b7cd7932 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-07-04 +date: 2023-07-05 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 6028515124c6f..7a430e93b5ca0 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-07-04 +date: 2023-07-05 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 15a537e2d51f6..06598f58ad8c5 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-07-04 +date: 2023-07-05 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 270077e1f90a4..4b1bb925243c7 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-07-04 +date: 2023-07-05 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 c9c25bfb55849..9cf2c80067ba2 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-07-04 +date: 2023-07-05 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 8fc7a7e9ed4fa..bb2f0bec92f7f 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-07-04 +date: 2023-07-05 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 2d1a7bc8c5c67..2a403a81ce883 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-07-04 +date: 2023-07-05 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 3b8c50f4f716c..78fc76e45c6d6 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-07-04 +date: 2023-07-05 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 7c787d2e5ffdb..5780d1614c206 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-07-04 +date: 2023-07-05 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 1ebeebd4806c9..bf4a68d0decfb 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-07-04 +date: 2023-07-05 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 9c29344ace5f4..8f8e4b5650720 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-07-04 +date: 2023-07-05 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 70bb1c475558b..2e145b784ee3a 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 324fcd2d3e1d8..a412b86858f8d 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index e629b0856dfdc..064abd699fcc1 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-07-04 +date: 2023-07-05 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 e4a966fdb1ab7..49cd766fb154c 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-07-04 +date: 2023-07-05 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 b098d80253670..a12f1527b7bd6 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-07-04 +date: 2023-07-05 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 b5ed85ea0dcec..caa3f6999359d 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-07-04 +date: 2023-07-05 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 809ab35271d07..8208e3d11b0a1 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-07-04 +date: 2023-07-05 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 fe8c108d89c19..453c2c521f93b 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-07-04 +date: 2023-07-05 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 f54b3f1c9193f..8ced8b4d94d65 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-07-04 +date: 2023-07-05 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 ae22c32d050c6..a26b1a8bfb7a3 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-07-04 +date: 2023-07-05 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 3fa952261dfce..7cfa3c26ffc0f 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-07-04 +date: 2023-07-05 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 a34f0e49250b8..f18e468e26e83 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-07-04 +date: 2023-07-05 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 b312a6e580545..9405afd666b00 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-07-04 +date: 2023-07-05 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 a5fa5320a15ad..eb30834e29d5e 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-07-04 +date: 2023-07-05 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 3016167dbadc9..19168524c29ba 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-07-04 +date: 2023-07-05 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 92db3f9f5a869..67e1b7f02158f 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-07-04 +date: 2023-07-05 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 4447e5cac6cdf..45cf012204d6e 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-07-04 +date: 2023-07-05 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 c7881e6db0d4d..c17512a5f0b68 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-07-04 +date: 2023-07-05 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 892fe8b449a2b..00832a2176ad9 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 0383b8294e741..81f5d6b6ecabe 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 09c8ce2b54e61..af7edc0d8a497 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index b1cc6337c8b88..55907ec366571 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 05db7cccba3ee..7291da859af3a 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-07-04 +date: 2023-07-05 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 eaa250a5ecc47..d4b446a4feb9f 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-07-04 +date: 2023-07-05 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 29edbaff662f9..cd833eb9c0c7d 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-07-04 +date: 2023-07-05 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 a8b8deafa8651..a80d36504c5f8 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-07-04 +date: 2023-07-05 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 1020205dc4822..0a11917654e18 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-07-04 +date: 2023-07-05 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 05c90d17d081d..989a7c56c4e02 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-07-04 +date: 2023-07-05 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 86a3dde84ae35..653fb639d5118 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-07-04 +date: 2023-07-05 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 f7dc2dc3b5cd9..71f6d6887ca2f 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-07-04 +date: 2023-07-05 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 ffd76f5befb0a..90eeda70308da 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-07-04 +date: 2023-07-05 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 4ff52a33cd106..a061cd8d5b950 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-07-04 +date: 2023-07-05 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 e0e3d648396ed..7169cbfa902dc 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-07-04 +date: 2023-07-05 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 08eb9822b3992..0d4bd7daabd64 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 6af0298297db2..6aec3f4c21c56 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index ee145317c7a15..39aa5e354040a 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 0e1ff6a18c03d..845c13ed3d5ff 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 09d08081ede2d..922efdf36bebf 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-07-04 +date: 2023-07-05 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 5a8b540b7afd0..ccb99fbe2c75a 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-07-04 +date: 2023-07-05 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 c0d60d4e438b3..6080c4b114768 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-07-04 +date: 2023-07-05 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 f5fec23312d66..c410b8266abdb 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-07-04 +date: 2023-07-05 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 be02de2cfa2b6..c6ad6c25c5899 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index e2c1441169e54..94e1ccec124a0 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index 7f96b467760a9..1215355cd87c7 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index e8a553cc9d3e8..3984da8b0fc33 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-07-04 +date: 2023-07-05 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 dfb0fc4bea1af..8a2db1c927fb4 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-07-04 +date: 2023-07-05 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 5840134a950a8..462dfab3c9a2c 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-07-04 +date: 2023-07-05 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 04a87e07837bf..cdf1e277d3d40 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-07-04 +date: 2023-07-05 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 1b1f33770ba25..70f1c79666d8f 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-07-04 +date: 2023-07-05 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_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index f1cf58b40fe78..936c643770e70 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 6637ae18de157..49f1f8754acaa 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 86878d5639e57..4f96ce3f3326d 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 830c118143e97..890c6416b9405 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 008651ac78525..6ceaee7d6b2ef 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-07-04 +date: 2023-07-05 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 e96413c1a76ee..51c64ffe9dd2d 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-07-04 +date: 2023-07-05 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 38c692ab09281..5bf8c63c71e01 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-07-04 +date: 2023-07-05 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 c38f0f22c5c57..651a6e4da1abb 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-07-04 +date: 2023-07-05 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 4646a442f6da2..5407846be8d2e 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-07-04 +date: 2023-07-05 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 09a807b53a682..48a3087decd9f 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-07-04 +date: 2023-07-05 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 edc0fe763f88f..eb2314d674462 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-07-04 +date: 2023-07-05 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 2cc6de17e6ab8..1c35027756a2f 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-07-04 +date: 2023-07-05 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 538e6d007d361..b73ae9f06c746 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-07-04 +date: 2023-07-05 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 6043c0fc6355c..2a67df9211aa2 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-07-04 +date: 2023-07-05 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 019640cbbcc4e..d2a25f38fb4d2 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-07-04 +date: 2023-07-05 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 cc2727a24e0ab..2acbf08a4c62e 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-07-04 +date: 2023-07-05 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 8a63df9777762..12041897dce02 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-07-04 +date: 2023-07-05 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 e0903c7183424..488c71d92b97d 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-07-04 +date: 2023-07-05 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 d002fd41f7ec5..064cec1a5eed8 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-07-04 +date: 2023-07-05 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 3de35a97b476a..c583484c2cdf6 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-07-04 +date: 2023-07-05 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 619ca6aeb9bc8..6f76e1d155eb8 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-07-04 +date: 2023-07-05 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 b97664c086f8f..c1f11e04df7a6 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-07-04 +date: 2023-07-05 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 bb705fe5edb52..4191ddb733757 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-07-04 +date: 2023-07-05 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 295e6df862d87..66f3a1bb801d3 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-07-04 +date: 2023-07-05 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 e93d15505034b..2d5e5ff1e96a4 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-07-04 +date: 2023-07-05 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 cb9f0af5035f8..b3c10ca9a18b5 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-07-04 +date: 2023-07-05 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 0009d47b8a4a5..644b075c9c3b3 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-07-04 +date: 2023-07-05 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 59d0fa8660c8c..d69c3b7926792 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-07-04 +date: 2023-07-05 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 4fb5fd22aad52..24372e4bbdbcd 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-07-04 +date: 2023-07-05 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 c45e9944816bb..2cb8f66c49c4c 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-07-04 +date: 2023-07-05 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 7b6f25d3a912a..95e58fc0c9777 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-07-04 +date: 2023-07-05 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 e972c6cf04c96..d3dbd54ad9279 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-07-04 +date: 2023-07-05 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 110cd4e3f07f6..9b1e7a8745949 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-07-04 +date: 2023-07-05 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 6a268409b8b8e..77edb606cd11a 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-07-04 +date: 2023-07-05 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 fff01280c1b7e..0e196b2bd08ae 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-07-04 +date: 2023-07-05 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 1d2525ad461f4..8d8feab21d924 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-07-04 +date: 2023-07-05 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 2c6f2cb0c9f05..2c6385fe8c91e 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-07-04 +date: 2023-07-05 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 2244941546c14..1bd4110d334f0 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-07-04 +date: 2023-07-05 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 a62a6b4eab1c2..2c427d5efea09 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-07-04 +date: 2023-07-05 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 e8a9f111eefc1..a1284fa96f99b 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-07-04 +date: 2023-07-05 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 ef32238172fc3..be8722ffae792 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-07-04 +date: 2023-07-05 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 ce299f14629b8..f10a0ed1c2066 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-07-04 +date: 2023-07-05 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 1b51cdc26d7cc..64c3a41cadc0f 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-07-04 +date: 2023-07-05 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 f14ea8fedf2e3..bf5b7f4a564db 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-07-04 +date: 2023-07-05 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 c68c1db4cd4d6..4221cacdfd20c 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-07-04 +date: 2023-07-05 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 ab05459266b27..1c815d6ecedc1 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-07-04 +date: 2023-07-05 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 acdad0a739f8f..bb9f2e2927c07 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-07-04 +date: 2023-07-05 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 9cc3421ef11d9..ec38221f328ea 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-07-04 +date: 2023-07-05 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 24e834d41a22c..11d66e6acf880 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-07-04 +date: 2023-07-05 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 a64e41ba3731e..7f8038073112b 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-07-04 +date: 2023-07-05 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 35f51d36937d6..3d3459d0d270f 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-07-04 +date: 2023-07-05 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 06577c4bfedef..de0ccf46b3def 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-07-04 +date: 2023-07-05 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 5b05d23cf4e75..f11befc3b2955 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-07-04 +date: 2023-07-05 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 611747b140e5a..510a3c7ac009f 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-07-04 +date: 2023-07-05 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 54ca347bac7b2..e8532585f92b9 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-07-04 +date: 2023-07-05 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 61bd3b7cf44ca..26435a1ad1913 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-07-04 +date: 2023-07-05 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 680e61cedd9f9..d89a5b6b08229 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-07-04 +date: 2023-07-05 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 744c2f429b0bc..a5e9e261771f9 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-07-04 +date: 2023-07-05 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 7f7f44f139808..c05397383fd58 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-07-04 +date: 2023-07-05 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 c62e6d381bcf7..a55127e548af9 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-07-04 +date: 2023-07-05 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 54d4aae2e008e..c43348023f87c 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-07-04 +date: 2023-07-05 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 b37260cd83244..44dd7858a0f8c 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-07-04 +date: 2023-07-05 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 2865f4b8275ad..36b96d513bc87 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-07-04 +date: 2023-07-05 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 00847cf8ece37..925fbf6464446 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-07-04 +date: 2023-07-05 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 ea3dc9f8213d1..f615bcb7abdaa 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-07-04 +date: 2023-07-05 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 886e0eb03817b..7da6ed3f8cbb9 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-07-04 +date: 2023-07-05 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 7c3941e3a4b95..ba262b7bb2b84 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-07-04 +date: 2023-07-05 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 72c13da6384d7..10f606bdfd339 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-07-04 +date: 2023-07-05 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 d05e402eba6db..22d4e70d3173e 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-07-04 +date: 2023-07-05 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 59b93a42e3f51..19ca707814d45 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-07-04 +date: 2023-07-05 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 185c261cb8f1a..4c9af7f15ace0 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-07-04 +date: 2023-07-05 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 70cdc4c6b44af..2ba02ad258c15 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-07-04 +date: 2023-07-05 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 be0d486c3c14c..ffa0dbee6531d 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-07-04 +date: 2023-07-05 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 b2eeca5f96d65..0a7c4cebfbf5b 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-07-04 +date: 2023-07-05 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 697be80a43bd1..990cd120d005d 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-07-04 +date: 2023-07-05 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.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 91dab3c567922..0a32bbd81f22e 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-07-04 +date: 2023-07-05 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 5e29c1c8d5d5c..5d486e605e5d9 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-07-04 +date: 2023-07-05 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 96f5bbfc54ed8..53c2079403431 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-07-04 +date: 2023-07-05 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 6e11aee7bff50..fd637cf169891 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-07-04 +date: 2023-07-05 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 8bfa1abdea3cf..663505c4f9d59 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-07-04 +date: 2023-07-05 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 c3531b95057c4..7e54e17279400 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-07-04 +date: 2023-07-05 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 71b2a0188555a..b61ff43c5b540 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-07-04 +date: 2023-07-05 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 1cda5852cfb3a..9dc6a88194b85 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-07-04 +date: 2023-07-05 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 c948050d4aae7..58fb313d243e2 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-07-04 +date: 2023-07-05 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 b7e43c6383f0e..e903f08994ded 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-07-04 +date: 2023-07-05 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 1487d3a5b95c7..fe7be83756d28 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-07-04 +date: 2023-07-05 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 e3bbfe6ae8041..3addbfc94941f 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-07-04 +date: 2023-07-05 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 764e031107a69..1e4aca3b887cf 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-07-04 +date: 2023-07-05 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 f3425b129afa0..eed6ea4e108d5 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-07-04 +date: 2023-07-05 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 9d145940a1d4c..63e02d42af553 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-07-04 +date: 2023-07-05 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 63cf0b9ae89e9..0eba98df374b5 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-07-04 +date: 2023-07-05 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 2d6c7ea659c6e..4da2a009012cc 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-07-04 +date: 2023-07-05 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 47f3b69935869..1b2a36ee8af4c 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-07-04 +date: 2023-07-05 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 f097b5f4ae190..12aa4833fa682 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-07-04 +date: 2023-07-05 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 92e83e107aa3c..f0ddb326d4b89 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-07-04 +date: 2023-07-05 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 d074354d8bfcc..5615047cd64a6 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-07-04 +date: 2023-07-05 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 436361e3a98ba..0b0bb11d0bfc5 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-07-04 +date: 2023-07-05 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 6afd1424146c4..0d0f7a04f1de5 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-07-04 +date: 2023-07-05 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 ce03c4ed395ea..5f038e86d92dc 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-07-04 +date: 2023-07-05 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 01213c660eb38..807bab424b2d7 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-07-04 +date: 2023-07-05 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 21153e4c20214..0049ea05bae51 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-07-04 +date: 2023-07-05 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 22032b4cf15e8..ef0ed68bd3577 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-07-04 +date: 2023-07-05 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 04543a86d0f18..29fff33334979 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-07-04 +date: 2023-07-05 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 1e02cdc66bcb0..35e8dc6b2ba2f 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-07-04 +date: 2023-07-05 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 cb6065df415aa..f8a3e9a121e1f 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-07-04 +date: 2023-07-05 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 57d8eab0e2460..3f3fe477b5a01 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-07-04 +date: 2023-07-05 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 cd77277ba2055..53dcf1ad9aac0 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-07-04 +date: 2023-07-05 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 e421f830fefc8..c6b969274388a 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-07-04 +date: 2023-07-05 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 00d6841616eaf..516617eea9696 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-07-04 +date: 2023-07-05 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 b72c13a2524dc..12ee8f08e3411 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-07-04 +date: 2023-07-05 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 a2e52feb035fd..576d45988c503 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-07-04 +date: 2023-07-05 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 f20f940bcb4b3..cbae006cbe3f5 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-07-04 +date: 2023-07-05 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 bbce5ccf2f396..347a157cd85ba 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-07-04 +date: 2023-07-05 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 482591c15c5d5..2ed786d7e5d5d 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-07-04 +date: 2023-07-05 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 fce578a024807..a91692e09d9fd 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-07-04 +date: 2023-07-05 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 ca72a5e33e755..73bb0667dc436 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-07-04 +date: 2023-07-05 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 971e6c1d5ad5c..6e914a5a786eb 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-07-04 +date: 2023-07-05 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 e0424e272d223..93332ea1f401b 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-07-04 +date: 2023-07-05 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 3242bd32717d1..0d5927b0ee018 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-07-04 +date: 2023-07-05 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 a56edb7348e00..b83e74136bc2e 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-07-04 +date: 2023-07-05 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_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index b0f0185d613a5..928b33d7d50e4 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-07-04 +date: 2023-07-05 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 46e56a4600a34..d9fc5e6bbea9e 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-07-04 +date: 2023-07-05 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 c30924e5d4944..4902d8d31c73a 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-07-04 +date: 2023-07-05 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 ecee99ce6b8e6..bafd0df0fdce0 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-07-04 +date: 2023-07-05 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 e7a62377c5490..92665b7bcb74c 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-07-04 +date: 2023-07-05 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 17d7b701c8ae6..b01436ed5928a 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-07-04 +date: 2023-07-05 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.devdocs.json b/api_docs/kbn_core_saved_objects_common.devdocs.json index 7b4695420afa3..fbc383d88c59c 100644 --- a/api_docs/kbn_core_saved_objects_common.devdocs.json +++ b/api_docs/kbn_core_saved_objects_common.devdocs.json @@ -1489,34 +1489,6 @@ "plugin": "data", "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/actions.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/api.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts" - }, - { - "plugin": "synthetics", - "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/global_params/index.ts" - }, { "plugin": "synthetics", "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts" diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index c24e300c7ae76..893ac78382639 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-07-04 +date: 2023-07-05 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 0d038a4d8c4a2..ad40ac69d5eba 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-07-04 +date: 2023-07-05 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 4caf846a211cb..0be9a0e8206d2 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-07-04 +date: 2023-07-05 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 a3dae1157c7b6..8371af4f13cd8 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-07-04 +date: 2023-07-05 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 37a950cf4a1e6..663dc071f28f2 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-07-04 +date: 2023-07-05 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 d3b76b217c041..24e76ceb5f53a 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-07-04 +date: 2023-07-05 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 7041c9e794c0b..e945f00f884ae 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-07-04 +date: 2023-07-05 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 aafe67cbc77e3..168156da1ddb9 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-07-04 +date: 2023-07-05 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 c961a02353ad9..1c5232d33b214 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-07-04 +date: 2023-07-05 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 3e982bcdcdfbc..98b0249f8e054 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-07-04 +date: 2023-07-05 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 3f9b8ea6277ca..2dbdc902c77e2 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-07-04 +date: 2023-07-05 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 4ef72b8729839..0650139c640af 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-07-04 +date: 2023-07-05 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 b31a27d321c66..a1dccd271d397 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-07-04 +date: 2023-07-05 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 8846edb7c118f..b0abaa8abedf4 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-07-04 +date: 2023-07-05 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 85d8cad3d4b1e..1940f37349838 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-07-04 +date: 2023-07-05 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 7bd36413cff19..bd42702bb7617 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-07-04 +date: 2023-07-05 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 5a10893b25f65..475de1f36a366 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-07-04 +date: 2023-07-05 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 e1172bfcf5736..4f91385037bca 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-07-04 +date: 2023-07-05 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 932f78c36e2f5..96534af7d163a 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-07-04 +date: 2023-07-05 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 9ce1c80941fc0..2f2122a4c41cc 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-07-04 +date: 2023-07-05 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 8fbb1d68a59d9..f3596e6c9b442 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-07-04 +date: 2023-07-05 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 d6270e822e583..7a72019e2a24c 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-07-04 +date: 2023-07-05 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 c6c9e9db5e2e8..9323f3c818db8 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-07-04 +date: 2023-07-05 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 5e61152ee78c7..8b3058b3c42b4 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-07-04 +date: 2023-07-05 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 ed527423205b0..d39b2db40ed50 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-07-04 +date: 2023-07-05 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 4f3505d61acb4..938efa0a423a7 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-07-04 +date: 2023-07-05 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 4901fa31e1eef..416334f6351b9 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-07-04 +date: 2023-07-05 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 0261a6753fd87..2283b43fc865b 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-07-04 +date: 2023-07-05 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 59aad9446a785..f6852008c9996 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-07-04 +date: 2023-07-05 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 c9eff7e078326..b6967380d8820 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-07-04 +date: 2023-07-05 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 290460ff39772..bd939750029ce 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-07-04 +date: 2023-07-05 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 ef72203c9a249..f9412de052cf4 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-07-04 +date: 2023-07-05 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_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index eab0737161af4..a3cd79cb0f2a2 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 5bd975ff079a0..193e7472a6022 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index a9c9b44293c5b..657bd8444eef1 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index df2549a2dbd25..8116a3f0da0ff 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-07-04 +date: 2023-07-05 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 ca331bc0f110f..50c1bc8a38b2e 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-07-04 +date: 2023-07-05 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 cd7a2d468959a..b4e7d659b4b7f 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index e0432f0678d1d..ccf31fc5b622f 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 367754dce9395..631882a8f5a2b 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index 3080e419eacc5..6431eb586768a 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index 68575f9ab1232..a0f5ab936f828 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 074598f2cea12..cf43a8b6cdd8c 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index 0c09bc615d507..0517bf418e899 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index fc254f18c3121..3e428f46cae50 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index b74ffd6153fd1..edb11e1ef6bbd 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index b8dd1b16c1afe..81d527ce01372 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index ae70bde03b62e..d1c9856de5f31 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index e24b1368c737c..a65dba1592e6a 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index 8a8b442215eb1..c4f24d090c74d 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 2f3ae44f970cc..1510d767c6bf8 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-07-04 +date: 2023-07-05 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 6636b5c1150fb..d28350f75cb2f 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-07-04 +date: 2023-07-05 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 36f13e19990f5..1bf6c89dfe937 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-07-04 +date: 2023-07-05 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 d27aaf7f12377..c95a7feb12ecc 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 85fbfcea2892d..33436d8bacdca 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -658,7 +658,7 @@ "label": "observability", "description": [], "signature": [ - "{ readonly guide: string; readonly infrastructureThreshold: string; readonly logsThreshold: string; readonly metricsThreshold: string; readonly threshold: string; readonly monitorStatus: string; readonly monitorUptime: string; readonly tlsCertificate: string; readonly uptimeDurationAnomaly: string; readonly monitorLogs: string; readonly analyzeMetrics: string; readonly monitorUptimeSynthetics: string; readonly userExperience: string; readonly createAlerts: string; readonly syntheticsCommandReference: string; readonly syntheticsProjectMonitors: string; readonly syntheticsMigrateFromIntegration: string; }" + "{ readonly guide: string; readonly infrastructureThreshold: string; readonly logsThreshold: string; readonly metricsThreshold: string; readonly threshold: string; readonly monitorStatus: string; readonly monitorUptime: string; readonly tlsCertificate: string; readonly uptimeDurationAnomaly: string; readonly monitorLogs: string; readonly analyzeMetrics: string; readonly monitorUptimeSynthetics: string; readonly userExperience: string; readonly createAlerts: string; readonly syntheticsCommandReference: string; readonly syntheticsProjectMonitors: string; readonly syntheticsMigrateFromIntegration: string; readonly sloBurnRateRule: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index f8bb2a0756f61..ae81cabcc0fd8 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-07-04 +date: 2023-07-05 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 9ee7f091de121..d72e51b1ab038 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index 525fe1ea49948..2a2740d570c36 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index a1badcff4047a..1c35244834411 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-07-04 +date: 2023-07-05 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 9a21b35956941..0f8efd19b9a29 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 1380a5ce23606..12b55452a3798 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index fe13918be2778..d7aa33323d970 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 4c00487d2c921..f817ec0859dc1 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-07-04 +date: 2023-07-05 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 e130b85df50f8..d5c755b334ed8 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-07-04 +date: 2023-07-05 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 37ed6764d9d11..5718752bd3dd4 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-07-04 +date: 2023-07-05 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 8cc7f32862d75..d59bb5ddd951d 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-07-04 +date: 2023-07-05 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 9993297aecd47..2081f038f43e4 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-07-04 +date: 2023-07-05 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 c6221cdd52fd8..fccc76a9972c2 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 13039abc93aee..5e87a772ddaa4 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index a780a047abf91..c76e5be48d94d 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-07-04 +date: 2023-07-05 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 a3ec886292f86..cc927d2563282 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-07-04 +date: 2023-07-05 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 4cd3a8ffd8321..64285e4ea52d3 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-07-04 +date: 2023-07-05 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 460933a2bda73..2a4252112f6a7 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index 1f0558a568281..d450935d31331 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 93c368ed8344d..bf78b04382785 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 19055b5175f5b..0c18490fc9c0a 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 6962f103e5e3a..df7d4da812877 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-07-04 +date: 2023-07-05 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 ca311d4625ffc..76e2fcedb8f6b 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 980f8dae553bb..707eb01fdfdd9 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-07-04 +date: 2023-07-05 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 0995e7249e78a..41f99fbe22ff6 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-07-04 +date: 2023-07-05 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 c70a2b6524a90..12b114d11419d 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-07-04 +date: 2023-07-05 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 35ddd71105f38..40954ee038b46 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-07-04 +date: 2023-07-05 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 581a1ee645ad7..1e046a3e074ee 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-07-04 +date: 2023-07-05 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 1d7212b47abc2..a09a6acb7966a 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-07-04 +date: 2023-07-05 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 9992c13c43ead..3aa45aea29ce6 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 87b444509c485..69afe9c8be9d7 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 3c57cadc78fe7..3148ef143f500 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-07-04 +date: 2023-07-05 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 f85b14c96f908..2522ef4484934 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-07-04 +date: 2023-07-05 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 3a09e78df1cbf..fc145dbadb6c1 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-07-04 +date: 2023-07-05 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 689b4dcace196..875b50dca5058 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-07-04 +date: 2023-07-05 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 03cfccc40e4ef..2882e4a85d646 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-07-04 +date: 2023-07-05 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 5f8335522f806..7e3446d54e950 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-07-04 +date: 2023-07-05 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 24e0a861e8aea..f0b0dee2e59a1 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-07-04 +date: 2023-07-05 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 bd1a52c6f2b56..d8656d2c7b08e 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-07-04 +date: 2023-07-05 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 ab60eff2f410e..b874ca581b2ed 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-07-04 +date: 2023-07-05 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 f858ddf4a4fe8..6427e57a56090 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index e6575c26fe7dd..4801a3d431dd7 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 25143b05f015d..b36c548b3a256 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index b431413f651d2..1acfc03f758ed 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index c2964e6dd24df..97ce255d43aff 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 998583b2ee74c..4b86e5a5d91da 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-07-04 +date: 2023-07-05 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_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index 681d57a9343f9..81b7732d7d54d 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 5028d47a4a19a..67e7bebfd62ce 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index ee8cc92bd5d33..eb2bda204fb60 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index eeb84e42534a4..06cc579d58af8 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-07-04 +date: 2023-07-05 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_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index 4da916714865d..c79d46c85e15c 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index 855a5375ffb9d..83f67640a203f 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 72e71f0f70996..8a7723e9f4b52 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-07-04 +date: 2023-07-05 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 805fff1032625..32266a258893e 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-07-04 +date: 2023-07-05 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_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index 02574a65870d1..902e61e596883 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 10d1a665a71ac..d83547a5193d6 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-07-04 +date: 2023-07-05 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 55c743966dff9..c0bc51865d04d 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-07-04 +date: 2023-07-05 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_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index aded4faf4a8d2..9bae59a6eacf9 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 7174d6886a240..2b05f974f8297 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-07-04 +date: 2023-07-05 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_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index c1a1e0e7e8176..2f37f244dacfd 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index d278a62e86690..f4cffc6552377 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index d5d4f8d961ad4..deb6851a6694d 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index ae87a6216452b..53c42072a23a0 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-07-04 +date: 2023-07-05 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_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index a8ed779b2ecbc..667e781b31b2c 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 621b0bfebb6a9..81b827e7d47b9 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-07-04 +date: 2023-07-05 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 1e0d3e09b97a0..b677020dbfd90 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index c48dbe3542113..4c8b8c779ad23 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index dda91509afd31..724aeb08bced6 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 6722f507bb655..fe46d23c82bf0 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-07-04 +date: 2023-07-05 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 c1489e0cc7527..0ee301007ce39 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-07-04 +date: 2023-07-05 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 b2f7f21f2f32b..3de2f47c2a484 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-07-04 +date: 2023-07-05 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 9dfba7cb472a7..c0a39fff7e0d9 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-07-04 +date: 2023-07-05 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 d3f5e78d048a1..35dadb27af453 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-07-04 +date: 2023-07-05 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 5c0f830b0546c..f825c8a465ca3 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index fb47d883a1cce..b5fbc1b7c5f3f 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index acced4c06f26a..0b08ea7363967 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-07-04 +date: 2023-07-05 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 96e1bdc0aa3af..554d4dcb5af84 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-07-04 +date: 2023-07-05 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 46dad8550374e..955ef83ff1cdc 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-07-04 +date: 2023-07-05 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 ed5855fa5b5c7..2c9945dbba730 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-07-04 +date: 2023-07-05 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 87cc3d28fa85d..550a8eaf50a67 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index 3a09f1e40d2a3..43c1420846cef 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 124a5c2af1f1a..e259a39092f0c 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index d64728cc9b774..6d36cbbebda1e 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 62d73252b3566..156c11bb3eb1e 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index b64ddbbe16878..fea62bc327b5f 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 169d5449fb4f8..04021ce24ff92 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index 952785cc2c82b..00ca6215b5697 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index c486fcc009901..1ed0c4cc1bb23 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index 1f971f26a38b1..474af441e362e 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index eb8c16f7f0189..b0054b96656be 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index a876fa751d1e3..062ff3f7fd368 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-07-04 +date: 2023-07-05 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.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 499d71419f549..a43b54c7e8be6 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-07-04 +date: 2023-07-05 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_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index e3bb28518da10..765aca6e6ccb2 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index f0f7cdb095b8b..01b91c96f5fb8 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-07-04 +date: 2023-07-05 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 965e0e6582db4..c6930ecbabaca 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-07-04 +date: 2023-07-05 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.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index e420ba825040d..a49d0cf0ea181 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-07-04 +date: 2023-07-05 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 9b1257fc1aede..cc151193b5f4d 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-07-04 +date: 2023-07-05 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 1a37c07efd577..f262893b0d38e 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-07-04 +date: 2023-07-05 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.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 3bf2b2919ac10..9734f0e0acad9 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-07-04 +date: 2023-07-05 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 454b191ee9481..4e736d97d3972 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-07-04 +date: 2023-07-05 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.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index edcdff4b43526..5dbb710e0fc0c 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-07-04 +date: 2023-07-05 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.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 7cb9ee7927615..64601b6d4c4c9 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-07-04 +date: 2023-07-05 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 2af94107cbe1b..6393c27aa5b16 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-07-04 +date: 2023-07-05 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 ed5633cdb8ccc..8ae592064a6ff 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-07-04 +date: 2023-07-05 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 d69dccadae991..25d56bed1306c 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-07-04 +date: 2023-07-05 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 f8cca2f10e94b..642c8490fc15b 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-07-04 +date: 2023-07-05 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 8dcac28c3bccc..09988c969aed2 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index c2ca97af14a74..66f94916d8283 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 5f1c36c201878..9ff861f91a90d 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index c66885af1fee0..b30b411128fa2 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-07-04 +date: 2023-07-05 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 320ec0d432116..1c1210832eaa1 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-07-04 +date: 2023-07-05 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 5b7045a8d9f67..531bc47c943a8 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-07-04 +date: 2023-07-05 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 062ba46d30075..2c912c64b30cf 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-07-04 +date: 2023-07-05 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 a71ec43d86a10..3c07ddc4652cf 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-07-04 +date: 2023-07-05 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 f8a35e8e438bb..bd70bd98c3692 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-07-04 +date: 2023-07-05 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 aed464bdb5c76..706bac4f59acd 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-07-04 +date: 2023-07-05 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 2e90743efdc20..02102583a77b0 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-07-04 +date: 2023-07-05 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_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index fceef20809889..ac8e0150cad76 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 6d3a402bf7d5c..8e3c4ff5c8ec3 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-07-04 +date: 2023-07-05 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 d65184508e829..ea250c4c3a7fb 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-07-04 +date: 2023-07-05 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 6336eb2c93483..07b09f5f34f91 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-07-04 +date: 2023-07-05 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 de2e8566a93b2..1d51faf21ef34 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-07-04 +date: 2023-07-05 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 0711650d3ce91..b263a80e5f5d0 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-07-04 +date: 2023-07-05 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_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index cb38e442dde46..03137d11e0274 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 9e0a8eceb5047..3d18c0daf5461 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-07-04 +date: 2023-07-05 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 b97db00647318..6b4a7568839ba 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-07-04 +date: 2023-07-05 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 9b3c6030a21c7..b255f6230f787 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-07-04 +date: 2023-07-05 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 0de696514c58c..27f167249ea83 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-07-04 +date: 2023-07-05 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 8c9583a40f46c..bc4473a08f23f 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-07-04 +date: 2023-07-05 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 99b7dbc36a069..886cb45856c00 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-07-04 +date: 2023-07-05 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 cefe9776163d1..811fc7c95e689 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-07-04 +date: 2023-07-05 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 158776fd378f5..3b0e8c63569a6 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-07-04 +date: 2023-07-05 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 c736fbcbb0e4a..fd74062daae01 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-07-04 +date: 2023-07-05 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 0e76431df5ff9..91379e848e63e 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-07-04 +date: 2023-07-05 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 b7e573b04a18b..59ef177721ddf 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-07-04 +date: 2023-07-05 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 6e0970a5b0986..0835f6dab888c 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-07-04 +date: 2023-07-05 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 24c3e122857c8..63b6cc21a36f8 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-07-04 +date: 2023-07-05 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 f024d4dc85e0b..c7255c2077499 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-07-04 +date: 2023-07-05 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 6724eb0caa46b..e218153d7da31 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-07-04 +date: 2023-07-05 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 8bd4211647a70..1a536d3315703 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-07-04 +date: 2023-07-05 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 eb04cd0d0e7f9..3e70d4567cc79 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-07-04 +date: 2023-07-05 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 fbb6a42471c95..8a598bc22cf94 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-07-04 +date: 2023-07-05 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 6694f28ec422b..75b73b8a877b3 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-07-04 +date: 2023-07-05 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 758b858389536..8c72280b0a6d1 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-07-04 +date: 2023-07-05 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 1a564ec4b5f56..987c7d0586ca7 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-07-04 +date: 2023-07-05 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 792465bfb7734..c8b99990edbe9 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-07-04 +date: 2023-07-05 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 658b9eaec33b3..e4fbe5a4291ad 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-07-04 +date: 2023-07-05 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 aa88d77fe7388..ed436ac1cd0f0 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-07-04 +date: 2023-07-05 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 5d0d84ee98663..e106b8562a601 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-07-04 +date: 2023-07-05 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 8f9700fc1cc01..ae23535f6b45f 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-07-04 +date: 2023-07-05 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 44039e8d97ff6..67ff55eefa97d 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-07-04 +date: 2023-07-05 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 84ffa7a7b6cc7..048c6f24c03b6 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-07-04 +date: 2023-07-05 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 49574d65569d3..434f426e02a46 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-07-04 +date: 2023-07-05 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 867a30b1fde6d..024c14d8b5033 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-07-04 +date: 2023-07-05 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 847ce7296955c..6db2677eba7ae 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-07-04 +date: 2023-07-05 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 de2b67b4228fe..eb3509a798cda 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-07-04 +date: 2023-07-05 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 e4ab96c56f975..1009301eb174f 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-07-04 +date: 2023-07-05 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 7e1e26e6cdfff..39bf68611d8d2 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 246752490577a..8923c6e8831e6 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 8d47a3e0cf55a..22cb1362d684a 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-07-04 +date: 2023-07-05 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 4794a40ac7e2c..e4af602a22d07 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-07-04 +date: 2023-07-05 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 cc6b8a9680907..12fc03dc73aaa 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-07-04 +date: 2023-07-05 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_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index dc397f344d19e..21132d0b49eff 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 26094e3a601e9..4b91f5241febd 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-07-04 +date: 2023-07-05 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 34523e2dff591..4f49eeac558e5 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index cd932d9d6849e..60361fd6e2243 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 29541b076aea1..3828f42063e9d 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index f09da062ff82e..6439073eac901 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-07-04 +date: 2023-07-05 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 bf4ca46684de0..ad7fcc1d9a86e 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-07-04 +date: 2023-07-05 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 d23d2f88684eb..1d3ad06f90eec 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-07-04 +date: 2023-07-05 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 e6b5c16156af8..8d09226d8cde8 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-07-04 +date: 2023-07-05 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 c465ac339244b..085cecb17cd01 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-07-04 +date: 2023-07-05 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 4164af8d68a6b..6940bb92bfde0 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-07-04 +date: 2023-07-05 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 a470737c64185..88e2b49ec80e6 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-07-04 +date: 2023-07-05 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 f140aac1e0ac7..fc785b8740ab7 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-07-04 +date: 2023-07-05 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 b429f30661484..86f3e74f10c56 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-07-04 +date: 2023-07-05 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 374bac01d12b7..67b3a0c09834d 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-07-04 +date: 2023-07-05 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 6083771d6cefe..418c7d6471634 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-07-04 +date: 2023-07-05 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 23419ef04718a..f78f30f5ea87a 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-07-04 +date: 2023-07-05 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 9cae783d8749c..57ed54ac6f483 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 38ce8789989f1..05c5960070511 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.devdocs.json b/api_docs/management.devdocs.json index 6e970de9f2c57..61f282b25ee2c 100644 --- a/api_docs/management.devdocs.json +++ b/api_docs/management.devdocs.json @@ -805,6 +805,38 @@ ], "returnComment": [] }, + { + "parentPluginId": "management", + "id": "def-public.ManagementStart.setLandingPageRedirect", + "type": "Function", + "tags": [], + "label": "setLandingPageRedirect", + "description": [], + "signature": [ + "(landingPageRedirect: string) => void" + ], + "path": "src/plugins/management/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "management", + "id": "def-public.ManagementStart.setLandingPageRedirect.$1", + "type": "string", + "tags": [], + "label": "landingPageRedirect", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/management/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "management", "id": "def-public.ManagementStart.setupCardsNavigation", diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 68bfbf4918408..b7d9c0485d960 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/platform-deployment-management](https://github.com/orgs/elasti | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 45 | 0 | 45 | 7 | +| 47 | 0 | 47 | 7 | ## Client diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 6a1ed8133255c..dbc775b5f1dbc 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-07-04 +date: 2023-07-05 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 299ade9e71af2..b5d807b56d5a4 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-07-04 +date: 2023-07-05 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 16e46d18ead56..f58609b971172 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-07-04 +date: 2023-07-05 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 4133dfde906ef..41e3baa9bd414 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-07-04 +date: 2023-07-05 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 97288b7b95e6d..bd1a9da908500 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-07-04 +date: 2023-07-05 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 530ffc11c7b28..10e65aecf96a6 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-07-04 +date: 2023-07-05 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 31f20cff3b9e4..a6c451b483497 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-07-04 +date: 2023-07-05 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 53f267fa0477e..88f460f7ef274 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-07-04 +date: 2023-07-05 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 62e58fc3dc2cd..71425278a3406 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index e7f3a62632dfa..2ccee1c31e89c 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index ae30125da3bbd..0c300be82aaf0 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 4bdeb7094a5e8..49af78d45b357 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-07-04 +date: 2023-07-05 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 aeab64a07c161..a847b1da1639f 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 70982 | 544 | 60792 | 1409 | +| 70987 | 544 | 60808 | 1409 | ## Plugin Directory @@ -56,11 +56,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 271 | 0 | 252 | 1 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 100 | 0 | 98 | 9 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 54 | 0 | 51 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3303 | 119 | 2579 | 27 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3303 | 119 | 2583 | 27 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 16 | 0 | 7 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Reusable data view field editor across Kibana | 72 | 0 | 33 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data view management app | 2 | 0 | 2 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1048 | 0 | 258 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1051 | 0 | 268 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 10 | 0 | 8 | 2 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 97 | 0 | 71 | 14 | @@ -123,7 +123,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 210 | 0 | 94 | 51 | | logstash | [@elastic/logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 45 | 0 | 45 | 7 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 47 | 0 | 47 | 7 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 266 | 0 | 265 | 28 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 150 | 3 | 64 | 32 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 45a4cedff2e77..c03517c32181d 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-07-04 +date: 2023-07-05 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 44ddb29e58bb1..d38e239182911 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-07-04 +date: 2023-07-05 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 8151486dacb73..0dbe8450665c2 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-07-04 +date: 2023-07-05 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 462db023b77c8..66305771e23fc 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index 8c2c6bb90afea..6ec11afb27a39 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index ec70b4249c6d3..6df0719478949 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-07-04 +date: 2023-07-05 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 ec82ecc994b0a..01fee08efd10a 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-07-04 +date: 2023-07-05 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 6de928bdb2037..ff1c503e48f9c 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-07-04 +date: 2023-07-05 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 7c1875319e739..6bf8190ccf2a3 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-07-04 +date: 2023-07-05 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 075b7695f7562..773ef8d73391c 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-07-04 +date: 2023-07-05 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 b67fe7179270e..0cbb23923e783 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-07-04 +date: 2023-07-05 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 7a4501f01b6ba..90d1b3092d057 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-07-04 +date: 2023-07-05 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 f3f2361a11ece..922893523ded1 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-07-04 +date: 2023-07-05 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 a62e45f86b888..7dd50c518a8ba 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-07-04 +date: 2023-07-05 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 494e76c3cf65e..7507e2a9f95dd 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-07-04 +date: 2023-07-05 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 1368ee6cbb76d..e74025234fa80 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-07-04 +date: 2023-07-05 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 c1d5c218edbf2..5057f57deedee 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-07-04 +date: 2023-07-05 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 7e53e37b906f8..f49c4e732e19a 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 41752046e3e9c..b378e96dd1769 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index a598a19132443..086f5ddd62ae3 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index a9e04358d9ee4..0e2906e0c48f7 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/serverless_security.mdx b/api_docs/serverless_security.mdx index 1d9f4d9577271..d3f04f77aa789 100644 --- a/api_docs/serverless_security.mdx +++ b/api_docs/serverless_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSecurity title: "serverlessSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSecurity plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSecurity'] --- import serverlessSecurityObj from './serverless_security.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index d8872d809c041..9996b614d4f55 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-07-04 +date: 2023-07-05 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 e5a6e44040e8f..6fee690d24ee7 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-07-04 +date: 2023-07-05 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 961944a41153d..b6414973bfac4 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-07-04 +date: 2023-07-05 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 4f3d26414eeab..69d2bb90c629a 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-07-04 +date: 2023-07-05 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 c19398e23ad5e..3c4331805d1bc 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-07-04 +date: 2023-07-05 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 51df18fc67a84..ee04c17c8a08c 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-07-04 +date: 2023-07-05 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 4768f6de5c0ef..5cb5c232a8c2e 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-07-04 +date: 2023-07-05 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 3f755385b93f6..46d841e2ff7f1 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-07-04 +date: 2023-07-05 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 462e3f9442070..bfd9aa4afee77 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-07-04 +date: 2023-07-05 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 091a41712240d..e4b7f79a9375e 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-07-04 +date: 2023-07-05 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 b2382d3b1b374..5c2e12eebba7a 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index fe1ce3fbd0576..5888c1b29a889 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index bdacfa3854af8..007d55d57e774 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 4ce06eb6edb6c..41fa43757d384 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-07-04 +date: 2023-07-05 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 50af3624ae3d8..d913ae767c551 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-07-04 +date: 2023-07-05 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 5ddab506cf1ed..04571ec89b674 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-07-04 +date: 2023-07-05 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 01839cd14fff6..1187fdb94ea9a 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-07-04 +date: 2023-07-05 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 15f1205fe4731..cd1ab232e8d84 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 97d02724e627d..0197cf908f0e4 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-07-04 +date: 2023-07-05 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 93fc2b40d9f5c..9a44bd9bc3470 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-07-04 +date: 2023-07-05 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 e9a3fe63e40f5..229cf50806970 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-07-04 +date: 2023-07-05 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 8d01c6f9a2659..c5232b0b57c25 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-07-04 +date: 2023-07-05 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 75e9132aae821..1a6e7e8e985ee 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-07-04 +date: 2023-07-05 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 ae8e52c16d898..3c3b9dd888195 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-07-04 +date: 2023-07-05 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 a9a0ab3cf7a19..bc101a54eee9c 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-07-04 +date: 2023-07-05 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 453adeccb22d7..9b98623cf9ef6 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-07-04 +date: 2023-07-05 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 788974c703c98..7be1137b65531 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-07-04 +date: 2023-07-05 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 156f48abffdbd..d624890761b2a 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-07-04 +date: 2023-07-05 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 ab0cfaedd26d5..82fee9fc02d9e 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-07-04 +date: 2023-07-05 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 27d898573845b..a70dbf66e069d 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-07-04 +date: 2023-07-05 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 bfc80aa1193e3..fcdf5f386295d 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-07-04 +date: 2023-07-05 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 d5c328ee070e7..bb7b848848e3f 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-07-04 +date: 2023-07-05 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 dca311a74be70..b8397b606fbad 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-07-04 +date: 2023-07-05 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 49b2ee08dabab..e62c03def083c 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-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index 66ffdc6dac8da..e513affacd64f 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 3b8f2591a11f0..6d60a643b0492 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-04 +date: 2023-07-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From d79e69a1ed944bc047eee56909891732efdffe38 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Wed, 5 Jul 2023 08:52:24 +0200 Subject: [PATCH 23/64] [Infrastructure UI] Add strict payload validation to inventory_views endpoint (#160852) closes [#157505](https://github.com/elastic/kibana/issues/157505) fixes [#157740](https://github.com/elastic/kibana/issues/157740) ## Summary This PR adds strict payload validation to `inventory_views` endpoint. I tried to make the types consistent between sever and frontend code and because of that more changes had to be made. I also refactored the `toolbar_control` component, decoupling them from Inventory View and Metrics Explorer View types ### How to test - Call the endpoint below trying to use invalid values. see [here](https://github.com/elastic/kibana/pull/160852/files#diff-058b21e249ebbe2795d450d07025d8904a58cfb07a97979e85975f87e931ffceR133-R143). ```bash [POST|PUT] kbn:/api/infra/inventory_views { "attributes": { "metric": { "type": [TYPE] }, "sort": { "by": "name" "direction": "desc" }, "groupBy": [], "nodeType": "host", "view": "map", "customOptions": [], "customMetrics": [], "boundsOverride": { "max": 1, "min": 0 }, "autoBounds": true, "accountId": "", "region": "", "autoReload": false, "filterQuery": { "expression": "", "kind": "kuery" }, "legend": { "palette": "cool", "steps": 10, "reverseColors": false }, "timelineOpen": false, "name": "test-uptime" } } ``` - Set up a local Kibana instance - Navigate to `Infrastructure` - In the UI, use the Saved View feature and try different field combinations --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../kbn-io-ts-utils/src/in_range_rt/index.ts | 14 ++- .../http_api/inventory_views/v1/common.ts | 31 +---- .../v1/create_inventory_view.ts | 20 ++-- .../inventory_views/v1/find_inventory_view.ts | 25 +--- .../inventory_views/v1/get_inventory_view.ts | 3 + .../v1/update_inventory_view.ts | 20 ++-- .../infra/common/inventory_views/types.ts | 107 ++++++++++++++++-- .../common/metrics_explorer_views/types.ts | 2 +- .../plugins/infra/common/saved_views/index.ts | 8 ++ .../plugins/infra/common/saved_views/types.ts | 70 ++++++++++++ .../saved_views/manage_views_flyout.tsx | 35 +++--- .../saved_views/toolbar_control.tsx | 43 ++++--- .../infra/public/hooks/use_inventory_views.ts | 73 ++++-------- .../hooks/use_metrics_explorer_views.ts | 73 ++++-------- x-pack/plugins/infra/public/lib/lib.ts | 14 +-- .../inventory_view/components/saved_views.tsx | 4 +- .../components/waffle/legend_controls.tsx | 8 +- .../components/waffle/palette_preview.tsx | 2 +- .../hooks/use_waffle_filters.ts | 29 ++--- .../hooks/use_waffle_options.ts | 68 +++-------- .../hooks/use_waffle_view_state.ts | 26 ++--- .../inventory_view/lib/create_legend.ts | 5 +- .../components/saved_views.tsx | 2 +- .../inventory_views/inventory_views_client.ts | 13 ++- .../public/services/inventory_views/types.ts | 13 ++- .../server/routes/inventory_views/README.md | 48 +++++++- .../saved_objects/inventory_view/types.ts | 70 +++++++++++- .../inventory_views/inventory_views_client.ts | 9 +- .../test/functional/apps/infra/home_page.ts | 2 - .../page_objects/infra_saved_views.ts | 5 +- 30 files changed, 497 insertions(+), 345 deletions(-) create mode 100644 x-pack/plugins/infra/common/saved_views/index.ts create mode 100644 x-pack/plugins/infra/common/saved_views/types.ts diff --git a/packages/kbn-io-ts-utils/src/in_range_rt/index.ts b/packages/kbn-io-ts-utils/src/in_range_rt/index.ts index b632173cb69d9..99d04b3f6abc6 100644 --- a/packages/kbn-io-ts-utils/src/in_range_rt/index.ts +++ b/packages/kbn-io-ts-utils/src/in_range_rt/index.ts @@ -16,11 +16,15 @@ export interface InRangeBrand { export type InRange = rt.Branded; export const inRangeRt = (start: number, end: number) => - rt.brand( - rt.number, // codec - (n): n is InRange => n >= start && n <= end, - // refinement of the number type - 'InRange' // name of this codec + new rt.Type( + 'InRange', + (input: unknown): input is number => + typeof input === 'number' && input >= start && input <= end, + (input: unknown, context: rt.Context) => + typeof input === 'number' && input >= start && input <= end + ? rt.success(input) + : rt.failure(input, context), + rt.identity ); export const inRangeFromStringRt = (start: number, end: number) => { diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts index 65e056f30e0d9..f1eb9b24ee039 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/common.ts @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; + import * as rt from 'io-ts'; import { either } from 'fp-ts/Either'; +import { inventoryViewRT } from '../../../inventory_views'; export const INVENTORY_VIEW_URL = '/api/infra/inventory_views'; export const INVENTORY_VIEW_URL_ENTITY = `${INVENTORY_VIEW_URL}/{inventoryViewId}`; @@ -33,30 +34,8 @@ export const inventoryViewRequestQueryRT = rt.partial({ sourceId: rt.string, }); -export type InventoryViewRequestQuery = rt.TypeOf; - -const inventoryViewAttributesResponseRT = rt.intersection([ - rt.strict({ - name: nonEmptyStringRt, - isDefault: rt.boolean, - isStatic: rt.boolean, - }), - rt.UnknownRecord, -]); - -const inventoryViewResponseRT = rt.exact( - rt.intersection([ - rt.type({ - id: rt.string, - attributes: inventoryViewAttributesResponseRT, - }), - rt.partial({ - updatedAt: rt.number, - version: rt.string, - }), - ]) -); - export const inventoryViewResponsePayloadRT = rt.type({ - data: inventoryViewResponseRT, + data: inventoryViewRT, }); + +export type InventoryViewRequestQuery = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts index 8bad088b00542..67a3bd7df1a70 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/create_inventory_view.ts @@ -5,16 +5,18 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { inventoryViewAttributesRT, inventoryViewRT } from '../../../inventory_views'; -export const createInventoryViewAttributesRequestPayloadRT = rt.intersection([ - rt.type({ - name: nonEmptyStringRt, - }), - rt.UnknownRecord, - rt.exact(rt.partial({ isDefault: rt.undefined, isStatic: rt.undefined })), -]); +export const createInventoryViewAttributesRequestPayloadRT = rt.exact( + rt.intersection([ + inventoryViewAttributesRT, + rt.partial({ + isDefault: rt.undefined, + isStatic: rt.undefined, + }), + ]) +); export type CreateInventoryViewAttributesRequestPayload = rt.TypeOf< typeof createInventoryViewAttributesRequestPayloadRT @@ -23,3 +25,5 @@ export type CreateInventoryViewAttributesRequestPayload = rt.TypeOf< export const createInventoryViewRequestPayloadRT = rt.type({ attributes: createInventoryViewAttributesRequestPayloadRT, }); + +export type CreateInventoryViewResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts index 17a9820a93a4d..3452a22a45d17 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/find_inventory_view.ts @@ -5,28 +5,11 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; - -export const findInventoryViewAttributesResponseRT = rt.strict({ - name: nonEmptyStringRt, - isDefault: rt.boolean, - isStatic: rt.boolean, -}); - -const findInventoryViewResponseRT = rt.exact( - rt.intersection([ - rt.type({ - id: rt.string, - attributes: findInventoryViewAttributesResponseRT, - }), - rt.partial({ - updatedAt: rt.number, - version: rt.string, - }), - ]) -); +import { singleInventoryViewRT } from '../../../inventory_views'; export const findInventoryViewResponsePayloadRT = rt.type({ - data: rt.array(findInventoryViewResponseRT), + data: rt.array(singleInventoryViewRT), }); + +export type FindInventoryViewResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts index 8e5cef06bb916..a13541c1e8a44 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/get_inventory_view.ts @@ -6,7 +6,10 @@ */ import * as rt from 'io-ts'; +import { inventoryViewRT } from '../../../inventory_views'; export const getInventoryViewRequestParamsRT = rt.type({ inventoryViewId: rt.string, }); + +export type GetInventoryViewResposePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts b/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts index b21bafbecec18..5698ab2a0b2c9 100644 --- a/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts +++ b/x-pack/plugins/infra/common/http_api/inventory_views/v1/update_inventory_view.ts @@ -5,16 +5,18 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { inventoryViewAttributesRT, inventoryViewRT } from '../../../inventory_views'; -export const updateInventoryViewAttributesRequestPayloadRT = rt.intersection([ - rt.type({ - name: nonEmptyStringRt, - }), - rt.UnknownRecord, - rt.exact(rt.partial({ isDefault: rt.undefined, isStatic: rt.undefined })), -]); +export const updateInventoryViewAttributesRequestPayloadRT = rt.exact( + rt.intersection([ + inventoryViewAttributesRT, + rt.partial({ + isDefault: rt.undefined, + isStatic: rt.undefined, + }), + ]) +); export type UpdateInventoryViewAttributesRequestPayload = rt.TypeOf< typeof updateInventoryViewAttributesRequestPayloadRT @@ -23,3 +25,5 @@ export type UpdateInventoryViewAttributesRequestPayload = rt.TypeOf< export const updateInventoryViewRequestPayloadRT = rt.type({ attributes: updateInventoryViewAttributesRequestPayloadRT, }); + +export type UpdateInventoryViewResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/inventory_views/types.ts b/x-pack/plugins/infra/common/inventory_views/types.ts index 49979c1063efa..a493d2332f212 100644 --- a/x-pack/plugins/infra/common/inventory_views/types.ts +++ b/x-pack/plugins/infra/common/inventory_views/types.ts @@ -5,19 +5,89 @@ * 2.0. */ -import { nonEmptyStringRt } from '@kbn/io-ts-utils'; +import { isoToEpochRt, nonEmptyStringRt, inRangeRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { + SnapshotCustomMetricInputRT, + SnapshotGroupByRT, + SnapshotMetricInputRT, +} from '../http_api/snapshot_api'; +import { ItemTypeRT } from '../inventory_models/types'; + +export const inventoryColorPaletteRT = rt.keyof({ + status: null, + temperature: null, + cool: null, + warm: null, + positive: null, + negative: null, +}); + +const inventoryLegendOptionsRT = rt.type({ + palette: inventoryColorPaletteRT, + steps: inRangeRt(2, 18), + reverseColors: rt.boolean, +}); + +export const inventorySortOptionRT = rt.type({ + by: rt.keyof({ name: null, value: null }), + direction: rt.keyof({ asc: null, desc: null }), +}); + +export const inventoryViewOptionsRT = rt.keyof({ table: null, map: null }); + +export const inventoryMapBoundsRT = rt.type({ + min: inRangeRt(0, 1), + max: inRangeRt(0, 1), +}); + +export const inventoryFiltersStateRT = rt.type({ + kind: rt.literal('kuery'), + expression: rt.string, +}); + +export const inventoryOptionsStateRT = rt.intersection([ + rt.type({ + accountId: rt.string, + autoBounds: rt.boolean, + boundsOverride: inventoryMapBoundsRT, + customMetrics: rt.array(SnapshotCustomMetricInputRT), + customOptions: rt.array( + rt.type({ + text: rt.string, + field: rt.string, + }) + ), + groupBy: SnapshotGroupByRT, + metric: SnapshotMetricInputRT, + nodeType: ItemTypeRT, + region: rt.string, + sort: inventorySortOptionRT, + view: inventoryViewOptionsRT, + }), + rt.partial({ legend: inventoryLegendOptionsRT, source: rt.string, timelineOpen: rt.boolean }), +]); + +export const inventoryViewBasicAttributesRT = rt.type({ + name: nonEmptyStringRt, +}); + +const inventoryViewFlagsRT = rt.partial({ isDefault: rt.boolean, isStatic: rt.boolean }); export const inventoryViewAttributesRT = rt.intersection([ - rt.strict({ - name: nonEmptyStringRt, - isDefault: rt.boolean, - isStatic: rt.boolean, + inventoryOptionsStateRT, + inventoryViewBasicAttributesRT, + inventoryViewFlagsRT, + rt.type({ + autoReload: rt.boolean, + filterQuery: inventoryFiltersStateRT, }), - rt.UnknownRecord, + rt.partial({ time: rt.number }), ]); -export type InventoryViewAttributes = rt.TypeOf; +const singleInventoryViewAttributesRT = rt.exact( + rt.intersection([inventoryViewBasicAttributesRT, inventoryViewFlagsRT]) +); export const inventoryViewRT = rt.exact( rt.intersection([ @@ -26,10 +96,31 @@ export const inventoryViewRT = rt.exact( attributes: inventoryViewAttributesRT, }), rt.partial({ - updatedAt: rt.number, + updatedAt: isoToEpochRt, + version: rt.string, + }), + ]) +); + +export const singleInventoryViewRT = rt.exact( + rt.intersection([ + rt.type({ + id: rt.string, + attributes: singleInventoryViewAttributesRT, + }), + rt.partial({ + updatedAt: isoToEpochRt, version: rt.string, }), ]) ); +export type InventoryColorPalette = rt.TypeOf; +export type InventoryFiltersState = rt.TypeOf; +export type InventoryLegendOptions = rt.TypeOf; +export type InventoryMapBounds = rt.TypeOf; +export type InventoryOptionsState = rt.TypeOf; +export type InventorySortOption = rt.TypeOf; export type InventoryView = rt.TypeOf; +export type InventoryViewAttributes = rt.TypeOf; +export type InventoryViewOptions = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/metrics_explorer_views/types.ts b/x-pack/plugins/infra/common/metrics_explorer_views/types.ts index 47ecb06ceace5..0d0c2fa3166e0 100644 --- a/x-pack/plugins/infra/common/metrics_explorer_views/types.ts +++ b/x-pack/plugins/infra/common/metrics_explorer_views/types.ts @@ -9,7 +9,7 @@ import { nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; export const metricsExplorerViewAttributesRT = rt.intersection([ - rt.strict({ + rt.type({ name: nonEmptyStringRt, isDefault: rt.boolean, isStatic: rt.boolean, diff --git a/x-pack/plugins/infra/common/saved_views/index.ts b/x-pack/plugins/infra/common/saved_views/index.ts new file mode 100644 index 0000000000000..6cc0ccaa93a6d --- /dev/null +++ b/x-pack/plugins/infra/common/saved_views/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 './types'; diff --git a/x-pack/plugins/infra/common/saved_views/types.ts b/x-pack/plugins/infra/common/saved_views/types.ts new file mode 100644 index 0000000000000..01bf806da44d9 --- /dev/null +++ b/x-pack/plugins/infra/common/saved_views/types.ts @@ -0,0 +1,70 @@ +/* + * 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 { + QueryObserverBaseResult, + UseMutateAsyncFunction, + UseMutateFunction, +} from '@tanstack/react-query'; + +import { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; + +export type ServerError = IHttpFetchError; + +export interface SavedViewState { + views?: SavedViewItem[]; + currentView?: TView | null; + isCreatingView: boolean; + isFetchingCurrentView: boolean; + isFetchingViews: boolean; + isUpdatingView: boolean; +} + +export interface SavedViewOperations< + TView extends { id: TView['id'] }, + TId extends TView['id'] = TView['id'], + TPayload = any, + TConfig = any +> { + createView: UseMutateAsyncFunction; + deleteViewById: UseMutateFunction>; + fetchViews: QueryObserverBaseResult['refetch']; + updateViewById: UseMutateAsyncFunction>; + switchViewById: (id: TId) => void; + setDefaultViewById: UseMutateFunction>; +} + +export interface SavedViewResult< + TView extends { + id: TView['id']; + }, + TId extends string = '', + TPayload = any, + TConfig = any +> extends SavedViewState, + SavedViewOperations {} + +export interface UpdateViewParams { + id: string; + attributes: TRequestPayload; +} + +export interface MutationContext { + id?: string; + previousViews?: TView[]; +} + +export interface BasicAttributes { + name?: string; + time?: number; + isDefault?: boolean; + isStatic?: boolean; +} +export interface SavedViewItem { + id: string; + attributes: BasicAttributes; +} diff --git a/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx b/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx index e503bdebafa03..67235c96a8bcc 100644 --- a/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx +++ b/x-pack/plugins/infra/public/components/saved_views/manage_views_flyout.tsx @@ -24,21 +24,15 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiBasicTableColumn } from '@elastic/eui'; import { EuiButtonIcon } from '@elastic/eui'; -import { MetricsExplorerView } from '../../../common/metrics_explorer_views'; -import type { InventoryView } from '../../../common/inventory_views'; -import { UseInventoryViewsResult } from '../../hooks/use_inventory_views'; -import { UseMetricsExplorerViewsResult } from '../../hooks/use_metrics_explorer_views'; +import { SavedViewOperations, SavedViewItem } from '../../../common/saved_views'; -type View = InventoryView | MetricsExplorerView; -type UseViewResult = UseInventoryViewsResult | UseMetricsExplorerViewsResult; - -export interface ManageViewsFlyoutProps { - views: UseViewResult['views']; +export interface ManageViewsFlyoutProps { + views?: SavedViewItem[]; loading: boolean; onClose(): void; - onMakeDefaultView: UseViewResult['setDefaultViewById']; - onSwitchView: UseViewResult['switchViewById']; - onDeleteView: UseViewResult['deleteViewById']; + onMakeDefaultView: SavedViewOperations['setDefaultViewById']; + onSwitchView: SavedViewOperations['switchViewById']; + onDeleteView: SavedViewOperations['deleteViewById']; } interface DeleteConfimationProps { @@ -50,18 +44,18 @@ const searchConfig = { box: { incremental: true }, }; -export function ManageViewsFlyout({ +export function ManageViewsFlyout({ onClose, views = [], onSwitchView, onMakeDefaultView, onDeleteView, loading, -}: ManageViewsFlyoutProps) { +}: ManageViewsFlyoutProps) { // Add name as top level property to allow in memory search const namedViews = useMemo(() => views.map(addOwnName), [views]); - const renderName = (name: string, item: View) => ( + const renderName = (name: string, item: SavedViewItem) => ( ); - const renderDeleteAction = (item: View) => { + const renderDeleteAction = (item: SavedViewItem) => { return ( { + const renderMakeDefaultAction = (item: SavedViewItem) => { return ( > = [ + const columns: Array> = [ { field: 'name', name: i18n.translate('xpack.infra.openView.columnNames.name', { defaultMessage: 'Name' }), @@ -193,4 +187,7 @@ const DeleteConfimation = ({ isDisabled, onConfirm }: DeleteConfimationProps) => /** * Helpers */ -const addOwnName = (view: View) => ({ ...view, name: view.attributes.name }); +const addOwnName = (view: TSavedViewState) => ({ + ...view, + name: view.attributes.name, +}); diff --git a/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx b/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx index b52d83cac60c6..11d45a51a0b2c 100644 --- a/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx +++ b/x-pack/plugins/infra/public/components/saved_views/toolbar_control.tsx @@ -10,35 +10,30 @@ import { i18n } from '@kbn/i18n'; import { EuiButton, EuiPopover, EuiListGroup, EuiListGroupItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { NonEmptyString } from '@kbn/io-ts-utils'; +import { + SavedViewState, + SavedViewOperations, + SavedViewItem, + BasicAttributes, +} from '../../../common/saved_views'; import { ManageViewsFlyout } from './manage_views_flyout'; import { useBoolean } from '../../hooks/use_boolean'; import { UpsertViewModal } from './upsert_modal'; -import { UseInventoryViewsResult } from '../../hooks/use_inventory_views'; -import { UseMetricsExplorerViewsResult } from '../../hooks/use_metrics_explorer_views'; - -type UseViewProps = - | 'currentView' - | 'views' - | 'isFetchingViews' - | 'isFetchingCurrentView' - | 'isCreatingView' - | 'isUpdatingView'; - -type UseViewResult = UseInventoryViewsResult | UseMetricsExplorerViewsResult; -type InventoryViewsResult = Pick; -type MetricsExplorerViewsResult = Pick; - -interface Props extends InventoryViewsResult, MetricsExplorerViewsResult { - viewState: ViewState & { time?: number }; - onCreateView: UseViewResult['createView']; - onDeleteView: UseViewResult['deleteViewById']; - onUpdateView: UseViewResult['updateViewById']; - onLoadViews: UseViewResult['fetchViews']; - onSetDefaultView: UseViewResult['setDefaultViewById']; - onSwitchView: UseViewResult['switchViewById']; + +interface Props + extends SavedViewState { + viewState: TViewState & BasicAttributes; + onCreateView: SavedViewOperations['createView']; + onDeleteView: SavedViewOperations['deleteViewById']; + onUpdateView: SavedViewOperations['updateViewById']; + onLoadViews: SavedViewOperations['fetchViews']; + onSetDefaultView: SavedViewOperations['setDefaultViewById']; + onSwitchView: SavedViewOperations['switchViewById']; } -export function SavedViewsToolbarControls(props: Props) { +export function SavedViewsToolbarControls( + props: Props +) { const { currentView, views, diff --git a/x-pack/plugins/infra/public/hooks/use_inventory_views.ts b/x-pack/plugins/infra/public/hooks/use_inventory_views.ts index 5bbc52e17afda..93873a307d59d 100644 --- a/x-pack/plugins/infra/public/hooks/use_inventory_views.ts +++ b/x-pack/plugins/infra/public/hooks/use_inventory_views.ts @@ -9,63 +9,29 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { - QueryObserverBaseResult, - UseMutateAsyncFunction, - UseMutateFunction, - useMutation, - useQuery, - useQueryClient, -} from '@tanstack/react-query'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useUiTracker } from '@kbn/observability-shared-plugin/public'; -import { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; -import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; import { - CreateInventoryViewAttributesRequestPayload, - UpdateInventoryViewAttributesRequestPayload, -} from '../../common/http_api/latest'; + MutationContext, + SavedViewResult, + ServerError, + UpdateViewParams, +} from '../../common/saved_views'; +import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; +import { CreateInventoryViewAttributesRequestPayload } from '../../common/http_api/latest'; import type { InventoryView } from '../../common/inventory_views'; import { useKibanaContextForPlugin } from './use_kibana'; import { useUrlState } from '../utils/use_url_state'; import { useSavedViewsNotifier } from './use_saved_views_notifier'; import { useSourceContext } from '../containers/metrics_source'; -interface UpdateViewParams { - id: string; - attributes: UpdateInventoryViewAttributesRequestPayload; -} - -export interface UseInventoryViewsResult { - views?: InventoryView[]; - currentView?: InventoryView | null; - createView: UseMutateAsyncFunction< - InventoryView, - ServerError, - CreateInventoryViewAttributesRequestPayload - >; - deleteViewById: UseMutateFunction; - fetchViews: QueryObserverBaseResult['refetch']; - updateViewById: UseMutateAsyncFunction; - switchViewById: (id: InventoryViewId) => void; - setDefaultViewById: UseMutateFunction< - MetricsSourceConfigurationResponse, - ServerError, - string, - MutationContext - >; - isCreatingView: boolean; - isFetchingCurrentView: boolean; - isFetchingViews: boolean; - isUpdatingView: boolean; -} - -type ServerError = IHttpFetchError; - -interface MutationContext { - id?: string; - previousViews?: InventoryView[]; -} +export type UseInventoryViewsResult = SavedViewResult< + InventoryView, + InventoryViewId, + CreateInventoryViewAttributesRequestPayload, + MetricsSourceConfigurationResponse +>; const queryKeys = { find: ['inventory-views-find'] as const, @@ -122,7 +88,7 @@ export const useInventoryViews = (): UseInventoryViewsResult => { MetricsSourceConfigurationResponse, ServerError, string, - MutationContext + MutationContext >({ mutationFn: (id) => updateSourceConfiguration({ inventoryDefaultView: id }), /** @@ -167,7 +133,7 @@ export const useInventoryViews = (): UseInventoryViewsResult => { const { mutateAsync: updateViewById, isLoading: isUpdatingView } = useMutation< InventoryView, ServerError, - UpdateViewParams + UpdateViewParams >({ mutationFn: ({ id, attributes }) => inventoryViews.client.updateInventoryView(id, attributes), onError: (error) => { @@ -178,7 +144,12 @@ export const useInventoryViews = (): UseInventoryViewsResult => { }, }); - const { mutate: deleteViewById } = useMutation({ + const { mutate: deleteViewById } = useMutation< + null, + ServerError, + string, + MutationContext + >({ mutationFn: (id: string) => inventoryViews.client.deleteInventoryView(id), /** * To provide a quick feedback, we perform an optimistic update on the list diff --git a/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts b/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts index 210a23a3b21ef..f2c9500f9ea63 100644 --- a/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts +++ b/x-pack/plugins/infra/public/hooks/use_metrics_explorer_views.ts @@ -9,63 +9,29 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { - QueryObserverBaseResult, - UseMutateAsyncFunction, - UseMutateFunction, - useMutation, - useQuery, - useQueryClient, -} from '@tanstack/react-query'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useUiTracker } from '@kbn/observability-shared-plugin/public'; -import { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser'; -import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; import { - CreateMetricsExplorerViewAttributesRequestPayload, - UpdateMetricsExplorerViewAttributesRequestPayload, -} from '../../common/http_api/latest'; + MutationContext, + SavedViewResult, + ServerError, + UpdateViewParams, +} from '../../common/saved_views'; +import { MetricsSourceConfigurationResponse } from '../../common/metrics_sources'; +import { CreateMetricsExplorerViewAttributesRequestPayload } from '../../common/http_api/latest'; import { MetricsExplorerView } from '../../common/metrics_explorer_views'; import { useKibanaContextForPlugin } from './use_kibana'; import { useUrlState } from '../utils/use_url_state'; import { useSavedViewsNotifier } from './use_saved_views_notifier'; import { useSourceContext } from '../containers/metrics_source'; -interface UpdateViewParams { - id: string; - attributes: UpdateMetricsExplorerViewAttributesRequestPayload; -} - -export interface UseMetricsExplorerViewsResult { - views?: MetricsExplorerView[]; - currentView?: MetricsExplorerView | null; - createView: UseMutateAsyncFunction< - MetricsExplorerView, - ServerError, - CreateMetricsExplorerViewAttributesRequestPayload - >; - deleteViewById: UseMutateFunction; - fetchViews: QueryObserverBaseResult['refetch']; - updateViewById: UseMutateAsyncFunction; - switchViewById: (id: MetricsExplorerViewId) => void; - setDefaultViewById: UseMutateFunction< - MetricsSourceConfigurationResponse, - ServerError, - string, - MutationContext - >; - isCreatingView: boolean; - isFetchingCurrentView: boolean; - isFetchingViews: boolean; - isUpdatingView: boolean; -} - -type ServerError = IHttpFetchError; - -interface MutationContext { - id?: string; - previousViews?: MetricsExplorerView[]; -} +export type UseMetricsExplorerViewsResult = SavedViewResult< + MetricsExplorerView, + MetricsExplorerViewId, + CreateMetricsExplorerViewAttributesRequestPayload, + MetricsSourceConfigurationResponse +>; const queryKeys = { find: ['metrics-explorer-views-find'] as const, @@ -122,7 +88,7 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => { MetricsSourceConfigurationResponse, ServerError, string, - MutationContext + MutationContext >({ mutationFn: (id) => updateSourceConfiguration({ metricsExplorerDefaultView: id }), /** @@ -167,7 +133,7 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => { const { mutateAsync: updateViewById, isLoading: isUpdatingView } = useMutation< MetricsExplorerView, ServerError, - UpdateViewParams + UpdateViewParams >({ mutationFn: ({ id, attributes }) => metricsExplorerViews.client.updateMetricsExplorerView(id, attributes), @@ -179,7 +145,12 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => { }, }); - const { mutate: deleteViewById } = useMutation({ + const { mutate: deleteViewById } = useMutation< + null, + ServerError, + string, + MutationContext + >({ mutationFn: (id: string) => metricsExplorerViews.client.deleteMetricsExplorerView(id), /** * To provide a quick feedback, we perform an optimistic update on the list diff --git a/x-pack/plugins/infra/public/lib/lib.ts b/x-pack/plugins/infra/public/lib/lib.ts index a37a9af7d9320..ac6527b9cc9c3 100644 --- a/x-pack/plugins/infra/public/lib/lib.ts +++ b/x-pack/plugins/infra/public/lib/lib.ts @@ -7,14 +7,16 @@ import { i18n } from '@kbn/i18n'; import * as rt from 'io-ts'; -import { +import type { InventoryMapBounds } from '../../common/inventory_views'; +import type { InfraTimerangeInput, SnapshotGroupBy, SnapshotMetricInput, SnapshotNodeMetric, SnapshotNodePath, } from '../../common/http_api/snapshot_api'; -import { WaffleSortOption } from '../pages/metrics/inventory_view/hooks/use_waffle_options'; +import type { WaffleSortOption } from '../pages/metrics/inventory_view/hooks/use_waffle_options'; +export type { InventoryColorPalette } from '../../common/inventory_views'; export interface InfraWaffleMapNode { pathId: string; @@ -72,9 +74,6 @@ export const PALETTES = { }), }; -export const InventoryColorPaletteRT = rt.keyof(PALETTES); -export type InventoryColorPalette = rt.TypeOf; - export const StepRuleRT = rt.intersection([ rt.type({ value: rt.number, @@ -136,10 +135,7 @@ export interface InfraOptions { wafflemap: InfraWaffleMapOptions; } -export interface InfraWaffleMapBounds { - min: number; - max: number; -} +export type InfraWaffleMapBounds = InventoryMapBounds; export type InfraFormatter = (value: string | number) => string; export enum InfraFormatterType { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx index 4547b0dbb0147..feb5283a39dcb 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/saved_views.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { useInventoryViews } from '../../../../hooks/use_inventory_views'; import { SavedViewsToolbarControls } from '../../../../components/saved_views/toolbar_control'; -import { useWaffleViewState, WaffleViewState } from '../hooks/use_waffle_view_state'; +import { useWaffleViewState } from '../hooks/use_waffle_view_state'; export const SavedViews = () => { const { viewState } = useWaffleViewState(); @@ -28,7 +28,7 @@ export const SavedViews = () => { } = useInventoryViews(); return ( - + { return true; }; -export const DEFAULT_WAFFLE_FILTERS_STATE: WaffleFiltersState = { kind: 'kuery', expression: '' }; +export const DEFAULT_WAFFLE_FILTERS_STATE: InventoryFiltersState = { + kind: 'kuery', + expression: '', +}; export const useWaffleFilters = () => { const { createDerivedIndexPattern } = useSourceContext(); const indexPattern = createDerivedIndexPattern(); - const [urlState, setUrlState] = useUrlState({ + const [urlState, setUrlState] = useUrlState({ defaultState: DEFAULT_WAFFLE_FILTERS_STATE, decodeUrlState, encodeUrlState, urlStateKey: 'waffleFilter', }); - const [state, setState] = useState(urlState); + const [state, setState] = useState(urlState); useEffect(() => setUrlState(state), [setUrlState, state]); @@ -61,7 +68,7 @@ export const useWaffleFilters = () => { [setState] ); - const applyFilterQuery = useCallback((filterQuery: WaffleFiltersState) => { + const applyFilterQuery = useCallback((filterQuery: InventoryFiltersState) => { setState(filterQuery); setFilterQueryDraft(filterQuery.expression); }, []); @@ -87,14 +94,10 @@ export const useWaffleFilters = () => { }; }; -export const WaffleFiltersStateRT = rt.type({ - kind: rt.literal('kuery'), - expression: rt.string, -}); - -export type WaffleFiltersState = rt.TypeOf; -const encodeUrlState = WaffleFiltersStateRT.encode; +// temporary +export type WaffleFiltersState = InventoryFiltersState; +const encodeUrlState = inventoryFiltersStateRT.encode; const decodeUrlState = (value: unknown) => - pipe(WaffleFiltersStateRT.decode(value), fold(constant(undefined), identity)); + pipe(inventoryFiltersStateRT.decode(value), fold(constant(undefined), identity)); export const WaffleFilters = createContainter(useWaffleFilters); export const [WaffleFiltersProvider, useWaffleFiltersContext] = WaffleFilters; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts index 8767be4f8a27e..9151e591a09f1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts @@ -6,23 +6,25 @@ */ import { useCallback, useState, useEffect } from 'react'; -import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import createContainer from 'constate'; -import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill'; -import { InventoryColorPaletteRT } from '../../../../lib/lib'; +import { InventoryViewOptions } from '../../../../../common/inventory_views/types'; import { + type InventoryLegendOptions, + type InventoryOptionsState, + type InventorySortOption, + inventoryOptionsStateRT, +} from '../../../../../common/inventory_views'; +import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill'; +import type { SnapshotMetricInput, SnapshotGroupBy, SnapshotCustomMetricInput, - SnapshotMetricInputRT, - SnapshotGroupByRT, - SnapshotCustomMetricInputRT, } from '../../../../../common/http_api/snapshot_api'; import { useUrlState } from '../../../../utils/use_url_state'; -import { InventoryItemType, ItemTypeRT } from '../../../../../common/inventory_models/types'; +import type { InventoryItemType } from '../../../../../common/inventory_models/types'; export const DEFAULT_LEGEND: WaffleLegendOptions = { palette: 'cool', @@ -75,7 +77,7 @@ export const useWaffleOptions = () => { ); const changeView = useCallback( - (view: string) => setState((previous) => ({ ...previous, view })), + (view: string) => setState((previous) => ({ ...previous, view: view as InventoryViewOptions })), [setState] ); @@ -160,51 +162,15 @@ export const useWaffleOptions = () => { }; }; -const WaffleLegendOptionsRT = rt.type({ - palette: InventoryColorPaletteRT, - steps: rt.number, - reverseColors: rt.boolean, -}); - -export type WaffleLegendOptions = rt.TypeOf; - -export const WaffleSortOptionRT = rt.type({ - by: rt.keyof({ name: null, value: null }), - direction: rt.keyof({ asc: null, desc: null }), -}); - -export const WaffleOptionsStateRT = rt.intersection([ - rt.type({ - metric: SnapshotMetricInputRT, - groupBy: SnapshotGroupByRT, - nodeType: ItemTypeRT, - view: rt.string, - customOptions: rt.array( - rt.type({ - text: rt.string, - field: rt.string, - }) - ), - boundsOverride: rt.type({ - min: rt.number, - max: rt.number, - }), - autoBounds: rt.boolean, - accountId: rt.string, - region: rt.string, - customMetrics: rt.array(SnapshotCustomMetricInputRT), - sort: WaffleSortOptionRT, - }), - rt.partial({ source: rt.string, legend: WaffleLegendOptionsRT, timelineOpen: rt.boolean }), -]); - -export type WaffleSortOption = rt.TypeOf; -export type WaffleOptionsState = rt.TypeOf; -const encodeUrlState = (state: WaffleOptionsState) => { - return WaffleOptionsStateRT.encode(state); +export type WaffleLegendOptions = InventoryLegendOptions; +export type WaffleSortOption = InventorySortOption; +export type WaffleOptionsState = InventoryOptionsState; + +const encodeUrlState = (state: InventoryOptionsState) => { + return inventoryOptionsStateRT.encode(state); }; const decodeUrlState = (value: unknown) => { - const state = pipe(WaffleOptionsStateRT.decode(value), fold(constant(undefined), identity)); + const state = pipe(inventoryOptionsStateRT.decode(value), fold(constant(undefined), identity)); if (state) { state.source = 'url'; } diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts index 6e685a6cc105f..c1ff4c67addbb 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_waffle_view_state.ts @@ -6,17 +6,10 @@ */ import { useCallback } from 'react'; -import { - useWaffleOptionsContext, - DEFAULT_WAFFLE_OPTIONS_STATE, - WaffleOptionsState, -} from './use_waffle_options'; +import { InventoryViewAttributes } from '../../../../../common/inventory_views'; +import { useWaffleOptionsContext, DEFAULT_WAFFLE_OPTIONS_STATE } from './use_waffle_options'; import { useWaffleTimeContext, DEFAULT_WAFFLE_TIME_STATE } from './use_waffle_time'; -import { - useWaffleFiltersContext, - DEFAULT_WAFFLE_FILTERS_STATE, - WaffleFiltersState, -} from './use_waffle_filters'; +import { useWaffleFiltersContext, DEFAULT_WAFFLE_FILTERS_STATE } from './use_waffle_filters'; export const DEFAULT_WAFFLE_VIEW_STATE: WaffleViewState = { ...DEFAULT_WAFFLE_OPTIONS_STATE, @@ -65,8 +58,8 @@ export const useWaffleViewState = () => { }; const onViewChange = useCallback( - (newState) => { - const attributes = newState.attributes as WaffleViewState; + (newState: { attributes: WaffleViewState }) => { + const attributes = newState.attributes; setWaffleOptionsState({ sort: attributes.sort, @@ -102,8 +95,7 @@ export const useWaffleViewState = () => { }; }; -export type WaffleViewState = WaffleOptionsState & { - time: number; - autoReload: boolean; - filterQuery: WaffleFiltersState; -}; +export type WaffleViewState = Omit< + InventoryViewAttributes, + 'name' | 'isDefault' | 'isStatic' | 'source' +>; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts index c7015764ddf24..cd37b0d8aab25 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/create_legend.ts @@ -5,7 +5,10 @@ * 2.0. */ -import { InventoryColorPalette, InfraWaffleMapSteppedGradientLegend } from '../../../../lib/lib'; +import type { + InventoryColorPalette, + InfraWaffleMapSteppedGradientLegend, +} from '../../../../lib/lib'; import { getColorPalette } from './get_color_palette'; export const createLegend = ( diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx index 2d329f121f008..ddce0eac506fe 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/saved_views.tsx @@ -31,7 +31,7 @@ export const SavedViews = ({ viewState }: Props) => { } = useMetricsExplorerViews(); return ( - + currentView={currentView} views={views} isFetchingViews={isFetchingViews} diff --git a/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts b/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts index eeabd15e60a4b..5cfda02fa4c17 100644 --- a/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts +++ b/x-pack/plugins/infra/public/services/inventory_views/inventory_views_client.ts @@ -9,15 +9,18 @@ import { HttpStart } from '@kbn/core/public'; import { CreateInventoryViewAttributesRequestPayload, createInventoryViewRequestPayloadRT, + CreateInventoryViewResponsePayload, + FindInventoryViewResponsePayload, findInventoryViewResponsePayloadRT, + GetInventoryViewResposePayload, getInventoryViewUrl, inventoryViewResponsePayloadRT, UpdateInventoryViewAttributesRequestPayload, + UpdateInventoryViewResponsePayload, } from '../../../common/http_api/latest'; import { DeleteInventoryViewError, FetchInventoryViewError, - InventoryView, UpsertInventoryViewError, } from '../../../common/inventory_views'; import { decodeOrThrow } from '../../../common/runtime_types'; @@ -26,7 +29,7 @@ import { IInventoryViewsClient } from './types'; export class InventoryViewsClient implements IInventoryViewsClient { constructor(private readonly http: HttpStart) {} - async findInventoryViews(): Promise { + async findInventoryViews(): Promise { const response = await this.http.get(getInventoryViewUrl()).catch((error) => { throw new FetchInventoryViewError(`Failed to fetch inventory views: ${error}`); }); @@ -40,7 +43,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { return data; } - async getInventoryView(inventoryViewId: string): Promise { + async getInventoryView(inventoryViewId: string): Promise { const response = await this.http.get(getInventoryViewUrl(inventoryViewId)).catch((error) => { throw new FetchInventoryViewError( `Failed to fetch inventory view "${inventoryViewId}": ${error}` @@ -60,7 +63,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { async createInventoryView( inventoryViewAttributes: CreateInventoryViewAttributesRequestPayload - ): Promise { + ): Promise { const response = await this.http .post(getInventoryViewUrl(), { body: JSON.stringify( @@ -85,7 +88,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { async updateInventoryView( inventoryViewId: string, inventoryViewAttributes: UpdateInventoryViewAttributesRequestPayload - ): Promise { + ): Promise { const response = await this.http .put(getInventoryViewUrl(inventoryViewId), { body: JSON.stringify( diff --git a/x-pack/plugins/infra/public/services/inventory_views/types.ts b/x-pack/plugins/infra/public/services/inventory_views/types.ts index 573c144e9c441..e2e26e6ef7f5b 100644 --- a/x-pack/plugins/infra/public/services/inventory_views/types.ts +++ b/x-pack/plugins/infra/public/services/inventory_views/types.ts @@ -8,9 +8,12 @@ import { HttpStart } from '@kbn/core/public'; import { CreateInventoryViewAttributesRequestPayload, + CreateInventoryViewResponsePayload, + FindInventoryViewResponsePayload, + GetInventoryViewResposePayload, UpdateInventoryViewAttributesRequestPayload, + UpdateInventoryViewResponsePayload, } from '../../../common/http_api/latest'; -import type { InventoryView } from '../../../common/inventory_views'; export type InventoryViewsServiceSetup = void; @@ -23,14 +26,14 @@ export interface InventoryViewsServiceStartDeps { } export interface IInventoryViewsClient { - findInventoryViews(): Promise; - getInventoryView(inventoryViewId: string): Promise; + findInventoryViews(): Promise; + getInventoryView(inventoryViewId: string): Promise; createInventoryView( inventoryViewAttributes: CreateInventoryViewAttributesRequestPayload - ): Promise; + ): Promise; updateInventoryView( inventoryViewId: string, inventoryViewAttributes: UpdateInventoryViewAttributesRequestPayload - ): Promise; + ): Promise; deleteInventoryView(inventoryViewId: string): Promise; } diff --git a/x-pack/plugins/infra/server/routes/inventory_views/README.md b/x-pack/plugins/infra/server/routes/inventory_views/README.md index be7d1c3734157..6edf5a540536a 100644 --- a/x-pack/plugins/infra/server/routes/inventory_views/README.md +++ b/x-pack/plugins/infra/server/routes/inventory_views/README.md @@ -130,26 +130,62 @@ Status code: 404 Creates a new inventory view. +`metric.type`: `"count" | "cpu" | "diskLatency" | "diskSpaceUsage" | "load" | "memory" | "memoryFree" | "memoryTotal" | "normalizedLoad1m" | "tx" | "rx" | "logRate" | "diskIOReadBytes" | "diskIOWriteBytes" | "s3TotalRequests" | "s3NumberOfObjects" | "s3BucketSize" | "s3DownloadBytes" | "s3UploadBytes" | "rdsConnections" | "rdsQueriesExecuted" | "rdsActiveTransactions" | "rdsLatency" | "sqsMessagesVisible" | "sqsMessagesDelayed" | "sqsMessagesSent" | "sqsMessagesEmpty" | "sqsOldestMessage"` + +`boundsOverride.max`: `range 0 to 1` +`boundsOverride.min`: `range 0 to 1` + +`sort.by`: `"name" | "value"` +`sort.direction`: `"asc | "desc"` + +`legend.pallete`: `"status" | "temperature" | "cool" | "warm" | "positive" | "negative"` + +`view`: `"map" | "table"` + ### Request - **Method**: POST - **Path**: /api/infra/inventory_views - **Request body**: + ```json { "attributes": { - "name": "View name", "metric": { - "type": "cpu" + "type": "cpu" }, "sort": { - "by": "name", - "direction": "desc" + "by": "name", + "direction": "desc" }, - //... + "groupBy": [], + "nodeType": "host", + "view": "map", + "customOptions": [], + "customMetrics": [], + "boundsOverride": { + "max": 1, + "min": 0 + }, + "autoBounds": true, + "accountId": "", + "region": "", + "autoReload": false, + "filterQuery": { + "expression": "", + "kind": "kuery" + }, + "legend": { + "palette": "cool", + "steps": 10, + "reverseColors": false + }, + "timelineOpen": false, + "name": "test-uptime" } } - ``` + +``` ### Response diff --git a/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts b/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts index 45e738f3920f1..30ab7068b7f40 100644 --- a/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts +++ b/x-pack/plugins/infra/server/saved_objects/inventory_view/types.ts @@ -5,14 +5,76 @@ * 2.0. */ -import { isoToEpochRt, nonEmptyStringRt } from '@kbn/io-ts-utils'; +import { inRangeRt, isoToEpochRt, nonEmptyStringRt } from '@kbn/io-ts-utils'; import * as rt from 'io-ts'; +import { ItemTypeRT } from '../../../common/inventory_models/types'; + +export const inventorySavedObjectColorPaletteRT = rt.keyof({ + status: null, + temperature: null, + cool: null, + warm: null, + positive: null, + negative: null, +}); + +const inventorySavedObjectLegendOptionsRT = rt.type({ + palette: inventorySavedObjectColorPaletteRT, + steps: inRangeRt(2, 18), + reverseColors: rt.boolean, +}); + +export const inventorySavedObjectSortOptionRT = rt.type({ + by: rt.keyof({ name: null, value: null }), + direction: rt.keyof({ asc: null, desc: null }), +}); + +export const inventorySavedObjectViewOptionsRT = rt.keyof({ table: null, map: null }); + +export const inventorySabedObjectMapBoundsRT = rt.type({ + min: inRangeRt(0, 1), + max: inRangeRt(0, 1), +}); + +export const inventorySavedObjectFiltersStateRT = rt.type({ + kind: rt.literal('kuery'), + expression: rt.string, +}); + +export const inventorySavedObjectOptionsStateRT = rt.intersection([ + rt.type({ + accountId: rt.string, + autoBounds: rt.boolean, + boundsOverride: inventorySabedObjectMapBoundsRT, + customMetrics: rt.UnknownArray, + customOptions: rt.array( + rt.type({ + text: rt.string, + field: rt.string, + }) + ), + groupBy: rt.UnknownArray, + metric: rt.UnknownRecord, + nodeType: ItemTypeRT, + region: rt.string, + sort: inventorySavedObjectSortOptionRT, + view: inventorySavedObjectViewOptionsRT, + }), + rt.partial({ + legend: inventorySavedObjectLegendOptionsRT, + source: rt.string, + timelineOpen: rt.boolean, + }), +]); export const inventoryViewSavedObjectAttributesRT = rt.intersection([ - rt.strict({ + inventorySavedObjectOptionsStateRT, + rt.type({ name: nonEmptyStringRt, + autoReload: rt.boolean, + filterQuery: inventorySavedObjectFiltersStateRT, }), - rt.UnknownRecord, + rt.partial({ time: rt.number, isDefault: rt.boolean, isStatic: rt.boolean }), ]); export const inventoryViewSavedObjectRT = rt.intersection([ @@ -25,3 +87,5 @@ export const inventoryViewSavedObjectRT = rt.intersection([ updated_at: isoToEpochRt, }), ]); + +export type InventoryViewSavedObject = rt.TypeOf; diff --git a/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts b/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts index 5efce009da410..78c7007ed1d1a 100644 --- a/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts +++ b/x-pack/plugins/infra/server/services/inventory_views/inventory_views_client.ts @@ -14,6 +14,7 @@ import { } from '@kbn/core/server'; import Boom from '@hapi/boom'; import { + inventoryViewAttributesRT, staticInventoryViewAttributes, staticInventoryViewId, } from '../../../common/inventory_views'; @@ -131,10 +132,10 @@ export class InventoryViewsClient implements IInventoryViewsClient { return this.savedObjectsClient.delete(inventoryViewSavedObjectName, inventoryViewId); } - private mapSavedObjectToInventoryView( - savedObject: SavedObject | SavedObjectsUpdateResponse, + private mapSavedObjectToInventoryView( + savedObject: SavedObject | SavedObjectsUpdateResponse, defaultViewId?: string - ) { + ): InventoryView { const inventoryViewSavedObject = decodeOrThrow(inventoryViewSavedObjectRT)(savedObject); return { @@ -142,7 +143,7 @@ export class InventoryViewsClient implements IInventoryViewsClient { version: inventoryViewSavedObject.version, updatedAt: inventoryViewSavedObject.updated_at, attributes: { - ...inventoryViewSavedObject.attributes, + ...decodeOrThrow(inventoryViewAttributesRT)(inventoryViewSavedObject.attributes), isDefault: inventoryViewSavedObject.id === defaultViewId, isStatic: false, }, diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts index 98481732be9d5..59ea0e5d21702 100644 --- a/x-pack/test/functional/apps/infra/home_page.ts +++ b/x-pack/test/functional/apps/infra/home_page.ts @@ -224,9 +224,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/157740 describe('Saved Views', () => { - this.tags('skipFirefox'); before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); await pageObjects.infraHome.goToMetricExplorer(); diff --git a/x-pack/test/functional/page_objects/infra_saved_views.ts b/x-pack/test/functional/page_objects/infra_saved_views.ts index 56c6e0d1354fb..218a7058f1141 100644 --- a/x-pack/test/functional/page_objects/infra_saved_views.ts +++ b/x-pack/test/functional/page_objects/infra_saved_views.ts @@ -54,7 +54,10 @@ export function InfraSavedViewsProvider({ getService }: FtrProviderContext) { async createNewSavedView(name: string) { await testSubjects.setValue('savedViewName', name); await testSubjects.click('createSavedViewButton'); - await testSubjects.missingOrFail('savedViews-upsertModal'); + + await retry.tryForTime(10 * 1000, async () => { + await testSubjects.missingOrFail('savedViews-upsertModal'); + }); }, async createView(name: string) { From 71da75408589a5718ac0b780eb7f8305a70fd1a1 Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Wed, 5 Jul 2023 09:03:18 +0200 Subject: [PATCH 24/64] [SecuritySolutions] Remove filter actions from Cases alerts table and fix show_top_n action (#161150) issue https://github.com/elastic/kibana/issues/134442 ## Summary * Remove filter actions from the cases alerts page because it has no search bar (as suggested by Sergi). * Fix the `show_top_n` action not executing from inside a table cell * Fix the `show_top_n` action not preselecting alerts on the cases alerts table Warning: `show_top_n` uses the global `timerange` but the cases page doesn't have the time range picker. --- .../src/hooks/use_data_grid_column_cell_actions.tsx | 2 +- .../public/common/components/top_n/helpers.ts | 1 + .../trigger_actions_alert_table/use_cell_actions.tsx | 9 ++++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx b/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx index 5877added643f..5820e7a971e90 100644 --- a/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx +++ b/packages/kbn-cell-actions/src/hooks/use_data_grid_column_cell_actions.tsx @@ -192,7 +192,7 @@ const getParentCellElement = (element?: HTMLElement | null): HTMLElement | null if (element == null) { return null; } - if (element.nodeName === 'div' && element.getAttribute('role') === 'gridcell') { + if (element.nodeName === 'DIV' && element.getAttribute('role') === 'gridcell') { return element; } return getParentCellElement(element.parentElement); diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts b/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts index 659aa08d754bf..876f04393dcdc 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/top_n/helpers.ts @@ -70,6 +70,7 @@ export interface TopNOption { export const detectionAlertsTables: string[] = [ TableId.alertsOnAlertsPage, TableId.alertsOnRuleDetailsPage, + TableId.alertsOnCasePage, TimelineId.casePage, ]; diff --git a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx index b6987f2fe29f6..e945e2c4828f2 100644 --- a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_cell_actions.tsx @@ -8,12 +8,11 @@ import type { BrowserField, TimelineNonEcsData } from '@kbn/timelines-plugin/common'; import type { AlertsTableConfigurationRegistry } from '@kbn/triggers-actions-ui-plugin/public/types'; import { useCallback, useMemo } from 'react'; -import { tableDefaults, dataTableSelectors } from '@kbn/securitysolution-data-table'; -import type { TableId } from '@kbn/securitysolution-data-table'; +import { TableId, tableDefaults, dataTableSelectors } from '@kbn/securitysolution-data-table'; import { getAllFieldsByName } from '../../../common/containers/source'; import type { UseDataGridColumnsSecurityCellActionsProps } from '../../../common/components/cell_actions'; import { useDataGridColumnsSecurityCellActions } from '../../../common/components/cell_actions'; -import { SecurityCellActionsTrigger } from '../../../actions/constants'; +import { SecurityCellActionsTrigger, SecurityCellActionType } from '../../../actions/constants'; import { VIEW_SELECTION } from '../../../../common/constants'; import { useSourcererDataView } from '../../../common/containers/sourcerer'; import { SourcererScopeName } from '../../../common/store/sourcerer/model'; @@ -89,12 +88,16 @@ export const getUseCellActionsHook = (tableId: TableId) => { [finalData] ); + const disabledActionTypes = + tableId === TableId.alertsOnCasePage ? [SecurityCellActionType.FILTER] : undefined; + const cellActions = useDataGridColumnsSecurityCellActions({ triggerId: SecurityCellActionsTrigger.DEFAULT, fields: cellActionsFields, getCellValue, metadata: cellActionsMetadata, dataGridRef, + disabledActionTypes, }); const getCellActions = useCallback( From 7be72ef2bfe123a5669e67229d3f7afcda0b88bf Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Wed, 5 Jul 2023 09:11:50 +0200 Subject: [PATCH 25/64] [Security Solutions] Fix CellActions component should hide ShowTopN action for nested fields (#159645) issue: https://github.com/elastic/kibana/issues/150347 ## Summary CellActions component should hide `ShowTopN` action for nested fields because Lens doesn't support it. * Add validations to exclude field that are not supported by Lens **After:** Screenshot 2023-06-30 at 14 26 09 ### How to test * Go to Security Solutions Alerts page * Add `Endpoint.policy.applied.artifacts.global.identifiers.name` field * Check if `ShowTopN` is displayed ### 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 --- .../cell_action/show_top_n.test.tsx | 38 ++++++++++++++----- .../show_top_n/cell_action/show_top_n.tsx | 9 ++--- .../public/common/utils/lens.ts | 18 +++++++++ .../components/alerts_kpis/common/hooks.ts | 6 +-- 4 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/utils/lens.ts diff --git a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx index bb64a2a2bdac6..87c920e787895 100644 --- a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx +++ b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.test.tsx @@ -17,6 +17,7 @@ import { createStore } from '../../../common/store'; import { createShowTopNCellActionFactory } from './show_top_n'; import React from 'react'; import { createStartServicesMock } from '../../../common/lib/kibana/kibana_react.mock'; +import { KBN_FIELD_TYPES } from '@kbn/field-types'; jest.mock('../../../common/lib/kibana'); @@ -45,7 +46,7 @@ describe('createShowTopNCellActionFactory', () => { value: 'the-value', field: { name: 'user.name', - type: 'keyword', + type: KBN_FIELD_TYPES.STRING, aggregatable: true, searchable: true, }, @@ -71,35 +72,54 @@ describe('createShowTopNCellActionFactory', () => { }); describe('isCompatible', () => { - it('should return true if everything is okay', async () => { - expect(await showTopNAction.isCompatible(context)).toEqual(true); - }); - - it('should return false if field esType does not support aggregations', async () => { + it('should return false if field is not aggregatable', async () => { expect( await showTopNAction.isCompatible({ ...context, data: [ { - field: { ...context.data[0].field, esTypes: ['text'] }, + field: { ...context.data[0].field, aggregatable: false }, }, ], }) ).toEqual(false); }); - it('should return false if field is not aggregatable', async () => { + it('should return false if field is nested', async () => { expect( await showTopNAction.isCompatible({ ...context, data: [ { - field: { ...context.data[0].field, aggregatable: false }, + field: { ...context.data[0].field, subType: { nested: { path: 'test_path' } } }, }, ], }) ).toEqual(false); }); + + describe.each([ + { type: KBN_FIELD_TYPES.STRING, expectedValue: true }, + { type: KBN_FIELD_TYPES.BOOLEAN, expectedValue: true }, + { type: KBN_FIELD_TYPES.NUMBER, expectedValue: true }, + { type: KBN_FIELD_TYPES.IP, expectedValue: true }, + { type: KBN_FIELD_TYPES.DATE, expectedValue: false }, + { type: KBN_FIELD_TYPES.GEO_SHAPE, expectedValue: false }, + { type: KBN_FIELD_TYPES.IP_RANGE, expectedValue: false }, + ])('lens supported KBN types', ({ type, expectedValue }) => { + it(`should return ${expectedValue} when type is ${type}`, async () => { + expect( + await showTopNAction.isCompatible({ + ...context, + data: [ + { + field: { ...context.data[0].field, type }, + }, + ], + }) + ).toEqual(expectedValue); + }); + }); }); describe('execute', () => { diff --git a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx index 0e1c419b0449e..3491f0ffcc620 100644 --- a/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx +++ b/x-pack/plugins/security_solution/public/actions/show_top_n/cell_action/show_top_n.tsx @@ -12,7 +12,7 @@ import { Router } from '@kbn/shared-ux-router'; import { i18n } from '@kbn/i18n'; import { createCellActionFactory, type CellActionTemplate } from '@kbn/cell-actions'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; -import { ES_FIELD_TYPES } from '@kbn/field-types'; +import { isDataViewFieldSubtypeNested } from '@kbn/es-query'; import { KibanaContextProvider } from '../../../common/lib/kibana'; import { APP_NAME, DEFAULT_DARK_MODE } from '../../../../common/constants'; import type { SecurityAppStore } from '../../../common/store'; @@ -21,6 +21,7 @@ import { TopNAction } from '../show_top_n_component'; import type { StartServices } from '../../../types'; import type { SecurityCellAction } from '../../types'; import { SecurityCellActionType } from '../../constants'; +import { isLensSupportedType } from '../../../common/utils/lens'; const SHOW_TOP = (fieldName: string) => i18n.translate('xpack.securitySolution.actions.showTopTooltip', { @@ -29,7 +30,6 @@ const SHOW_TOP = (fieldName: string) => }); const ICON = 'visBarVertical'; -const UNSUPPORTED_ES_FIELD_TYPES = [ES_FIELD_TYPES.DATE, ES_FIELD_TYPES.TEXT]; export const createShowTopNCellActionFactory = createCellActionFactory( ({ @@ -51,9 +51,8 @@ export const createShowTopNCellActionFactory = createCellActionFactory( return ( data.length === 1 && fieldHasCellActions(field.name) && - (field.esTypes ?? []).every( - (esType) => !UNSUPPORTED_ES_FIELD_TYPES.includes(esType as ES_FIELD_TYPES) - ) && + isLensSupportedType(field.type) && + !isDataViewFieldSubtypeNested(field) && !!field.aggregatable ); }, diff --git a/x-pack/plugins/security_solution/public/common/utils/lens.ts b/x-pack/plugins/security_solution/public/common/utils/lens.ts new file mode 100644 index 0000000000000..047144ce55f6f --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/lens.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. + */ + +import { KBN_FIELD_TYPES } from '@kbn/field-types'; + +const SUPPORTED_LENS_TYPES = new Set([ + KBN_FIELD_TYPES.STRING, + KBN_FIELD_TYPES.BOOLEAN, + KBN_FIELD_TYPES.NUMBER, + KBN_FIELD_TYPES.IP, +]); + +export const isLensSupportedType = (fieldType: string | undefined) => + fieldType ? SUPPORTED_LENS_TYPES.has(fieldType as KBN_FIELD_TYPES) : false; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts index 2658a0af00d6b..86c8719053c81 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/common/hooks.ts @@ -14,6 +14,7 @@ import type { BrowserField } from '@kbn/timelines-plugin/common'; import type { GlobalTimeArgs } from '../../../../common/containers/use_global_time'; import { getScopeFromPath, useSourcererDataView } from '../../../../common/containers/sourcerer'; import { getAllFieldsByName } from '../../../../common/containers/source'; +import { isLensSupportedType } from '../../../../common/utils/lens'; export interface UseInspectButtonParams extends Pick { response: string; @@ -65,11 +66,6 @@ export function isDataViewFieldSubtypeNested(field: Partial) { return !!subTypeNested?.nested?.path; } -export function isLensSupportedType(fieldType: string | undefined) { - const supportedTypes = new Set(['string', 'boolean', 'number', 'ip']); - return fieldType ? supportedTypes.has(fieldType) : false; -} - export interface GetAggregatableFields { [fieldName: string]: Partial; } From abe58cb0113e7c58f3bab3ab7d297e65ca01c0d9 Mon Sep 17 00:00:00 2001 From: Marco Antonio Ghiani Date: Wed, 5 Jul 2023 10:30:28 +0200 Subject: [PATCH 26/64] [Logs Shared] Move LogStream and LogView into new shared plugin (#161151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📓 Summary Closes #159128 Due to a dependencies issue when disabling a plugin in serverless mode, the LogStream feature and related logic were disabled for every consumer. We decided to split this shared component and endpoint into their own plugin of shared logs utilities, reducing to the minimum the required dependency that could disable the plugin. What we moved can be summarized with: - `infrastructure-monitoring-log-view` saved object definition and registration - LogViews server/client services (exposed with start contract) + related endpoints - LogEntries server service + related endpoints - LogEntriesDomain logic (exposed with start contract) - `` component - `` component and related logic - LogView state machine - Containers/Hooks to consume the moved APIs. - Common types/utils definition, now exported and consumed as a dependency from the `infra` plugin. ## 🤓 Review hints Most of the changes are just renaming and moving stuff into the new plugin, but for some operations was required to implement new logic, which may deserve a more critical review: - server/public `plugin.ts` files for the `infra` and `logs_shared` plugins. The new plugin now registers the fallback actions to retrieve a source configuration if there's no stored log view. It also set the configuration for the message field and registers the log view saved object. - the `logEntriesDomain` has also been moved inside the new plugin, but is also used by the logs-analysis endpoints, so it is exposed by the logs_shared plugin and consumed by `infra`. ## 👣 Following steps We currently are still using the `observability` plugin for consuming the CoPilot feature on our LogsStream flyout. The plugin dependency is marked as optional, so disabling the `observability` plugin in a serverless environment won't disable also the exposed features in this new plugin, but it'll affect only the CoPilot feature, which won't be loaded. In future, would be nice to extract the CoPilot feature into its own package/plugin, so that also serverless projects can consume it without depending on `observability. --------- Co-authored-by: Marco Antonio Ghiani Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 1 + docs/developer/plugin-list.asciidoc | 4 + package.json | 1 + packages/kbn-optimizer/limits.yml | 1 + tsconfig.base.json | 2 + x-pack/.i18nrc.json | 1 + x-pack/plugins/apm/kibana.jsonc | 1 + .../components/app/service_logs/index.tsx | 2 +- .../transaction_tabs.tsx | 2 +- x-pack/plugins/apm/tsconfig.json | 1 + .../common/types/kibana_deps.ts | 2 - x-pack/plugins/enterprise_search/kibana.jsonc | 2 +- .../shared/log_stream/log_stream.tsx | 8 +- .../enterprise_search/server/plugin.ts | 14 +- .../plugins/enterprise_search/tsconfig.json | 2 +- x-pack/plugins/fleet/kibana.jsonc | 2 +- .../components/agent_logs/agent_logs.tsx | 2 +- x-pack/plugins/fleet/tsconfig.json | 2 +- .../alerting/logs/log_threshold/types.ts | 2 +- x-pack/plugins/infra/common/http_api/index.ts | 2 - .../plugins/infra/common/http_api/latest.ts | 2 - .../log_alerts/v1/chart_preview_data.ts | 2 +- .../results/v1/log_entry_anomalies.ts | 2 +- .../v1/log_entry_anomalies_datasets.ts | 2 +- .../results/v1/log_entry_categories.ts | 2 +- .../results/v1/log_entry_category_datasets.ts | 2 +- .../results/v1/log_entry_category_examples.ts | 6 +- .../results/v1/log_entry_examples.ts | 2 +- .../plugins/infra/common/locators/helpers.ts | 24 +- .../infra/common/locators/locators.test.ts | 2 +- .../infra/common/locators/logs_locator.ts | 2 +- .../log_entries/log_entries.ts | 7 +- .../log_entries/log_entry.ts | 7 +- .../url_state_storage_service.ts | 8 +- x-pack/plugins/infra/kibana.jsonc | 1 + .../components/explain_log_rate_spike.tsx | 9 +- .../alert_details_app_section/index.tsx | 6 +- .../components/alert_dropdown.tsx | 2 +- .../components/expression_editor/criteria.tsx | 2 +- .../expression_editor/criterion.tsx | 2 +- .../criterion_preview_chart.tsx | 2 +- .../components/expression_editor/editor.tsx | 8 +- .../hooks/use_chart_preview_data.tsx | 2 +- .../expression_editor/log_view_switcher.tsx | 2 +- .../infra/public/apps/discover_app.tsx | 2 +- .../context/fixtures/log_entries.ts | 2 +- .../asset_details/tabs/logs/logs.tsx | 4 +- .../public/components/asset_details/types.ts | 2 +- .../log_stream/log_stream_embeddable.tsx | 4 +- .../logging/log_minimap/density_chart.tsx | 2 +- .../logging/log_minimap/log_minimap.tsx | 13 +- .../logging/log_minimap/search_marker.tsx | 7 +- .../logging/log_minimap/search_markers.tsx | 4 +- .../log_search_buttons.tsx | 3 +- .../log_search_controls.tsx | 2 +- .../view_log_in_context.ts | 3 +- .../infra/public/hooks/use_log_view.mock.ts | 77 ----- x-pack/plugins/infra/public/index.ts | 2 - x-pack/plugins/infra/public/mocks.tsx | 2 - .../state/src/state_machine.ts | 4 +- .../log_stream_page/state/src/types.ts | 12 +- .../src/url_state_storage_service.ts | 11 + .../src/state_machine.ts | 2 +- .../src/url_state_storage_service.ts | 6 +- .../src/state_machine_playground.tsx | 2 +- .../public/pages/link_to/redirect_to_logs.tsx | 2 +- .../pages/link_to/redirect_to_node_logs.tsx | 2 +- .../log_entry_categories/page_content.tsx | 2 +- .../log_entry_categories/page_providers.tsx | 2 +- .../page_results_content.tsx | 2 +- .../top_categories/category_details_row.tsx | 2 +- .../category_example_message.tsx | 25 +- .../top_categories/top_categories_section.tsx | 2 +- .../top_categories/top_categories_table.tsx | 2 +- .../get_log_entry_category_datasets.ts | 2 +- .../get_log_entry_category_examples.ts | 2 +- .../get_top_log_entry_categories.ts | 2 +- .../use_log_entry_categories_results.ts | 2 +- .../use_log_entry_category_examples.tsx | 2 +- .../logs/log_entry_rate/page_content.tsx | 2 +- .../logs/log_entry_rate/page_providers.tsx | 2 +- .../log_entry_rate/page_results_content.tsx | 3 +- .../sections/anomalies/expanded_row.tsx | 2 +- .../sections/anomalies/log_entry_example.tsx | 8 +- .../service_calls/get_log_entry_anomalies.ts | 2 +- .../get_log_entry_anomalies_datasets.ts | 2 +- .../service_calls/get_log_entry_examples.ts | 2 +- .../use_log_entry_anomalies_results.ts | 2 +- .../log_entry_rate/use_log_entry_examples.ts | 2 +- .../public/pages/logs/page_providers.tsx | 12 +- .../index_names_configuration_panel.tsx | 2 +- .../index_pattern_configuration_panel.tsx | 2 +- .../indices_configuration_form_state.ts | 2 +- .../settings/indices_configuration_panel.tsx | 2 +- .../source_configuration_form_state.tsx | 2 +- .../source_configuration_settings.tsx | 2 +- .../pages/logs/shared/page_log_view_error.tsx | 4 +- .../infra/public/pages/logs/stream/page.tsx | 2 +- .../pages/logs/stream/page_logs_content.tsx | 38 ++- .../pages/logs/stream/page_providers.tsx | 15 +- .../public/pages/logs/stream/page_toolbar.tsx | 8 +- .../logs/stream/page_view_log_in_context.tsx | 4 +- .../tabs/logs/logs_link_to_stream.tsx | 2 +- .../components/tabs/logs/logs_tab_content.tsx | 2 +- .../hosts/hooks/use_log_view_reference.ts | 8 +- .../components/node_details/tabs/logs.tsx | 2 +- .../metric_detail/hooks/use_metrics_time.ts | 2 +- x-pack/plugins/infra/public/plugin.ts | 18 +- .../infra/public/test_utils/entries.ts | 11 +- x-pack/plugins/infra/public/types.ts | 8 +- .../public/utils/logs_overview_fetchers.ts | 14 +- .../utils/logs_overview_fetches.test.ts | 74 +++-- .../plugins/infra/public/utils/url_state.tsx | 2 +- .../infra/public/utils/use_url_state.ts | 2 +- x-pack/plugins/infra/server/features.ts | 2 +- x-pack/plugins/infra/server/infra_server.ts | 10 - .../lib/adapters/framework/adapter_types.ts | 3 + ...nventory_metric_threshold_executor.test.ts | 3 +- .../inventory_metric_threshold_executor.ts | 4 +- .../log_threshold_chart_preview.ts | 2 +- .../log_threshold/log_threshold_executor.ts | 4 +- .../log_threshold_references_manager.ts | 4 +- .../plugins/infra/server/lib/infra_types.ts | 4 +- .../lib/log_analysis/log_entry_anomalies.ts | 2 +- .../log_entry_categories_analysis.ts | 7 +- x-pack/plugins/infra/server/mocks.ts | 16 +- x-pack/plugins/infra/server/plugin.ts | 61 ++-- .../routes/log_alerts/chart_preview_data.ts | 6 +- .../results/log_entry_category_examples.ts | 6 +- .../results/log_entry_examples.ts | 6 +- .../infra/server/routes/snapshot/index.ts | 4 +- .../infra/server/saved_objects/index.ts | 1 - x-pack/plugins/infra/server/types.ts | 12 +- .../utils/elasticsearch_runtime_types.ts | 7 - .../utils/map_source_to_log_view.test.ts | 59 ++++ .../server/utils/map_source_to_log_view.ts | 38 +++ x-pack/plugins/infra/tsconfig.json | 2 +- x-pack/plugins/logs_shared/README.md | 3 + .../plugins/logs_shared/common/constants.ts | 10 + x-pack/plugins/logs_shared/common/dynamic.tsx | 30 ++ .../logs_shared/common/formatters/datetime.ts | 18 ++ .../logs_shared/common/http_api/index.ts | 13 + .../logs_shared/common/http_api/latest.ts | 9 + .../http_api/log_entries/v1/highlights.ts | 0 .../common/http_api/log_entries/v1/index.ts | 0 .../common/http_api/log_entries/v1/summary.ts | 0 .../log_entries/v1/summary_highlights.ts | 0 .../common/http_api/log_views/common.ts | 0 .../common/http_api/log_views/index.ts | 0 .../http_api/log_views/v1/get_log_view.ts | 0 .../common/http_api/log_views/v1/index.ts | 0 .../http_api/log_views/v1/put_log_view.ts | 0 x-pack/plugins/logs_shared/common/index.ts | 58 ++++ .../common/log_entry/index.ts | 0 .../common/log_entry/log_entry.ts | 0 .../common/log_entry/log_entry_cursor.ts | 0 .../common/log_text_scale/index.ts | 8 + .../common/log_text_scale/log_text_scale.ts | 12 + .../common/log_views/defaults.ts | 7 +- .../common/log_views/errors.ts | 0 .../common/log_views/index.ts | 1 - .../common/log_views/log_view.mock.ts | 0 .../log_views/resolved_log_view.mock.ts | 0 .../common/log_views/resolved_log_view.ts | 9 +- .../common/log_views/types.ts | 4 +- x-pack/plugins/logs_shared/common/mocks.ts | 8 + .../logs_shared/common/runtime_types.ts | 69 ++++ .../common/search_strategies/common/errors.ts | 43 +++ .../log_entries/log_entries.ts | 75 +++++ .../log_entries/log_entry.ts | 40 +++ .../plugins/logs_shared/common/time/index.ts | 8 + .../logs_shared/common/time/time_key.ts | 80 +++++ .../plugins/logs_shared/common/typed_json.ts | 26 ++ x-pack/plugins/logs_shared/jest.config.js | 17 + x-pack/plugins/logs_shared/kibana.jsonc | 22 ++ .../public/components/auto_sizer.tsx | 188 +++++++++++ .../components/centered_flyout_body.tsx | 0 .../data_search_error_callout.stories.tsx | 0 .../components/data_search_error_callout.tsx | 6 +- .../data_search_progress.stories.tsx | 0 .../components/data_search_progress.tsx | 2 +- .../public/components/empty_states/index.tsx | 8 + .../components/empty_states/no_data.tsx | 49 +++ .../public/components/formatted_time.tsx | 0 .../loading/__examples__/index.stories.tsx | 23 ++ .../public/components/loading/index.tsx | 49 +++ .../public/components/log_stream/index.ts | 0 .../log_stream/log_stream.stories.mdx | 22 +- .../log_stream/log_stream.stories.tsx | 0 .../log_stream.story_decorators.tsx | 0 .../components/log_stream/log_stream.tsx | 0 .../log_stream/log_stream_error_boundary.tsx | 4 +- .../logging/log_entry_flyout/index.tsx | 0 .../log_entry_actions_menu.test.tsx | 0 .../log_entry_actions_menu.tsx | 19 +- .../log_entry_fields_table.tsx | 8 +- .../log_entry_flyout/log_entry_flyout.tsx | 26 +- .../log_text_stream/column_headers.tsx | 4 +- .../logging/log_text_stream/field_value.tsx | 0 .../logging/log_text_stream/highlighting.tsx | 0 .../logging/log_text_stream/index.ts | 7 +- .../logging/log_text_stream/item.ts | 0 .../logging/log_text_stream/jump_to_tail.tsx | 4 +- .../log_text_stream/loading_item_view.tsx | 28 +- .../logging/log_text_stream/log_date_row.tsx | 0 .../log_text_stream/log_entry_column.tsx | 0 .../log_entry_context_menu.tsx | 2 +- .../log_entry_field_column.test.tsx | 0 .../log_entry_field_column.tsx | 0 .../log_entry_message_column.test.tsx | 0 .../log_entry_message_column.tsx | 0 .../logging/log_text_stream/log_entry_row.tsx | 6 +- .../log_entry_timestamp_column.tsx | 0 .../log_text_stream/log_text_separator.tsx | 0 .../log_text_stream/measurable_item_view.tsx | 0 .../scrollable_log_text_stream_view.tsx | 22 +- .../logging/log_text_stream/text_styles.tsx | 0 .../log_text_stream/vertical_scroll_panel.tsx | 0 .../components/resettable_error_boundary.tsx | 0 .../public/containers/logs/log_entry.ts | 0 .../api/fetch_log_entries_highlights.ts | 0 .../api/fetch_log_summary_highlights.ts | 0 .../containers/logs/log_highlights/index.ts | 0 .../log_highlights/log_entry_highlights.tsx | 2 +- .../logs/log_highlights/log_highlights.tsx | 7 +- .../log_highlights/log_summary_highlights.ts | 2 +- .../logs/log_highlights/next_and_previous.tsx | 0 .../containers/logs/log_position/index.ts | 0 .../logs/log_position/use_log_position.ts | 43 ++- .../containers/logs/log_stream/index.ts | 0 .../log_stream/use_fetch_log_entries_after.ts | 0 .../use_fetch_log_entries_around.ts | 0 .../use_fetch_log_entries_before.ts | 0 .../logs/log_summary/api/fetch_log_summary.ts | 0 .../logs/log_summary/bucket_size.ts | 0 .../containers/logs/log_summary/index.ts | 0 .../logs/log_summary/log_summary.test.tsx | 0 .../logs/log_summary/log_summary.tsx | 2 +- .../logs/log_summary/with_summary.ts | 20 +- .../logs_shared/public/hooks/use_kibana.tsx | 71 +++++ .../public/hooks/use_log_view.ts | 0 x-pack/plugins/logs_shared/public/index.ts | 92 ++++++ x-pack/plugins/logs_shared/public/mocks.tsx | 16 + .../log_view_state/README.md | 0 .../log_view_state/index.ts | 0 .../log_view_state/src/index.ts | 0 .../log_view_state/src/notifications.ts | 0 .../log_view_state/src/state_machine.ts | 0 .../log_view_state/src/types.ts | 0 .../src/url_state_storage_service.ts | 0 .../xstate_helpers/README.md | 3 + .../xstate_helpers/index.ts | 8 + .../xstate_helpers/src/index.ts | 9 + .../src/notification_channel.ts | 41 +++ .../xstate_helpers/src/types.ts | 43 +++ x-pack/plugins/logs_shared/public/plugin.ts | 38 +++ .../public/services/log_views/index.ts | 0 .../log_views/log_views_client.mock.ts | 0 .../services/log_views/log_views_client.ts | 0 .../log_views/log_views_service.mock.ts | 0 .../services/log_views/log_views_service.ts | 14 +- .../public/services/log_views/types.ts | 5 +- .../logs_shared/public/test_utils/entries.ts | 75 +++++ .../test_utils/use_global_storybook_theme.tsx | 59 ++++ x-pack/plugins/logs_shared/public/types.ts | 57 ++++ .../utils/data_search/data_search.stories.mdx | 152 +++++++++ .../flatten_data_search_response.ts | 30 ++ .../public/utils/data_search/index.ts | 13 + .../normalize_data_search_responses.ts | 81 +++++ .../public/utils/data_search/types.ts | 50 +++ .../use_data_search_request.test.tsx | 198 ++++++++++++ .../data_search/use_data_search_request.ts | 104 ++++++ .../use_data_search_response_state.ts | 36 +++ ...test_partial_data_search_response.test.tsx | 121 +++++++ ...use_latest_partial_data_search_response.ts | 43 +++ .../logs_shared/public/utils/datemath.ts | 293 +++++++++++++++++ .../logs_shared/public/utils/dev_mode.ts | 12 + .../logs_shared/public/utils/handlers.ts | 25 ++ .../utils/log_column_render_configuration.tsx | 64 ++++ .../public/utils/log_entry/index.ts | 0 .../public/utils/log_entry/log_entry.ts | 0 .../utils/log_entry/log_entry_highlight.ts | 0 .../public/utils/styles.ts | 0 .../public/utils/typed_react.tsx} | 10 +- .../public/utils/use_kibana_query_settings.ts | 31 ++ .../public/utils/use_kibana_ui_setting.ts | 53 ++++ .../public/utils/use_observable.ts | 152 +++++++++ .../public/utils/use_tracked_promise.ts | 299 ++++++++++++++++++ .../public/utils/use_visibility_state.ts | 26 ++ x-pack/plugins/logs_shared/server/index.ts | 21 ++ .../lib/adapters/framework/adapter_types.ts | 96 ++++++ .../server/lib/adapters/framework/index.ts | 8 + .../framework/kibana_framework_adapter.ts | 179 +++++++++++ .../log_entries/kibana_log_entries_adapter.ts | 10 +- .../lib/domains/log_entries_domain/index.ts | 0 .../log_entries_domain.mock.ts | 19 ++ .../log_entries_domain/log_entries_domain.ts | 62 +++- .../queries/log_entry_datasets.ts | 2 - .../server/lib/logs_shared_types.ts | 24 ++ .../logs_shared/server/logs_shared_server.ts | 21 ++ x-pack/plugins/logs_shared/server/mocks.ts | 35 ++ x-pack/plugins/logs_shared/server/plugin.ts | 98 ++++++ .../server/routes/log_entries/highlights.ts | 4 +- .../server/routes/log_entries/index.ts | 0 .../server/routes/log_entries/summary.ts | 15 +- .../routes/log_entries/summary_highlights.ts | 4 +- .../server/routes/log_views/get_log_view.ts | 4 +- .../server/routes/log_views/index.ts | 4 +- .../server/routes/log_views/put_log_view.ts | 4 +- .../logs_shared/server/saved_objects/index.ts | 8 + .../server/saved_objects/log_view/index.ts | 0 .../log_view/log_view_saved_object.ts | 2 +- .../log_view/references/index.ts | 0 .../log_view/references/log_indices.ts | 12 +- .../server/saved_objects/log_view/types.ts | 2 + .../server/saved_objects/references.test.ts | 121 +++++++ .../server/saved_objects/references.ts | 78 +++++ .../server/services/log_entries/index.ts | 0 .../log_entries_search_strategy.test.ts | 0 .../log_entries_search_strategy.ts | 0 .../log_entries/log_entries_service.ts | 0 .../log_entry_search_strategy.test.ts | 0 .../log_entries/log_entry_search_strategy.ts | 0 .../builtin_rules/filebeat_apache2.test.ts | 0 .../message/builtin_rules/filebeat_apache2.ts | 0 .../builtin_rules/filebeat_auditd.test.ts | 0 .../message/builtin_rules/filebeat_auditd.ts | 0 .../builtin_rules/filebeat_haproxy.test.ts | 0 .../message/builtin_rules/filebeat_haproxy.ts | 0 .../builtin_rules/filebeat_icinga.test.ts | 0 .../message/builtin_rules/filebeat_icinga.ts | 0 .../builtin_rules/filebeat_iis.test.ts | 0 .../message/builtin_rules/filebeat_iis.ts | 0 .../builtin_rules/filebeat_kafka.test.ts | 0 .../builtin_rules/filebeat_logstash.test.ts | 0 .../builtin_rules/filebeat_logstash.ts | 0 .../builtin_rules/filebeat_mongodb.test.ts | 0 .../message/builtin_rules/filebeat_mongodb.ts | 0 .../builtin_rules/filebeat_mysql.test.ts | 0 .../message/builtin_rules/filebeat_mysql.ts | 0 .../builtin_rules/filebeat_nginx.test.ts | 0 .../message/builtin_rules/filebeat_nginx.ts | 0 .../builtin_rules/filebeat_osquery.test.ts | 0 .../message/builtin_rules/filebeat_osquery.ts | 0 .../message/builtin_rules/filebeat_redis.ts | 0 .../message/builtin_rules/filebeat_system.ts | 0 .../builtin_rules/filebeat_traefik.test.ts | 0 .../message/builtin_rules/filebeat_traefik.ts | 0 .../message/builtin_rules/generic.test.ts | 0 .../message/builtin_rules/generic.ts | 0 .../builtin_rules/generic_webserver.ts | 0 .../message/builtin_rules/helpers.ts | 0 .../message/builtin_rules/index.ts | 0 .../services/log_entries/message/index.ts | 0 .../services/log_entries/message/message.ts | 0 .../log_entries/message/rule_types.ts | 0 .../services/log_entries/queries/common.ts | 0 .../log_entries/queries/log_entries.ts | 0 .../services/log_entries/queries/log_entry.ts | 0 .../server/services/log_entries/types.ts | 0 .../server/services/log_views/errors.ts | 9 + .../server/services/log_views/index.ts | 0 .../log_views/log_views_client.mock.ts | 0 .../log_views/log_views_client.test.ts | 52 +-- .../services/log_views/log_views_client.ts | 51 +-- .../log_views/log_views_service.mock.ts | 2 + .../services/log_views/log_views_service.ts | 33 +- .../server/services/log_views/types.ts | 13 +- x-pack/plugins/logs_shared/server/types.ts | 48 +++ .../utils/elasticsearch_runtime_types.ts | 41 +++ .../server/utils/serialized_query.ts | 30 ++ .../server/utils/typed_search_strategy.ts | 0 x-pack/plugins/logs_shared/tsconfig.json | 31 ++ x-pack/plugins/monitoring/kibana.jsonc | 1 + ...{init_infra_source.ts => init_log_view.ts} | 8 +- .../collection/get_collection_status.test.ts | 2 + x-pack/plugins/monitoring/server/plugin.ts | 4 +- x-pack/plugins/monitoring/server/types.ts | 2 + x-pack/plugins/monitoring/tsconfig.json | 1 + .../translations/translations/fr-FR.json | 82 ++--- .../translations/translations/ja-JP.json | 82 ++--- .../translations/translations/zh-CN.json | 82 ++--- x-pack/plugins/upgrade_assistant/kibana.jsonc | 3 +- .../upgrade_assistant/server/plugin.ts | 8 +- .../plugins/upgrade_assistant/tsconfig.json | 2 +- .../api_integration/apis/logs_ui/log_views.ts | 4 +- .../apis/metrics_ui/log_entry_highlights.ts | 2 +- .../apis/metrics_ui/log_summary.ts | 2 +- .../test/common/services/infra_log_views.ts | 4 +- x-pack/test/tsconfig.json | 1 + yarn.lock | 4 + 391 files changed, 4955 insertions(+), 836 deletions(-) rename x-pack/plugins/infra/common/{log_views => }/url_state_storage_service.ts (90%) delete mode 100644 x-pack/plugins/infra/public/hooks/use_log_view.mock.ts create mode 100644 x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts create mode 100644 x-pack/plugins/infra/server/utils/map_source_to_log_view.ts create mode 100755 x-pack/plugins/logs_shared/README.md create mode 100644 x-pack/plugins/logs_shared/common/constants.ts create mode 100644 x-pack/plugins/logs_shared/common/dynamic.tsx create mode 100644 x-pack/plugins/logs_shared/common/formatters/datetime.ts create mode 100644 x-pack/plugins/logs_shared/common/http_api/index.ts create mode 100644 x-pack/plugins/logs_shared/common/http_api/latest.ts rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/summary.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_entries/v1/summary_highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/common.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/v1/get_log_view.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/v1/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/http_api/log_views/v1/put_log_view.ts (100%) create mode 100644 x-pack/plugins/logs_shared/common/index.ts rename x-pack/plugins/{infra => logs_shared}/common/log_entry/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_entry/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_entry/log_entry_cursor.ts (100%) create mode 100644 x-pack/plugins/logs_shared/common/log_text_scale/index.ts create mode 100644 x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts rename x-pack/plugins/{infra => logs_shared}/common/log_views/defaults.ts (82%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/errors.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/index.ts (89%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/log_view.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/resolved_log_view.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/resolved_log_view.ts (91%) rename x-pack/plugins/{infra => logs_shared}/common/log_views/types.ts (96%) create mode 100644 x-pack/plugins/logs_shared/common/mocks.ts create mode 100644 x-pack/plugins/logs_shared/common/runtime_types.ts create mode 100644 x-pack/plugins/logs_shared/common/search_strategies/common/errors.ts create mode 100644 x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts create mode 100644 x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.ts create mode 100644 x-pack/plugins/logs_shared/common/time/index.ts create mode 100644 x-pack/plugins/logs_shared/common/time/time_key.ts create mode 100644 x-pack/plugins/logs_shared/common/typed_json.ts create mode 100644 x-pack/plugins/logs_shared/jest.config.js create mode 100644 x-pack/plugins/logs_shared/kibana.jsonc create mode 100644 x-pack/plugins/logs_shared/public/components/auto_sizer.tsx rename x-pack/plugins/{infra => logs_shared}/public/components/centered_flyout_body.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_error_callout.stories.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_error_callout.tsx (92%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_progress.stories.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/data_search_progress.tsx (93%) create mode 100644 x-pack/plugins/logs_shared/public/components/empty_states/index.tsx create mode 100644 x-pack/plugins/logs_shared/public/components/empty_states/no_data.tsx rename x-pack/plugins/{infra => logs_shared}/public/components/formatted_time.tsx (100%) create mode 100644 x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx create mode 100644 x-pack/plugins/logs_shared/public/components/loading/index.tsx rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.stories.mdx (91%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.stories.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.story_decorators.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/log_stream/log_stream_error_boundary.tsx (93%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/index.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx (90%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx (90%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_entry_flyout/log_entry_flyout.tsx (91%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/column_headers.tsx (96%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/field_value.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/highlighting.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/index.ts (79%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/item.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/jump_to_tail.tsx (93%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/loading_item_view.tsx (89%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_date_row.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_context_menu.tsx (97%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_field_column.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_field_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_message_column.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_message_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_row.tsx (97%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/log_text_separator.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/measurable_item_view.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx (95%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/text_styles.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/logging/log_text_stream/vertical_scroll_panel.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/components/resettable_error_boundary.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/log_entry_highlights.tsx (98%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/log_highlights.tsx (96%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/log_summary_highlights.ts (97%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_highlights/next_and_previous.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_position/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_position/use_log_position.ts (80%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/use_fetch_log_entries_after.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/use_fetch_log_entries_around.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_stream/use_fetch_log_entries_before.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/api/fetch_log_summary.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/bucket_size.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/log_summary.test.tsx (100%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/log_summary.tsx (97%) rename x-pack/plugins/{infra => logs_shared}/public/containers/logs/log_summary/with_summary.ts (66%) create mode 100644 x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx rename x-pack/plugins/{infra => logs_shared}/public/hooks/use_log_view.ts (100%) create mode 100644 x-pack/plugins/logs_shared/public/index.ts create mode 100644 x-pack/plugins/logs_shared/public/mocks.tsx rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/README.md (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/notifications.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/state_machine.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/types.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/observability_logs/log_view_state/src/url_state_storage_service.ts (100%) create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/index.ts create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/index.ts create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts create mode 100644 x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.ts create mode 100644 x-pack/plugins/logs_shared/public/plugin.ts rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_client.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_client.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_service.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/log_views_service.ts (61%) rename x-pack/plugins/{infra => logs_shared}/public/services/log_views/types.ts (90%) create mode 100644 x-pack/plugins/logs_shared/public/test_utils/entries.ts create mode 100644 x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx create mode 100644 x-pack/plugins/logs_shared/public/types.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/index.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/types.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx create mode 100644 x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/datemath.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/dev_mode.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/handlers.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx rename x-pack/plugins/{infra => logs_shared}/public/utils/log_entry/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/utils/log_entry/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/utils/log_entry/log_entry_highlight.ts (100%) rename x-pack/plugins/{infra => logs_shared}/public/utils/styles.ts (100%) rename x-pack/plugins/{infra/public/components/log_stream/lazy_log_stream_wrapper.tsx => logs_shared/public/utils/typed_react.tsx} (50%) create mode 100644 x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_observable.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts create mode 100644 x-pack/plugins/logs_shared/public/utils/use_visibility_state.ts create mode 100644 x-pack/plugins/logs_shared/server/index.ts create mode 100644 x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.ts create mode 100644 x-pack/plugins/logs_shared/server/lib/adapters/framework/index.ts create mode 100644 x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts rename x-pack/plugins/{infra => logs_shared}/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts (96%) rename x-pack/plugins/{infra => logs_shared}/server/lib/domains/log_entries_domain/index.ts (100%) create mode 100644 x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.ts rename x-pack/plugins/{infra => logs_shared}/server/lib/domains/log_entries_domain/log_entries_domain.ts (84%) rename x-pack/plugins/{infra => logs_shared}/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts (96%) create mode 100644 x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts create mode 100644 x-pack/plugins/logs_shared/server/logs_shared_server.ts create mode 100644 x-pack/plugins/logs_shared/server/mocks.ts create mode 100644 x-pack/plugins/logs_shared/server/plugin.ts rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/highlights.ts (96%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/summary.ts (83%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_entries/summary_highlights.ts (95%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_views/get_log_view.ts (92%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_views/index.ts (82%) rename x-pack/plugins/{infra => logs_shared}/server/routes/log_views/put_log_view.ts (93%) create mode 100644 x-pack/plugins/logs_shared/server/saved_objects/index.ts rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/log_view_saved_object.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/references/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/references/log_indices.ts (85%) rename x-pack/plugins/{infra => logs_shared}/server/saved_objects/log_view/types.ts (95%) create mode 100644 x-pack/plugins/logs_shared/server/saved_objects/references.test.ts create mode 100644 x-pack/plugins/logs_shared/server/saved_objects/references.ts rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entries_search_strategy.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entries_search_strategy.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entries_service.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entry_search_strategy.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/log_entry_search_strategy.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_iis.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_redis.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_system.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/generic.test.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/generic.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/generic_webserver.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/helpers.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/builtin_rules/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/message.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/message/rule_types.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/queries/common.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/queries/log_entries.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/queries/log_entry.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_entries/types.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/errors.ts (65%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/index.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_client.mock.ts (100%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_client.test.ts (88%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_client.ts (77%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_service.mock.ts (90%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/log_views_service.ts (65%) rename x-pack/plugins/{infra => logs_shared}/server/services/log_views/types.ts (81%) create mode 100644 x-pack/plugins/logs_shared/server/types.ts create mode 100644 x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts create mode 100644 x-pack/plugins/logs_shared/server/utils/serialized_query.ts rename x-pack/plugins/{infra => logs_shared}/server/utils/typed_search_strategy.ts (100%) create mode 100644 x-pack/plugins/logs_shared/tsconfig.json rename x-pack/plugins/monitoring/server/lib/logs/{init_infra_source.ts => init_log_view.ts} (74%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9f41080bd5a59..4248bd86c7d5b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -468,6 +468,7 @@ examples/locator_examples @elastic/kibana-app-services examples/locator_explorer @elastic/kibana-app-services packages/kbn-logging @elastic/kibana-core packages/kbn-logging-mocks @elastic/kibana-core +x-pack/plugins/logs_shared @elastic/infra-monitoring-ui x-pack/plugins/logstash @elastic/logstash packages/kbn-managed-vscode-config @elastic/kibana-operations packages/kbn-managed-vscode-config-cli @elastic/kibana-operations diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 919703efff78f..8e001dcd6fdc6 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -628,6 +628,10 @@ the infrastructure monitoring use-case within Kibana. using the CURL scripts in the scripts folder. +|{kib-repo}blob/{branch}/x-pack/plugins/logs_shared/README.md[logsShared] +|Exposes the shared components and APIs to access and visualize logs. + + |{kib-repo}blob/{branch}/x-pack/plugins/logstash[logstash] |WARNING: Missing README. diff --git a/package.json b/package.json index 9a3366b65ee29..7658626741ea1 100644 --- a/package.json +++ b/package.json @@ -487,6 +487,7 @@ "@kbn/locator-explorer-plugin": "link:examples/locator_explorer", "@kbn/logging": "link:packages/kbn-logging", "@kbn/logging-mocks": "link:packages/kbn-logging-mocks", + "@kbn/logs-shared-plugin": "link:x-pack/plugins/logs_shared", "@kbn/logstash-plugin": "link:x-pack/plugins/logstash", "@kbn/management-cards-navigation": "link:packages/kbn-management/cards_navigation", "@kbn/management-plugin": "link:src/plugins/management", diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index eb7ca100c56f8..c0a9f99b09d4c 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -88,6 +88,7 @@ pageLoadAssetSize: licenseManagement: 41817 licensing: 29004 lists: 22900 + logsShared: 281060 logstash: 53548 management: 46112 maps: 90000 diff --git a/tsconfig.base.json b/tsconfig.base.json index 6db4864f58f05..1f70f84715646 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -930,6 +930,8 @@ "@kbn/logging/*": ["packages/kbn-logging/*"], "@kbn/logging-mocks": ["packages/kbn-logging-mocks"], "@kbn/logging-mocks/*": ["packages/kbn-logging-mocks/*"], + "@kbn/logs-shared-plugin": ["x-pack/plugins/logs_shared"], + "@kbn/logs-shared-plugin/*": ["x-pack/plugins/logs_shared/*"], "@kbn/logstash-plugin": ["x-pack/plugins/logstash"], "@kbn/logstash-plugin/*": ["x-pack/plugins/logstash/*"], "@kbn/managed-vscode-config": ["packages/kbn-managed-vscode-config"], diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index eea7dced5e278..2fa461531b499 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -37,6 +37,7 @@ "xpack.idxMgmt": "plugins/index_management", "xpack.indexLifecycleMgmt": "plugins/index_lifecycle_management", "xpack.infra": "plugins/infra", + "xpack.logsShared": "plugins/logs_shared", "xpack.fleet": "plugins/fleet", "xpack.ingestPipelines": "plugins/ingest_pipelines", "xpack.kubernetesSecurity": "plugins/kubernetes_security", diff --git a/x-pack/plugins/apm/kibana.jsonc b/x-pack/plugins/apm/kibana.jsonc index ac33a0ee0b844..0b248bbbe53f6 100644 --- a/x-pack/plugins/apm/kibana.jsonc +++ b/x-pack/plugins/apm/kibana.jsonc @@ -15,6 +15,7 @@ "embeddable", "features", "infra", + "logsShared", "inspector", "licensing", "observability", diff --git a/x-pack/plugins/apm/public/components/app/service_logs/index.tsx b/x-pack/plugins/apm/public/components/app/service_logs/index.tsx index 83cf09b3e586e..bde1749f33d35 100644 --- a/x-pack/plugins/apm/public/components/app/service_logs/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_logs/index.tsx @@ -7,7 +7,7 @@ import React from 'react'; import moment from 'moment'; -import { LogStream } from '@kbn/infra-plugin/public'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { useFetcher } from '../../../hooks/use_fetcher'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx index 7e363d50ae666..78e6a89d30620 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx @@ -7,7 +7,7 @@ import { EuiSpacer, EuiTab, EuiTabs, EuiSkeletonText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { LogStream } from '@kbn/infra-plugin/public'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import React, { useMemo } from 'react'; import { Transaction } from '../../../../../typings/es_schemas/ui/transaction'; import { TransactionMetadata } from '../../../shared/metadata_table/transaction_metadata'; diff --git a/x-pack/plugins/apm/tsconfig.json b/x-pack/plugins/apm/tsconfig.json index 4052693523612..6947c8cfcd628 100644 --- a/x-pack/plugins/apm/tsconfig.json +++ b/x-pack/plugins/apm/tsconfig.json @@ -92,6 +92,7 @@ "@kbn/dashboard-plugin", "@kbn/controls-plugin", "@kbn/core-http-server", + "@kbn/logs-shared-plugin", "@kbn/unified-field-list", "@kbn/slo-schema", "@kbn/discover-plugin" diff --git a/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts b/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts index 2bc2fed33aa4f..1e268aad1f73c 100644 --- a/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts +++ b/x-pack/plugins/enterprise_search/common/types/kibana_deps.ts @@ -11,7 +11,6 @@ import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DiscoverStart } from '@kbn/discover-plugin/public'; import type { FeaturesPluginStart } from '@kbn/features-plugin/public'; import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public'; -import type { InfraClientStartExports } from '@kbn/infra-plugin/public'; import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { SecurityPluginStart } from '@kbn/security-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; @@ -24,7 +23,6 @@ export interface KibanaDeps { discover: DiscoverStart; features: FeaturesPluginStart; guidedOnboarding: GuidedOnboardingPluginStart; - infra: InfraClientStartExports; licensing: LicensingPluginStart; security: SecurityPluginStart; share: SharePluginStart; diff --git a/x-pack/plugins/enterprise_search/kibana.jsonc b/x-pack/plugins/enterprise_search/kibana.jsonc index 0a6d3ebee52ae..01e43542e84f7 100644 --- a/x-pack/plugins/enterprise_search/kibana.jsonc +++ b/x-pack/plugins/enterprise_search/kibana.jsonc @@ -17,7 +17,7 @@ "data", "discover", "charts", - "infra", + "logsShared", "cloud", "esUiShared", "guidedOnboarding", diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx index d655a7c57a971..5f3af9a500b9b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/log_stream/log_stream.tsx @@ -7,17 +7,17 @@ import React from 'react'; -import { LogStream, LogStreamProps } from '@kbn/infra-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { LogStream, LogStreamProps } from '@kbn/logs-shared-plugin/public'; /* - * EnterpriseSearchLogStream is a light wrapper on top of infra's embeddable LogStream component. + * EnterpriseSearchLogStream is a light wrapper on top of logsShared's embeddable LogStream component. * It prepopulates our log source ID (set in server/plugin.ts) and sets a basic 24-hours-ago * default for timestamps. All other props get passed as-is to the underlying LogStream. * * Documentation links for reference: - * - https://github.com/elastic/kibana/blob/main/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx - * - Run `yarn storybook infra` for live docs + * - https://github.com/elastic/kibana/blob/main/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx + * - Run `yarn storybook logsShared` for live docs */ interface Props extends Omit { diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts index b072fbdf51503..041a295ff4831 100644 --- a/x-pack/plugins/enterprise_search/server/plugin.ts +++ b/x-pack/plugins/enterprise_search/server/plugin.ts @@ -21,7 +21,7 @@ import { DataPluginStart } from '@kbn/data-plugin/server/plugin'; import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { GlobalSearchPluginSetup } from '@kbn/global-search-plugin/server'; import type { GuidedOnboardingPluginSetup } from '@kbn/guided-onboarding-plugin/server'; -import { InfraPluginSetup } from '@kbn/infra-plugin/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import { SpacesPluginStart } from '@kbn/spaces-plugin/server'; @@ -88,7 +88,7 @@ interface PluginsSetup { features: FeaturesPluginSetup; globalSearch: GlobalSearchPluginSetup; guidedOnboarding: GuidedOnboardingPluginSetup; - infra: InfraPluginSetup; + logsShared: LogsSharedPluginSetup; ml?: MlPluginSetup; security: SecurityPluginSetup; usageCollection?: UsageCollectionSetup; @@ -125,7 +125,7 @@ export class EnterpriseSearchPlugin implements Plugin { security, features, globalSearch, - infra, + logsShared, customIntegrations, ml, guidedOnboarding, @@ -261,9 +261,9 @@ export class EnterpriseSearchPlugin implements Plugin { /* * Register logs source configuration, used by LogStream components - * @see https://github.com/elastic/kibana/blob/main/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx#with-a-source-configuration + * @see https://github.com/elastic/kibana/blob/main/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx#with-a-source-configuration */ - infra.logViews.defineInternalLogView(ENTERPRISE_SEARCH_RELEVANCE_LOGS_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(ENTERPRISE_SEARCH_RELEVANCE_LOGS_SOURCE_ID, { logIndices: { indexName: 'logs-app_search.search_relevance_suggestions-*', type: 'index_name', @@ -271,7 +271,7 @@ export class EnterpriseSearchPlugin implements Plugin { name: 'Enterprise Search Search Relevance Logs', }); - infra.logViews.defineInternalLogView(ENTERPRISE_SEARCH_AUDIT_LOGS_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(ENTERPRISE_SEARCH_AUDIT_LOGS_SOURCE_ID, { logIndices: { indexName: 'logs-enterprise_search*', type: 'index_name', @@ -279,7 +279,7 @@ export class EnterpriseSearchPlugin implements Plugin { name: 'Enterprise Search Audit Logs', }); - infra.logViews.defineInternalLogView(ENTERPRISE_SEARCH_ANALYTICS_LOGS_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(ENTERPRISE_SEARCH_ANALYTICS_LOGS_SOURCE_ID, { logIndices: { indexName: 'behavioral_analytics-events-*', type: 'index_name', diff --git a/x-pack/plugins/enterprise_search/tsconfig.json b/x-pack/plugins/enterprise_search/tsconfig.json index f8407385478f5..39758cb511103 100644 --- a/x-pack/plugins/enterprise_search/tsconfig.json +++ b/x-pack/plugins/enterprise_search/tsconfig.json @@ -22,7 +22,6 @@ "@kbn/usage-collection-plugin", "@kbn/cloud-plugin", "@kbn/cloud-chat-plugin", - "@kbn/infra-plugin", "@kbn/features-plugin", "@kbn/lens-plugin", "@kbn/licensing-plugin", @@ -60,6 +59,7 @@ "@kbn/core-elasticsearch-server-mocks", "@kbn/shared-ux-link-redirect-app", "@kbn/global-search-plugin", + "@kbn/logs-shared-plugin", "@kbn/share-plugin", "@kbn/core-saved-objects-migration-server-internal", ] diff --git a/x-pack/plugins/fleet/kibana.jsonc b/x-pack/plugins/fleet/kibana.jsonc index f86c939456445..f0b01080db22d 100644 --- a/x-pack/plugins/fleet/kibana.jsonc +++ b/x-pack/plugins/fleet/kibana.jsonc @@ -40,7 +40,7 @@ "kibanaReact", "cloudChat", "esUiShared", - "infra", + "logsShared", "kibanaUtils", "usageCollection", "unifiedSearch" diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx index 4af6b30c99fb4..e6dae29cea881 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx @@ -30,7 +30,7 @@ import semverCoerce from 'semver/functions/coerce'; import { createStateContainerReactHelpers } from '@kbn/kibana-utils-plugin/public'; import { RedirectAppLinks } from '@kbn/kibana-react-plugin/public'; import type { TimeRange } from '@kbn/es-query'; -import { LogStream, type LogStreamProps } from '@kbn/infra-plugin/public'; +import { LogStream, type LogStreamProps } from '@kbn/logs-shared-plugin/public'; import type { Agent, AgentPolicy } from '../../../../../types'; import { useLink, useStartServices } from '../../../../../hooks'; diff --git a/x-pack/plugins/fleet/tsconfig.json b/x-pack/plugins/fleet/tsconfig.json index dc858ff5029a8..4e8ec7de3fcc7 100644 --- a/x-pack/plugins/fleet/tsconfig.json +++ b/x-pack/plugins/fleet/tsconfig.json @@ -42,7 +42,7 @@ "@kbn/cloud-chat-plugin", "@kbn/kibana-react-plugin", "@kbn/es-ui-shared-plugin", - "@kbn/infra-plugin", + "@kbn/logs-shared-plugin", "@kbn/kibana-utils-plugin", "@kbn/unified-search-plugin", "@kbn/storybook", diff --git a/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts index 2eec5b035c793..4f5b977dd3b82 100644 --- a/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts +++ b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { commonSearchSuccessResponseFieldsRT } from '../../../utils/elasticsearch_runtime_types'; export const LOG_DOCUMENT_COUNT_RULE_TYPE_ID = 'logs.alert.document.count'; diff --git a/x-pack/plugins/infra/common/http_api/index.ts b/x-pack/plugins/infra/common/http_api/index.ts index 9f63896dbca9f..cfa4841d9aa57 100644 --- a/x-pack/plugins/infra/common/http_api/index.ts +++ b/x-pack/plugins/infra/common/http_api/index.ts @@ -20,6 +20,4 @@ export * as inventoryViewsV1 from './inventory_views/v1'; export * as logAlertsV1 from './log_alerts/v1'; export * as logAnalysisResultsV1 from './log_analysis/results/v1'; export * as logAnalysisValidationV1 from './log_analysis/validation/v1'; -export * as logEntriesV1 from './log_entries/v1'; -export * as logViewsV1 from './log_views/v1'; export * as metricsExplorerViewsV1 from './metrics_explorer_views/v1'; diff --git a/x-pack/plugins/infra/common/http_api/latest.ts b/x-pack/plugins/infra/common/http_api/latest.ts index 28cdf220f710e..98787a2c581a2 100644 --- a/x-pack/plugins/infra/common/http_api/latest.ts +++ b/x-pack/plugins/infra/common/http_api/latest.ts @@ -9,6 +9,4 @@ export * from './inventory_views/v1'; export * from './log_alerts/v1'; export * from './log_analysis/results/v1'; export * from './log_analysis/validation/v1'; -export * from './log_entries/v1'; -export * from './log_views/v1'; export * from './metrics_explorer_views/v1'; diff --git a/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts b/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts index 5647b9d09bdcc..7f0424f0df53b 100644 --- a/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts +++ b/x-pack/plugins/infra/common/http_api/log_alerts/v1/chart_preview_data.ts @@ -6,6 +6,7 @@ */ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { ThresholdRT, countCriteriaRT, @@ -13,7 +14,6 @@ import { timeSizeRT, groupByRT, } from '../../../alerting/logs/log_threshold/types'; -import { persistedLogViewReferenceRT } from '../../../log_views'; export const LOG_ALERTS_CHART_PREVIEW_DATA_PATH = '/api/infra/log_alerts/chart_preview_data'; diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts index 56ee97a468462..3553962063990 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies.ts @@ -7,7 +7,7 @@ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { timeRangeRT, routeTimingMetadataRT } from '../../../shared'; import { logEntryAnomalyRT, diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts index 8de55d96ba3c0..c07007be05115 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_anomalies_datasets.ts @@ -6,7 +6,7 @@ */ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { badRequestErrorRT, diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts index 9e838174bb6a1..e84825b8c6835 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_categories.ts @@ -7,7 +7,7 @@ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { badRequestErrorRT, forbiddenErrorRT, diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts index 6523559103fdc..e051e313d9b8e 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_datasets.ts @@ -7,13 +7,13 @@ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { badRequestErrorRT, forbiddenErrorRT, timeRangeRT, routeTimingMetadataRT, } from '../../../shared'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH = '/api/infra/log_analysis/results/log_entry_category_datasets'; diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts index 00fff8aabf9d1..fc6ece5d7b7f7 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_category_examples.ts @@ -5,16 +5,14 @@ * 2.0. */ +import { logEntryContextRT, persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import * as rt from 'io-ts'; - -import { persistedLogViewReferenceRT } from '../../../../log_views'; import { badRequestErrorRT, forbiddenErrorRT, - timeRangeRT, routeTimingMetadataRT, + timeRangeRT, } from '../../../shared'; -import { logEntryContextRT } from '../../../../log_entry'; export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH = '/api/infra/log_analysis/results/log_entry_category_examples'; diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts index 8233962df6bfa..ebc78693f4983 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/v1/log_entry_examples.ts @@ -6,7 +6,7 @@ */ import * as rt from 'io-ts'; -import { persistedLogViewReferenceRT } from '../../../../log_views'; +import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { logEntryExampleRT } from '../../../../log_analysis'; import { badRequestErrorRT, diff --git a/x-pack/plugins/infra/common/locators/helpers.ts b/x-pack/plugins/infra/common/locators/helpers.ts index 9ede09e7f1b1a..b4258053a0c01 100644 --- a/x-pack/plugins/infra/common/locators/helpers.ts +++ b/x-pack/plugins/infra/common/locators/helpers.ts @@ -5,23 +5,25 @@ * 2.0. */ -import { flowRight } from 'lodash'; import type { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import type { DiscoverStart } from '@kbn/discover-plugin/public'; -import { findInventoryFields } from '../inventory_models'; -import { MESSAGE_FIELD, TIMESTAMP_FIELD } from '../constants'; -import type { TimeRange } from '../time'; -import type { LogsLocatorParams } from './logs_locator'; -import type { InfraClientCoreSetup } from '../../public/types'; import { DEFAULT_LOG_VIEW, LogViewColumnConfiguration, LogViewReference, + ResolvedLogView, +} from '@kbn/logs-shared-plugin/common'; +import { flowRight } from 'lodash'; +import type { InfraClientCoreSetup } from '../../public/types'; +import { MESSAGE_FIELD, TIMESTAMP_FIELD } from '../constants'; +import { findInventoryFields } from '../inventory_models'; +import type { TimeRange } from '../time'; +import { replaceLogFilterInQueryString, replaceLogPositionInQueryString, replaceLogViewInQueryString, - ResolvedLogView, -} from '../log_views'; +} from '../url_state_storage_service'; +import type { LogsLocatorParams } from './logs_locator'; import type { NodeLogsLocatorParams } from './node_logs_locator'; interface LocationToDiscoverParams { @@ -59,9 +61,9 @@ export const getLocationToDiscover = async ({ filter, logView = DEFAULT_LOG_VIEW, }: LocationToDiscoverParams) => { - const [, plugins, pluginStart] = await core.getStartServices(); - const { discover } = plugins; - const { logViews } = pluginStart; + const [, plugins] = await core.getStartServices(); + const { discover, logsShared } = plugins; + const { logViews } = logsShared; const resolvedLogView = await logViews.client.getResolvedLogView(logView); const discoverParams: DiscoverAppLocatorParams = { diff --git a/x-pack/plugins/infra/common/locators/locators.test.ts b/x-pack/plugins/infra/common/locators/locators.test.ts index 5a4ea0047e2d7..c0573d942e757 100644 --- a/x-pack/plugins/infra/common/locators/locators.test.ts +++ b/x-pack/plugins/infra/common/locators/locators.test.ts @@ -13,7 +13,7 @@ import type { NodeLogsLocatorParams } from './node_logs_locator'; import { coreMock } from '@kbn/core/public/mocks'; import { findInventoryFields } from '../inventory_models'; import moment from 'moment'; -import { DEFAULT_LOG_VIEW, LogViewReference } from '../log_views'; +import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common'; const setupLogsLocator = async () => { const deps: LogsLocatorDependencies = { diff --git a/x-pack/plugins/infra/common/locators/logs_locator.ts b/x-pack/plugins/infra/common/locators/logs_locator.ts index f4e65634aa762..ee9006f359e66 100644 --- a/x-pack/plugins/infra/common/locators/logs_locator.ts +++ b/x-pack/plugins/infra/common/locators/logs_locator.ts @@ -7,7 +7,7 @@ import type { LocatorDefinition, LocatorPublic } from '@kbn/share-plugin/public'; import { SerializableRecord } from '@kbn/utility-types'; -import type { LogViewReference } from '../log_views'; +import type { LogViewReference } from '@kbn/logs-shared-plugin/common'; import type { TimeRange } from '../time'; import type { InfraClientCoreSetup } from '../../public/types'; diff --git a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts index f8daaa1b9227b..c6b53abee7143 100644 --- a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts +++ b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts @@ -6,14 +6,15 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import * as rt from 'io-ts'; import { logEntryAfterCursorRT, logEntryBeforeCursorRT, logEntryCursorRT, logEntryRT, -} from '../../log_entry'; -import { logViewColumnConfigurationRT, logViewReferenceRT } from '../../log_views'; + logViewColumnConfigurationRT, + logViewReferenceRT, +} from '@kbn/logs-shared-plugin/common'; +import * as rt from 'io-ts'; import { jsonObjectRT } from '../../typed_json'; import { searchStrategyErrorRT } from '../common/errors'; diff --git a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts index 6d2a7891264d1..131450d588c0f 100644 --- a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts +++ b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts @@ -5,9 +5,12 @@ * 2.0. */ +import { + logEntryCursorRT, + logEntryFieldRT, + logViewReferenceRT, +} from '@kbn/logs-shared-plugin/common'; import * as rt from 'io-ts'; -import { logEntryCursorRT, logEntryFieldRT } from '../../log_entry'; -import { logViewReferenceRT } from '../../log_views'; import { searchStrategyErrorRT } from '../common/errors'; export const LOG_ENTRY_SEARCH_STRATEGY = 'infra-log-entry'; diff --git a/x-pack/plugins/infra/common/log_views/url_state_storage_service.ts b/x-pack/plugins/infra/common/url_state_storage_service.ts similarity index 90% rename from x-pack/plugins/infra/common/log_views/url_state_storage_service.ts rename to x-pack/plugins/infra/common/url_state_storage_service.ts index 973fcd53ca98c..5d701ad1876bb 100644 --- a/x-pack/plugins/infra/common/log_views/url_state_storage_service.ts +++ b/x-pack/plugins/infra/common/url_state_storage_service.ts @@ -10,15 +10,15 @@ import { encode } from '@kbn/rison'; import type { Query } from '@kbn/es-query'; import { parse, stringify } from 'query-string'; import moment, { DurationInputObject } from 'moment'; -import type { FilterStateInUrl } from '../../public/observability_logs/log_stream_query_state'; -import type { PositionStateInUrl } from '../../public/observability_logs/log_stream_position_state/src/url_state_storage_service'; import { defaultFilterStateKey, defaultPositionStateKey, DEFAULT_REFRESH_INTERVAL, LogViewReference, -} from '.'; -import type { TimeRange } from '../time'; +} from '@kbn/logs-shared-plugin/common'; +import type { FilterStateInUrl } from '../public/observability_logs/log_stream_query_state'; +import type { PositionStateInUrl } from '../public/observability_logs/log_stream_position_state/src/url_state_storage_service'; +import type { TimeRange } from './time'; export const defaultLogViewKey = 'logView'; diff --git a/x-pack/plugins/infra/kibana.jsonc b/x-pack/plugins/infra/kibana.jsonc index c9a9ca0e18674..973d979ed90aa 100644 --- a/x-pack/plugins/infra/kibana.jsonc +++ b/x-pack/plugins/infra/kibana.jsonc @@ -20,6 +20,7 @@ "features", "fieldFormats", "lens", + "logsShared", "observability", "observabilityShared", "ruleRegistry", diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx index b51c9beae3836..a8acacd8debd1 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx @@ -52,7 +52,7 @@ export const ExplainLogRateSpikes: FC { const { services } = useKibanaContextForPlugin(); - const { dataViews, logViews } = services; + const { dataViews, logsShared } = services; const [dataView, setDataView] = useState(); const [esSearchQuery, setEsSearchQuery] = useState(); const [logSpikeParams, setLogSpikeParams] = useState< @@ -61,9 +61,8 @@ export const ExplainLogRateSpikes: FC { const getDataView = async () => { - const { timestampField, dataViewReference } = await logViews.client.getResolvedLogView( - rule.params.logView - ); + const { timestampField, dataViewReference } = + await logsShared.logViews.client.getResolvedLogView(rule.params.logView); if (dataViewReference.id) { const logDataView = await dataViews.get(dataViewReference.id); @@ -94,7 +93,7 @@ export const ExplainLogRateSpikes: FC import('./components/logs_history_chart')); @@ -44,7 +44,7 @@ const AlertDetailsAppSection = ({ alert, setAlertSummaryFields, }: AlertDetailsAppSectionProps) => { - const { observability, logViews } = useKibanaContextForPlugin().services; + const { observability, logsShared } = useKibanaContextForPlugin().services; const theme = useTheme(); const timeRange = getPaddedAlertTimeRange(alert.fields[ALERT_START]!, alert.fields[ALERT_END]); const alertEnd = alert.fields[ALERT_END] ? moment(alert.fields[ALERT_END]).valueOf() : undefined; @@ -66,7 +66,7 @@ const AlertDetailsAppSection = ({ const { derivedDataView } = useLogView({ initialLogViewReference: rule.params.logView, - logViews: logViews.client, + logViews: logsShared.logViews.client, }); const { hasAtLeast } = useLicense(); diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx index df324169c98e0..bb2dbc7afdc36 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx @@ -9,7 +9,7 @@ import React, { useState, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiPopover, EuiContextMenuItem, EuiContextMenuPanel, EuiHeaderLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useLogViewContext } from '../../../hooks/use_log_view'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { AlertFlyout } from './alert_flyout'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx index c5af2938f5456..33f63fe6a49c3 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import type { PersistedLogViewReference, ResolvedLogViewField, -} from '../../../../../common/log_views'; +} from '@kbn/logs-shared-plugin/common'; import { Criterion } from './criterion'; import { PartialRuleParams, diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx index 2e394bb093ec8..f2bb1d8ed5785 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx @@ -22,12 +22,12 @@ import { i18n } from '@kbn/i18n'; import { isFinite, isNumber } from 'lodash'; import React, { useCallback, useMemo, useState } from 'react'; import type { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public'; +import type { ResolvedLogViewField } from '@kbn/logs-shared-plugin/common'; import { Comparator, ComparatorToi18nMap, Criterion as CriterionType, } from '../../../../../common/alerting/logs/log_threshold/types'; -import type { ResolvedLogViewField } from '../../../../../common/log_views'; const firstCriterionFieldPrefix = i18n.translate( 'xpack.infra.logs.alertFlyout.firstCriterionFieldPrefix', diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx index b8dbc56402b2b..6b2357a4f4611 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx @@ -21,9 +21,9 @@ import { } from '@elastic/charts'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getChartTheme } from '../../../../utils/get_chart_theme'; import { useIsDarkMode } from '../../../../hooks/use_is_dark_mode'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; import { ExecutionTimeRange } from '../../../../types'; import { ChartContainer, diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index d9275a1ff0178..475bb0b1fbdef 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -13,7 +13,8 @@ import { ForLastExpression, RuleTypeParamsExpressionProps, } from '@kbn/triggers-actions-ui-plugin/public'; -import { PersistedLogViewReference, ResolvedLogViewField } from '../../../../../common/log_views'; +import { LogViewProvider, useLogViewContext } from '@kbn/logs-shared-plugin/public'; +import { PersistedLogViewReference, ResolvedLogViewField } from '@kbn/logs-shared-plugin/common'; import { Comparator, isOptimizableGroupedThreshold, @@ -28,7 +29,6 @@ import { import { decodeOrThrow } from '../../../../../common/runtime_types'; import { ObjectEntries } from '../../../../../common/utility_types'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; -import { LogViewProvider, useLogViewContext } from '../../../../hooks/use_log_view'; import { GroupByExpression } from '../../../common/group_by_expression/group_by_expression'; import { errorsRT } from '../../validation'; import { Criteria } from './criteria'; @@ -95,7 +95,7 @@ export const ExpressionEditor: React.FC< > = (props) => { const isInternal = props.metadata?.isInternal ?? false; const { - services: { logViews }, + services: { logsShared }, } = useKibanaContextForPlugin(); // injected during alert registration return ( @@ -105,7 +105,7 @@ export const ExpressionEditor: React.FC< ) : ( - + diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx index d633a055c46ef..ad042d77a584c 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx @@ -8,6 +8,7 @@ import { HttpHandler } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useMemo, useState } from 'react'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { isRatioRule } from '../../../../../../common/alerting/logs/log_threshold'; import { GetLogAlertsChartPreviewDataAlertParamsSubset, @@ -16,7 +17,6 @@ import { getLogAlertsChartPreviewDataSuccessResponsePayloadRT, LOG_ALERTS_CHART_PREVIEW_DATA_PATH, } from '../../../../../../common/http_api'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; import { decodeOrThrow } from '../../../../../../common/runtime_types'; import { ExecutionTimeRange } from '../../../../../types'; import { useTrackedPromise } from '../../../../../utils/use_tracked_promise'; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx index f3988002a7f7e..8dfa7295b6769 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/log_view_switcher.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFlexItem, EuiFlexGroup, EuiExpression, EuiToolTip } from '@elastic/eui'; -import { ResolvedLogView } from '../../../../../common/log_views'; +import { ResolvedLogView } from '@kbn/logs-shared-plugin/common'; const description = i18n.translate('xpack.infra.logs.alertFlyout.logViewDescription', { defaultMessage: 'Log View', diff --git a/x-pack/plugins/infra/public/apps/discover_app.tsx b/x-pack/plugins/infra/public/apps/discover_app.tsx index dd99a5e4dd625..2ea704fa9b21f 100644 --- a/x-pack/plugins/infra/public/apps/discover_app.tsx +++ b/x-pack/plugins/infra/public/apps/discover_app.tsx @@ -6,8 +6,8 @@ */ import { createKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import type { AppMountParameters, CoreStart } from '@kbn/core/public'; +import { getLogViewReferenceFromUrl } from '@kbn/logs-shared-plugin/public'; import type { InfraClientStartExports } from '../types'; -import { getLogViewReferenceFromUrl } from '../observability_logs/log_view_state'; export const renderApp = ( core: CoreStart, diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts index 6212c256647ef..35549673701fc 100644 --- a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/log_entries.ts @@ -11,11 +11,11 @@ import type { IKibanaSearchResponse, ISearchOptions, } from '@kbn/data-plugin/public'; +import { defaultLogViewAttributes } from '@kbn/logs-shared-plugin/common'; import { type LogEntriesSearchResponsePayload, LOG_ENTRIES_SEARCH_STRATEGY, } from '../../../../../../common/search_strategies/log_entries/log_entries'; -import { defaultLogViewAttributes } from '../../../../../../common/log_views'; import { generateFakeEntries } from '../../../../../test_utils/entries'; export const getLogEntries = ({ params }: IKibanaSearchRequest, options?: ISearchOptions) => { diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx index d928eda5a2137..d2311b91fa1b2 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx @@ -11,10 +11,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; -import { DEFAULT_LOG_VIEW, LogViewReference } from '../../../../../common/log_views'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; +import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common'; import type { InventoryItemType } from '../../../../../common/inventory_models/types'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; -import { LogStream } from '../../../log_stream'; import { findInventoryFields } from '../../../../../common/inventory_models'; import { InfraLoadingPanel } from '../../../loading'; diff --git a/x-pack/plugins/infra/public/components/asset_details/types.ts b/x-pack/plugins/infra/public/components/asset_details/types.ts index c42953ab8fb3e..a3d519641da3a 100644 --- a/x-pack/plugins/infra/public/components/asset_details/types.ts +++ b/x-pack/plugins/infra/public/components/asset_details/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { LogViewReference } from '../../../common/log_views'; +import { LogViewReference } from '@kbn/logs-shared-plugin/common'; import type { InventoryItemType } from '../../../common/inventory_models/types'; import type { InfraAssetMetricType, SnapshotCustomMetricInput } from '../../../common/http_api'; diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx b/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx index d2d59fe519353..1986354b5e9bd 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx +++ b/x-pack/plugins/infra/public/components/log_stream/log_stream_embeddable.tsx @@ -13,10 +13,10 @@ import { Subscription } from 'rxjs'; import type { TimeRange } from '@kbn/es-query'; import { Embeddable, EmbeddableInput, IContainer } from '@kbn/embeddable-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { CoreProviders } from '../../apps/common_providers'; import { InfraClientStartDeps, InfraClientStartExports } from '../../types'; import { datemathToEpochMillis } from '../../utils/datemath'; -import { LazyLogStreamWrapper } from './lazy_log_stream_wrapper'; export const LOG_STREAM_EMBEDDABLE = 'LOG_STREAM_EMBEDDABLE'; @@ -90,7 +90,7 @@ export class LogStreamEmbeddable extends Embeddable { >
- void; diff --git a/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx b/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx index e60a606ce0ce3..6533bebf74fc6 100644 --- a/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_search_controls/log_search_controls.tsx @@ -9,7 +9,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import classNames from 'classnames'; import * as React from 'react'; -import { LogEntryTime } from '../../../../common/log_entry'; +import { LogEntryTime } from '@kbn/logs-shared-plugin/common'; import { LogSearchButtons } from './log_search_buttons'; import { LogSearchInput } from './log_search_input'; diff --git a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts index 1ea8f71da129e..8327a14c28256 100644 --- a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts +++ b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts @@ -7,8 +7,7 @@ import { useState } from 'react'; import createContainer from 'constate'; -import { LogViewReference } from '../../../../common/log_views'; -import { LogEntry } from '../../../../common/log_entry'; +import { LogEntry, LogViewReference } from '@kbn/logs-shared-plugin/common'; interface ViewLogInContextProps { logViewReference: LogViewReference; diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts b/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts deleted file mode 100644 index 3d95dfb72abb0..0000000000000 --- a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts +++ /dev/null @@ -1,77 +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 { interpret } from 'xstate'; -import { createLogViewMock } from '../../common/log_views/log_view.mock'; -import { createResolvedLogViewMockFromAttributes } from '../../common/log_views/resolved_log_view.mock'; -import { - createLogViewNotificationChannel, - createPureLogViewStateMachine, -} from '../observability_logs/log_view_state/src'; -import { useLogView } from './use_log_view'; - -type UseLogView = typeof useLogView; -type IUseLogView = ReturnType; - -const defaultLogViewId = 'default'; - -export const createUninitializedUseLogViewMock = - (logViewId: string = defaultLogViewId) => - (): IUseLogView => ({ - derivedDataView: undefined, - hasFailedLoading: false, - hasFailedLoadingLogView: false, - hasFailedLoadingLogViewStatus: false, - hasFailedResolvingLogView: false, - isLoading: false, - isLoadingLogView: false, - isLoadingLogViewStatus: false, - isResolvingLogView: false, - isUninitialized: true, - latestLoadLogViewFailures: [], - load: jest.fn(), - retry: jest.fn(), - logView: undefined, - logViewReference: { type: 'log-view-reference', logViewId }, - logViewStatus: undefined, - resolvedLogView: undefined, - update: jest.fn(), - changeLogViewReference: jest.fn(), - revertToDefaultLogView: jest.fn(), - logViewStateService: interpret( - createPureLogViewStateMachine({ logViewReference: { type: 'log-view-reference', logViewId } }) - ), - logViewStateNotifications: createLogViewNotificationChannel(), - isPersistedLogView: false, - isInlineLogView: false, - }); - -export const createLoadingUseLogViewMock = - (logViewId: string = defaultLogViewId) => - (): IUseLogView => ({ - ...createUninitializedUseLogViewMock(logViewId)(), - isLoading: true, - isLoadingLogView: true, - isLoadingLogViewStatus: true, - isResolvingLogView: true, - }); - -export const createLoadedUseLogViewMock = async (logViewId: string = defaultLogViewId) => { - const logView = createLogViewMock(logViewId); - const resolvedLogView = await createResolvedLogViewMockFromAttributes(logView.attributes); - - return (): IUseLogView => { - return { - ...createUninitializedUseLogViewMock(logViewId)(), - logView, - resolvedLogView, - logViewStatus: { - index: 'available', - }, - }; - }; -}; diff --git a/x-pack/plugins/infra/public/index.ts b/x-pack/plugins/infra/public/index.ts index 4bd094b3d79f4..49a0257a22b38 100644 --- a/x-pack/plugins/infra/public/index.ts +++ b/x-pack/plugins/infra/public/index.ts @@ -29,6 +29,4 @@ export { InfraFormatterType } from './lib/lib'; export type InfraAppId = 'logs' | 'metrics'; // Shared components -export { LazyLogStreamWrapper as LogStream } from './components/log_stream/lazy_log_stream_wrapper'; -export type { LogStreamProps } from './components/log_stream'; export type { InfraClientStartExports } from './types'; diff --git a/x-pack/plugins/infra/public/mocks.tsx b/x-pack/plugins/infra/public/mocks.tsx index d977e13ddd980..9b232c515ce81 100644 --- a/x-pack/plugins/infra/public/mocks.tsx +++ b/x-pack/plugins/infra/public/mocks.tsx @@ -8,14 +8,12 @@ import React from 'react'; import { createLocatorMock } from '../common/locators/locators.mock'; import { createInventoryViewsServiceStartMock } from './services/inventory_views/inventory_views_service.mock'; -import { createLogViewsServiceStartMock } from './services/log_views/log_views_service.mock'; import { createMetricsExplorerViewsServiceStartMock } from './services/metrics_explorer_views/metrics_explorer_views_service.mock'; import { createTelemetryServiceMock } from './services/telemetry/telemetry_service.mock'; import { InfraClientStartExports } from './types'; export const createInfraPluginStartMock = () => ({ inventoryViews: createInventoryViewsServiceStartMock(), - logViews: createLogViewsServiceStartMock(), metricsExplorerViews: createMetricsExplorerViewsServiceStartMock(), telemetry: createTelemetryServiceMock(), locators: createLocatorMock(), diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts index b7c02e916dc57..d2a71c65702eb 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/state_machine.ts @@ -8,7 +8,8 @@ import { RefreshInterval } from '@kbn/data-plugin/public'; import { TimeRange } from '@kbn/es-query'; import { actions, ActorRefFrom, createMachine, EmittedFrom } from 'xstate'; -import { DEFAULT_REFRESH_INTERVAL } from '../../../../../common/log_views'; +import { DEFAULT_REFRESH_INTERVAL } from '@kbn/logs-shared-plugin/common'; +import type { LogViewNotificationChannel } from '@kbn/logs-shared-plugin/public'; import { datemathToEpochMillis } from '../../../../utils/datemath'; import { createLogStreamPositionStateMachine } from '../../../log_stream_position_state/src/state_machine'; import { @@ -16,7 +17,6 @@ import { DEFAULT_TIMERANGE, LogStreamQueryStateMachineDependencies, } from '../../../log_stream_query_state'; -import type { LogViewNotificationChannel } from '../../../log_view_state'; import { OmitDeprecatedState } from '../../../xstate_helpers'; import { waitForInitialQueryParameters, diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts index eb42dccdf2486..12c707ebb91fd 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_page/state/src/types.ts @@ -6,8 +6,13 @@ */ import { TimeRange } from '@kbn/es-query'; +import type { LogViewStatus } from '@kbn/logs-shared-plugin/common'; +import type { + LogViewContextWithError, + LogViewContextWithResolvedLogView, + LogViewNotificationEvent, +} from '@kbn/logs-shared-plugin/public'; import { TimeKey } from '../../../../../common/time'; -import type { LogViewStatus } from '../../../../../common/log_views'; import { JumpToTargetPositionEvent, LogStreamPositionContext, @@ -22,11 +27,6 @@ import { UpdateTimeRangeEvent, } from '../../../log_stream_query_state'; import { LogStreamQueryNotificationEvent } from '../../../log_stream_query_state/src/notifications'; -import type { - LogViewContextWithError, - LogViewContextWithResolvedLogView, - LogViewNotificationEvent, -} from '../../../log_view_state'; export interface ReceivedInitialQueryParametersEvent { type: 'RECEIVED_INITIAL_QUERY_PARAMETERS'; diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts index 5607bf9207054..c98ab9e147444 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_position_state/src/url_state_storage_service.ts @@ -10,6 +10,7 @@ import { IKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugi import * as Either from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/function'; import { InvokeCreator } from 'xstate'; +import { replaceStateKeyInQueryString } from '../../../../common/url_state_storage_service'; import { minimalTimeKeyRT, pickTimeKey } from '../../../../common/time'; import { createPlainError, formatErrors } from '../../../../common/runtime_types'; import type { LogStreamPositionContext, LogStreamPositionEvent } from './types'; @@ -97,3 +98,13 @@ export type PositionStateInUrl = rt.TypeOf; const decodePositionQueryValueFromUrl = (queryValueFromUrl: unknown) => { return positionStateInUrlRT.decode(queryValueFromUrl); }; + +export const replaceLogPositionInQueryString = (time?: number) => + Number.isNaN(time) || time == null + ? (value: string) => value + : replaceStateKeyInQueryString(defaultPositionStateKey, { + position: { + time, + tiebreaker: 0, + }, + }); diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts index 1a69642037d19..1c0de464121c8 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/state_machine.ts @@ -14,7 +14,7 @@ import type { import { EsQueryConfig } from '@kbn/es-query'; import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import { actions, ActorRefFrom, createMachine, SpecialTargets, send } from 'xstate'; -import { DEFAULT_REFRESH_INTERVAL } from '../../../../common/log_views'; +import { DEFAULT_REFRESH_INTERVAL } from '@kbn/logs-shared-plugin/common'; import { OmitDeprecatedState, sendIfDefined } from '../../xstate_helpers'; import { logStreamQueryNotificationEventSelectors } from './notifications'; import { diff --git a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts index 448fb941e037c..fb65fcd987a11 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_stream_query_state/src/url_state_storage_service.ts @@ -16,9 +16,11 @@ import { defaultFilterStateKey, defaultPositionStateKey, DEFAULT_REFRESH_INTERVAL, - getTimeRangeStartFromTime, +} from '@kbn/logs-shared-plugin/common'; +import { getTimeRangeEndFromTime, -} from '../../../../common/log_views'; + getTimeRangeStartFromTime, +} from '../../../../common/url_state_storage_service'; import { minimalTimeKeyRT } from '../../../../common/time'; import { datemathStringRT } from '../../../utils/datemath'; import { createPlainError, formatErrors } from '../../../../common/runtime_types'; diff --git a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx index 78f1c5f15dee9..5a40bd5d32292 100644 --- a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx +++ b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx @@ -7,7 +7,7 @@ import { EuiButton } from '@elastic/eui'; import React, { useCallback } from 'react'; -import { useLogViewContext } from '../../../hooks/use_log_view'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; export const StateMachinePlayground = () => { const { changeLogViewReference, revertToDefaultLogView, update, isLoading, logViewStateService } = diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx index 3bbe00c5314cf..663df4c0f4d1a 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx @@ -7,7 +7,7 @@ import { useEffect } from 'react'; import { useLocation, useParams } from 'react-router-dom'; -import { DEFAULT_LOG_VIEW } from '../../../common/log_views'; +import { DEFAULT_LOG_VIEW } from '@kbn/logs-shared-plugin/common'; import { getFilterFromLocation, getTimeFromLocation } from './query_params'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx index 66898bf38b4b4..e3382d43c0e15 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx @@ -7,7 +7,7 @@ import { useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; -import { DEFAULT_LOG_VIEW } from '../../../common/log_views'; +import { DEFAULT_LOG_VIEW } from '@kbn/logs-shared-plugin/common'; import { InventoryItemType } from '../../../common/inventory_models/types'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx index bde85aa99ec7f..d6a1e9f2ddc5e 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback, useEffect } from 'react'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { LoadingPage } from '../../../components/loading_page'; import { @@ -22,7 +23,6 @@ import { import { SubscriptionSplashPage } from '../../../components/subscription_splash_content'; import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { LogEntryCategoriesResultsContent } from './page_results_content'; import { LogEntryCategoriesSetupContent } from './page_setup_content'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx index 6e1d3f4a4f0bd..5cb6a12166c53 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -6,12 +6,12 @@ */ import React from 'react'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ children }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx index f26f8768a4459..e1e317136deed 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx @@ -15,6 +15,7 @@ import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { MLJobsAwaitingNodeWarning, ML_PAGES, useMlHref } from '@kbn/ml-plugin/public'; import { useTrackPageview } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { TimeRange } from '../../../../common/time/time_range'; import { CategoryJobNoticesSection } from '../../../components/logging/log_analysis_job_status'; import { AnalyzeInMlButton } from '../../../components/logging/log_analysis_results'; @@ -24,7 +25,6 @@ import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_ import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { PageViewLogInContext } from '../stream/page_view_log_in_context'; import { TopCategoriesSection } from './sections/top_categories'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx index dbf143f95d0bc..34cced7d92ffd 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_details_row.tsx @@ -6,7 +6,7 @@ */ import React, { useEffect } from 'react'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { useLogEntryCategoryExamples } from '../../use_log_entry_category_examples'; import { LogEntryExampleMessages } from '../../../../../components/logging/log_entry_examples/log_entry_examples'; import { TimeRange } from '../../../../../../common/time/time_range'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx index 96c0a23ac755e..0811ec1708530 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx @@ -5,28 +5,27 @@ * 2.0. */ -import React, { useState, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; +import { LogEntry, LogEntryContext } from '@kbn/logs-shared-plugin/common'; +import { + LogEntryColumn, + LogEntryContextMenu, + LogEntryFieldColumn, + LogEntryMessageColumn, + LogEntryRowWrapper, + LogEntryTimestampColumn, +} from '@kbn/logs-shared-plugin/public'; +import { useLinkProps, useUiTracker } from '@kbn/observability-shared-plugin/public'; import { encode } from '@kbn/rison'; import moment from 'moment'; - -import { useUiTracker, useLinkProps } from '@kbn/observability-shared-plugin/public'; -import { LogEntry, LogEntryContext } from '../../../../../../common/log_entry'; -import { TimeRange } from '../../../../../../common/time'; +import React, { useCallback, useState } from 'react'; import { getFriendlyNameForPartitionId, partitionField, } from '../../../../../../common/log_analysis'; +import { TimeRange } from '../../../../../../common/time'; import { useViewLogInProviderContext } from '../../../../../containers/logs/view_log_in_context'; -import { - LogEntryColumn, - LogEntryFieldColumn, - LogEntryMessageColumn, - LogEntryRowWrapper, - LogEntryTimestampColumn, -} from '../../../../../components/logging/log_text_stream'; import { LogColumnConfiguration } from '../../../../../utils/source_configuration'; -import { LogEntryContextMenu } from '../../../../../components/logging/log_text_stream/log_entry_context_menu'; export const exampleMessageScale = 'medium' as const; export const exampleTimestampFormat = 'dateTime' as const; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx index c9f93ee618ddb..6dd07a80c8652 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx @@ -9,7 +9,7 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryCategory } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time'; import { LoadingOverlayWrapper } from '../../../../../components/loading_overlay_wrapper'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx index 3d06a212fe581..f119a08cbd10a 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_table.tsx @@ -12,7 +12,7 @@ import React, { useMemo, useCallback } from 'react'; import useSet from 'react-use/lib/useSet'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { PersistedLogViewReference } from '../../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryCategory, LogEntryCategoryDataset, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts index db17c0b866b7b..14e7ebfbebd35 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryCategoryDatasetsRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts index a27e734235c3b..3e4947ca1e84f 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryCategoryExamplesRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts index 5104ad897c880..c4a1b6d095a29 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryCategoriesRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts index 7ef8d57b29d9f..20f7adb106857 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts @@ -7,7 +7,7 @@ import { useMemo, useState } from 'react'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { GetLogEntryCategoriesSuccessResponsePayload, GetLogEntryCategoryDatasetsSuccessResponsePayload, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx index 8152cae426448..c5516fdbc02f9 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx @@ -6,7 +6,7 @@ */ import { useMemo, useState } from 'react'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryCategoryExample } from '../../../../common/http_api'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx index 1f6fe04e59161..533381dcbf7c3 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_content.tsx @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import React, { memo, useCallback, useEffect } from 'react'; import useInterval from 'react-use/lib/useInterval'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { LoadingPage } from '../../../components/loading_page'; import { @@ -24,7 +25,6 @@ import { SubscriptionSplashPage } from '../../../components/subscription_splash_ import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useLogEntryRateModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { LogEntryRateResultsContent } from './page_results_content'; import { LogEntryRateSetupContent } from './page_setup_content'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx index 7e1381cbd4f21..46ce90cff63cc 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; @@ -13,7 +14,6 @@ import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_a import { LogEntryRateModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; import { LogEntryFlyoutProvider } from '../../../containers/logs/log_flyout'; import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx index b535c1fd155de..a4d861e38ade1 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx @@ -14,6 +14,7 @@ import { encode } from '@kbn/rison'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { MLJobsAwaitingNodeWarning } from '@kbn/ml-plugin/public'; import { useTrackPageview } from '@kbn/observability-shared-plugin/public'; +import { useLogViewContext, LogEntryFlyout } from '@kbn/logs-shared-plugin/public'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { TimeKey } from '../../../../common/time'; import { @@ -23,12 +24,10 @@ import { import { DatasetsSelector } from '../../../components/logging/log_analysis_results/datasets_selector'; import { ManageJobsButton } from '../../../components/logging/log_analysis_setup/manage_jobs_button'; import { useLogAnalysisSetupFlyoutStateContext } from '../../../components/logging/log_analysis_setup/setup_flyout'; -import { LogEntryFlyout } from '../../../components/logging/log_entry_flyout'; import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis/log_analysis_capabilities'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useLogEntryRateModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; import { useLogEntryFlyoutContext } from '../../../containers/logs/log_flyout'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { LogsPageTemplate } from '../shared/page_template'; import { AnomaliesResults } from './sections/anomalies'; import { useDatasetFiltering } from './use_dataset_filtering'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx index 493b5c4077c69..5fe150e3c2724 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx @@ -11,10 +11,10 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import useMount from 'react-use/lib/useMount'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { isCategoryAnomaly, LogEntryAnomaly } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time/time_range'; import { LogEntryExampleMessages } from '../../../../../components/logging/log_entry_examples/log_entry_examples'; -import { useLogViewContext } from '../../../../../hooks/use_log_view'; import { useLogEntryExamples } from '../../use_log_entry_examples'; import { LogEntryExampleMessage, LogEntryExampleMessageHeaders } from './log_entry_example'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx index 5b23f5f9e2a45..288fc3df39c8e 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx @@ -12,8 +12,6 @@ import { i18n } from '@kbn/i18n'; import { useMlHref, ML_PAGES } from '@kbn/ml-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { useLinkProps, shouldHandleLinkEvent } from '@kbn/observability-shared-plugin/public'; -import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana'; -import { getFriendlyNameForPartitionId } from '../../../../../../common/log_analysis'; import { LogEntryColumn, LogEntryFieldColumn, @@ -23,11 +21,11 @@ import { LogEntryContextMenu, LogEntryColumnWidths, iconColumnId, -} from '../../../../../components/logging/log_text_stream'; -import { LogColumnHeadersWrapper, LogColumnHeader, -} from '../../../../../components/logging/log_text_stream/column_headers'; +} from '@kbn/logs-shared-plugin/public'; +import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana'; +import { getFriendlyNameForPartitionId } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time/time_range'; import { partitionField } from '../../../../../../common/log_analysis/job_parameters'; import { LogEntryExample, isCategoryAnomaly } from '../../../../../../common/log_analysis'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts index dc8ab4772473d..b6a515ae6f134 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryAnomaliesRequestPayloadRT, getLogEntryAnomaliesSuccessReponsePayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts index 093a906008582..a93712c5d5a86 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { decodeOrThrow } from '../../../../../common/runtime_types'; import { getLogEntryAnomaliesDatasetsRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts index f6d90692ad470..6cf35b95868e1 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts @@ -6,7 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; -import { PersistedLogViewReference } from '../../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { getLogEntryExamplesRequestPayloadRT, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts index db4fc77964173..745b5a7cd5aec 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts @@ -7,7 +7,7 @@ import { useMemo, useState, useCallback, useEffect, useReducer } from 'react'; import useMount from 'react-use/lib/useMount'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { useTrackedPromise, CanceledPromiseError } from '../../../utils/use_tracked_promise'; import { callGetLogEntryAnomaliesAPI } from './service_calls/get_log_entry_anomalies'; import { callGetLogEntryAnomaliesDatasetsAPI } from './service_calls/get_log_entry_anomalies_datasets'; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts index a678f5deaf07a..4301f08ab41da 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts @@ -6,7 +6,7 @@ */ import { useMemo, useState } from 'react'; -import { PersistedLogViewReference } from '../../../../common/log_views'; +import { PersistedLogViewReference } from '@kbn/logs-shared-plugin/common'; import { LogEntryExample } from '../../../../common/log_analysis'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; diff --git a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx index e185a62ea9646..f4112b7bd0a05 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx @@ -6,21 +6,21 @@ */ import React, { useState } from 'react'; -import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analysis'; -import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; -import { LogViewProvider } from '../../hooks/use_log_view'; import { + LogViewProvider, initializeFromUrl as createInitializeFromUrl, updateContextInUrl as createUpdateContextInUrl, listenForUrlChanges as createListenForUrlChanges, -} from '../../observability_logs/log_view_state/src/url_state_storage_service'; +} from '@kbn/logs-shared-plugin/public'; +import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analysis'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { useKbnUrlStateStorageFromRouterContext } from '../../utils/kbn_url_state_context'; export const LogsPageProviders: React.FunctionComponent = ({ children }) => { const { services: { notifications: { toasts: toastsService }, - logViews: { client }, + logsShared, }, } = useKibanaContextForPlugin(); @@ -38,7 +38,7 @@ export const LogsPageProviders: React.FunctionComponent = ({ children }) => { return ( { return ( - + {({ buckets, start, end }) => ( )} - + ); }} @@ -293,6 +299,16 @@ export const StreamPageLogsContent = React.memo<{ ); }); +const WithSummaryAndQuery = (props: Omit) => { + const serializedParsedQuery = useSelector(useLogStreamPageStateContext(), (logStreamPageState) => + logStreamPageState.matches({ hasLogViewIndices: 'initialized' }) + ? stringify(logStreamPageState.context.parsedQuery) + : null + ); + + return ; +}; + type InitializedLogStreamPageState = MatchedStateFromActor< LogStreamPageActorRef, { hasLogViewIndices: 'initialized' } diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx index 0a9f5ae9395e3..9b058bd03acd3 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx @@ -7,20 +7,21 @@ import stringify from 'json-stable-stringify'; import React, { useMemo } from 'react'; +import { + LogHighlightsStateProvider, + LogPositionStateProvider, + LogStreamProvider, + useLogPositionStateContext, + useLogStreamContext, + useLogViewContext, +} from '@kbn/logs-shared-plugin/public'; import { LogStreamPageActorRef, LogStreamPageCallbacks, } from '../../../observability_logs/log_stream_page/state'; import { LogEntryFlyoutProvider } from '../../../containers/logs/log_flyout'; -import { LogHighlightsStateProvider } from '../../../containers/logs/log_highlights/log_highlights'; -import { - LogPositionStateProvider, - useLogPositionStateContext, -} from '../../../containers/logs/log_position'; -import { LogStreamProvider, useLogStreamContext } from '../../../containers/logs/log_stream'; import { LogViewConfigurationProvider } from '../../../containers/logs/log_view_configuration'; import { ViewLogInContextProvider } from '../../../containers/logs/view_log_in_context'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { MatchedStateFromActor } from '../../../observability_logs/xstate_helpers'; const ViewLogInContext: React.FC = ({ children }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx index 99c9d498fc6cc..9ea8e60eef0b9 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx @@ -8,15 +8,17 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useMemo } from 'react'; +import { + useLogHighlightsStateContext, + useLogPositionStateContext, + useLogViewContext, +} from '@kbn/logs-shared-plugin/public'; import { LogCustomizationMenu } from '../../../components/logging/log_customization_menu'; import { LogHighlightsMenu } from '../../../components/logging/log_highlights_menu'; import { LogTextScaleControls } from '../../../components/logging/log_text_scale_controls'; import { LogTextWrapControls } from '../../../components/logging/log_text_wrap_controls'; -import { useLogHighlightsStateContext } from '../../../containers/logs/log_highlights/log_highlights'; -import { useLogPositionStateContext } from '../../../containers/logs/log_position'; import { useLogViewConfigurationContext } from '../../../containers/logs/log_view_configuration'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; -import { useLogViewContext } from '../../../hooks/use_log_view'; import { StreamLiveButton } from './components/stream_live_button'; export const LogsToolbar = () => { diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx index 15dbbcca7ce9f..2917b7b21d78f 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx @@ -17,10 +17,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { isEmpty } from 'lodash'; import React, { useCallback, useMemo } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { LogEntry } from '../../../../common/log_entry'; +import { LogEntry } from '@kbn/logs-shared-plugin/common'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { useViewLogInProviderContext } from '../../../containers/logs/view_log_in_context'; import { useViewportDimensions } from '../../../utils/use_viewport_dimensions'; -import { LogStream } from '../../../components/log_stream'; const MODAL_MARGIN = 25; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx index ac3981026ea8e..cd2537418e46c 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_link_to_stream.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; import { EuiButtonEmpty } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { LogViewReference } from '../../../../../../../common/log_views'; +import { LogViewReference } from '@kbn/logs-shared-plugin/common'; import { useKibanaContextForPlugin } from '../../../../../../hooks/use_kibana'; interface LogsLinkToStreamProps { diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx index 6fe796d33e909..66cbc9d1c1b1b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx @@ -8,8 +8,8 @@ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { InfraLoadingPanel } from '../../../../../../components/loading'; -import { LogStream } from '../../../../../../components/log_stream'; import { useHostsViewContext } from '../../../hooks/use_hosts_view'; import { useUnifiedSearchContext } from '../../../hooks/use_unified_search'; import { useLogsSearchUrlState } from '../../../hooks/use_logs_search_url_state'; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts index 7335855189526..46a062001bb74 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts @@ -8,8 +8,8 @@ // import { useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { v4 as uuidv4 } from 'uuid'; +import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common'; import { useLazyRef } from '../../../../hooks/use_lazy_ref'; -import { DEFAULT_LOG_VIEW, type LogViewReference } from '../../../../../common/log_views'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; interface Props { @@ -18,13 +18,11 @@ interface Props { } export const useLogViewReference = ({ id, extraFields = [] }: Props) => { const { - services: { - logViews: { client }, - }, + services: { logsShared }, } = useKibanaContextForPlugin(); const { loading, value: defaultLogView } = useAsync( - () => client.getLogView(DEFAULT_LOG_VIEW), + () => logsShared.logViews.client.getLogView(DEFAULT_LOG_VIEW), [] ); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx index 3024ff3d1bd06..ddbf4ae52788b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx @@ -14,9 +14,9 @@ import { EuiFlexGroup } from '@elastic/eui'; import { EuiFlexItem } from '@elastic/eui'; import { EuiButtonEmpty } from '@elastic/eui'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; +import { LogStream } from '@kbn/logs-shared-plugin/public'; import { useKibanaContextForPlugin } from '../../../../../../hooks/use_kibana'; import { TabContent, TabProps } from './shared'; -import { LogStream } from '../../../../../../components/log_stream'; import { useWaffleOptionsContext } from '../../../hooks/use_waffle_options'; import { findInventoryFields } from '../../../../../../../common/inventory_models'; diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts index 73b09017fecc0..9b48b9391f9bd 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts @@ -13,7 +13,7 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { replaceStateKeyInQueryString } from '../../../../../common/log_views'; +import { replaceStateKeyInQueryString } from '../../../../../common/url_state_storage_service'; import { useUrlState } from '../../../../utils/use_url_state'; const parseRange = (range: MetricsTimeInput) => { diff --git a/x-pack/plugins/infra/public/plugin.ts b/x-pack/plugins/infra/public/plugin.ts index 36c873c3b22df..7ea1dbdfa7cd2 100644 --- a/x-pack/plugins/infra/public/plugin.ts +++ b/x-pack/plugins/infra/public/plugin.ts @@ -19,7 +19,6 @@ import { ObservabilityTriggerId } from '@kbn/observability-shared-plugin/common' import { BehaviorSubject, combineLatest, from } from 'rxjs'; import { map } from 'rxjs/operators'; import { DISCOVER_APP_TARGET, LOGS_APP_TARGET } from '../common/constants'; -import { defaultLogViewsStaticConfig } from '../common/log_views'; import { InfraPublicConfig } from '../common/plugin_config_types'; import { createInventoryMetricRuleType } from './alerting/inventory'; import { createLogThresholdRuleType } from './alerting/log_threshold'; @@ -39,7 +38,6 @@ import { import { createMetricsFetchData, createMetricsHasData } from './metrics_overview_fetchers'; import { registerFeatures } from './register_feature'; import { InventoryViewsService } from './services/inventory_views'; -import { LogViewsService } from './services/log_views'; import { MetricsExplorerViewsService } from './services/metrics_explorer_views'; import { TelemetryService } from './services/telemetry'; import { @@ -56,7 +54,6 @@ import { getLogsHasDataFetcher, getLogsOverviewDataFetcher } from './utils/logs_ export class Plugin implements InfraClientPluginClass { public config: InfraPublicConfig; private inventoryViews: InventoryViewsService; - private logViews: LogViewsService; private metricsExplorerViews: MetricsExplorerViewsService; private telemetry: TelemetryService; private locators?: InfraLocators; @@ -68,10 +65,6 @@ export class Plugin implements InfraClientPluginClass { this.config = context.config.get(); this.inventoryViews = new InventoryViewsService(); - this.logViews = new LogViewsService({ - messageFields: - this.config.sources?.default?.fields?.message ?? defaultLogViewsStaticConfig.messageFields, - }); this.metricsExplorerViews = new MetricsExplorerViewsService(); this.telemetry = new TelemetryService(); this.appTarget = this.config.logs.app_target; @@ -106,6 +99,10 @@ export class Plugin implements InfraClientPluginClass { fetchData: createMetricsFetchData(core.getStartServices), }); + pluginsSetup.logsShared.logViews.setLogViewsStaticConfig({ + messageFields: this.config.sources?.default?.fields?.message, + }); + const startDep$AndHostViewFlag$ = combineLatest([ from(core.getStartServices()), core.uiSettings.get$(enableInfrastructureHostsView), @@ -342,12 +339,6 @@ export class Plugin implements InfraClientPluginClass { http: core.http, }); - const logViews = this.logViews.start({ - http: core.http, - dataViews: plugins.dataViews, - search: plugins.data.search, - }); - const metricsExplorerViews = this.metricsExplorerViews.start({ http: core.http, }); @@ -356,7 +347,6 @@ export class Plugin implements InfraClientPluginClass { const startContract: InfraClientStartExports = { inventoryViews, - logViews, metricsExplorerViews, telemetry, locators: this.locators!, diff --git a/x-pack/plugins/infra/public/test_utils/entries.ts b/x-pack/plugins/infra/public/test_utils/entries.ts index 4dc3732fd49d5..35dad808cdf4f 100644 --- a/x-pack/plugins/infra/public/test_utils/entries.ts +++ b/x-pack/plugins/infra/public/test_utils/entries.ts @@ -6,16 +6,7 @@ */ import faker from 'faker'; -import { LogEntry } from '../../common/log_entry'; -import { LogViewColumnConfiguration } from '../../common/log_views'; - -export const ENTRIES_EMPTY = { - data: { - entries: [], - topCursor: null, - bottomCursor: null, - }, -}; +import { LogEntry, LogViewColumnConfiguration } from '@kbn/logs-shared-plugin/common'; export function generateFakeEntries( count: number, diff --git a/x-pack/plugins/infra/public/types.ts b/x-pack/plugins/infra/public/types.ts index 5c78c1534a5a4..488d92573e746 100644 --- a/x-pack/plugins/infra/public/types.ts +++ b/x-pack/plugins/infra/public/types.ts @@ -38,6 +38,10 @@ import type { ChartsPluginStart } from '@kbn/charts-plugin/public'; import { CasesUiStart } from '@kbn/cases-plugin/public'; import { DiscoverStart } from '@kbn/discover-plugin/public'; import { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import { + LogsSharedClientSetupExports, + LogsSharedClientStartExports, +} from '@kbn/logs-shared-plugin/public'; import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { UnwrapPromise } from '../common/utility_types'; @@ -46,7 +50,6 @@ import type { UseNodeMetricsTableOptions, } from './components/infrastructure_node_metrics_tables/shared'; import { InventoryViewsServiceStart } from './services/inventory_views'; -import { LogViewsServiceStart } from './services/log_views'; import { MetricsExplorerViewsServiceStart } from './services/metrics_explorer_views'; import { ITelemetryClient } from './services/telemetry'; import type { InfraLocators } from '../common/locators'; @@ -58,7 +61,6 @@ export interface InfraClientSetupExports { export interface InfraClientStartExports { inventoryViews: InventoryViewsServiceStart; - logViews: LogViewsServiceStart; metricsExplorerViews: MetricsExplorerViewsServiceStart; telemetry: ITelemetryClient; locators: InfraLocators; @@ -74,6 +76,7 @@ export interface InfraClientStartExports { } export interface InfraClientSetupDeps { + logsShared: LogsSharedClientSetupExports; home?: HomePublicPluginSetup; observability: ObservabilityPublicSetup; observabilityShared: ObservabilitySharedPluginSetup; @@ -97,6 +100,7 @@ export interface InfraClientStartDeps { embeddable?: EmbeddableStart; kibanaVersion?: string; lens: LensPublicStart; + logsShared: LogsSharedClientStartExports; ml: MlPluginStart; observability: ObservabilityPublicStart; observabilityShared: ObservabilitySharedPluginStart; diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts index 5ebacc0e7773b..186e4c9bc1ed0 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts @@ -12,7 +12,7 @@ import { FetchDataParams, LogsFetchDataResponse, } from '@kbn/observability-plugin/public'; -import { DEFAULT_LOG_VIEW } from '../../common/log_views'; +import { DEFAULT_LOG_VIEW } from '@kbn/logs-shared-plugin/common'; import { TIMESTAMP_FIELD } from '../../common/constants'; import { InfraClientStartDeps, InfraClientStartServicesAccessor } from '../types'; @@ -38,9 +38,11 @@ type StatsAndSeries = Pick; export function getLogsHasDataFetcher(getStartServices: InfraClientStartServicesAccessor) { return async () => { - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); - const logViewStatus = await logViews.client.getResolvedLogViewStatus(resolvedLogView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); + const logViewStatus = await logsShared.logViews.client.getResolvedLogViewStatus( + resolvedLogView + ); const hasData = logViewStatus.index === 'available'; const indices = resolvedLogView.indices; @@ -56,8 +58,8 @@ export function getLogsOverviewDataFetcher( getStartServices: InfraClientStartServicesAccessor ): FetchData { return async (params) => { - const [, { data }, { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); + const [, { data, logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); const { stats, series } = await fetchLogsOverview( { diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts index dad3dedc4bb46..85d7f14586913 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts @@ -6,10 +6,11 @@ */ import { CoreStart } from '@kbn/core/public'; -import { of } from 'rxjs'; import { coreMock } from '@kbn/core/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; -import { createResolvedLogViewMock } from '../../common/log_views/resolved_log_view.mock'; +import { createResolvedLogViewMock } from '@kbn/logs-shared-plugin/common/mocks'; +import { createLogsSharedPluginStartMock } from '@kbn/logs-shared-plugin/public/mocks'; +import { of } from 'rxjs'; import { createInfraPluginStartMock } from '../mocks'; import { InfraClientStartDeps, InfraClientStartExports } from '../types'; import { getLogsHasDataFetcher, getLogsOverviewDataFetcher } from './logs_overview_fetchers'; @@ -24,10 +25,18 @@ const DEFAULT_PARAMS = { function setup() { const core = coreMock.createStart(); const data = dataPluginMock.createStartContract(); + const logsShared = createLogsSharedPluginStartMock(); const pluginStart = createInfraPluginStartMock(); - const pluginDeps = { data } as InfraClientStartDeps; + const pluginDeps = { data, logsShared } as unknown as InfraClientStartDeps; const dataSearch = data.search.search as jest.MockedFunction; + const getResolvedLogView = logsShared.logViews.client.getResolvedLogView as jest.MockedFunction< + typeof logsShared.logViews.client.getResolvedLogView + >; + const getResolvedLogViewStatus = logsShared.logViews.client + .getResolvedLogViewStatus as jest.MockedFunction< + typeof logsShared.logViews.client.getResolvedLogViewStatus + >; const mockedGetStartServices = jest.fn(() => Promise.resolve<[CoreStart, InfraClientStartDeps, InfraClientStartExports]>([ @@ -36,7 +45,15 @@ function setup() { pluginStart, ]) ); - return { core, dataSearch, mockedGetStartServices, pluginStart }; + return { + core, + dataSearch, + mockedGetStartServices, + pluginDeps, + pluginStart, + getResolvedLogView, + getResolvedLogViewStatus, + }; } describe('Logs UI Observability Homepage Functions', () => { @@ -46,62 +63,59 @@ describe('Logs UI Observability Homepage Functions', () => { describe('getLogsHasDataFetcher()', () => { it('should return true when non-empty indices exist', async () => { - const { mockedGetStartServices, pluginStart } = setup(); + const { mockedGetStartServices, pluginDeps, getResolvedLogView, getResolvedLogViewStatus } = + setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue( - createResolvedLogViewMock({ indices: 'test-index' }) - ); - pluginStart.logViews.client.getResolvedLogViewStatus.mockResolvedValue({ - index: 'available', - }); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock({ indices: 'test-index' })); + getResolvedLogViewStatus.mockResolvedValue({ index: 'available' }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(pluginStart.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes(1); + expect(pluginDeps.logsShared.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes( + 1 + ); expect(response).toEqual({ hasData: true, indices: 'test-index' }); }); it('should return false when only empty indices exist', async () => { - const { mockedGetStartServices, pluginStart } = setup(); + const { mockedGetStartServices, pluginDeps, getResolvedLogView, getResolvedLogViewStatus } = + setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue( - createResolvedLogViewMock({ indices: 'test-index' }) - ); - pluginStart.logViews.client.getResolvedLogViewStatus.mockResolvedValue({ - index: 'empty', - }); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock({ indices: 'test-index' })); + getResolvedLogViewStatus.mockResolvedValue({ index: 'empty' }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(pluginStart.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes(1); + expect(pluginDeps.logsShared.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes( + 1 + ); expect(response).toEqual({ hasData: false, indices: 'test-index' }); }); it('should return false when no index exists', async () => { - const { mockedGetStartServices, pluginStart } = setup(); + const { mockedGetStartServices, pluginDeps, getResolvedLogView, getResolvedLogViewStatus } = + setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue( - createResolvedLogViewMock({ indices: 'test-index' }) - ); - pluginStart.logViews.client.getResolvedLogViewStatus.mockResolvedValue({ - index: 'missing', - }); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock({ indices: 'test-index' })); + getResolvedLogViewStatus.mockResolvedValue({ index: 'missing' }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(pluginStart.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes(1); + expect(pluginDeps.logsShared.logViews.client.getResolvedLogViewStatus).toHaveBeenCalledTimes( + 1 + ); expect(response).toEqual({ hasData: false, indices: 'test-index' }); }); }); describe('getLogsOverviewDataFetcher()', () => { it('should work', async () => { - const { mockedGetStartServices, dataSearch, pluginStart } = setup(); + const { mockedGetStartServices, dataSearch, getResolvedLogView } = setup(); - pluginStart.logViews.client.getResolvedLogView.mockResolvedValue(createResolvedLogViewMock()); + getResolvedLogView.mockResolvedValue(createResolvedLogViewMock()); dataSearch.mockReturnValue( of({ diff --git a/x-pack/plugins/infra/public/utils/url_state.tsx b/x-pack/plugins/infra/public/utils/url_state.tsx index 8fc4961bba221..a07b8afbc68f8 100644 --- a/x-pack/plugins/infra/public/utils/url_state.tsx +++ b/x-pack/plugins/infra/public/utils/url_state.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { Route } from '@kbn/shared-ux-router'; import { decode, RisonValue } from '@kbn/rison'; import { throttle } from 'lodash'; -import { replaceStateKeyInQueryString } from '../../common/log_views'; +import { replaceStateKeyInQueryString } from '../../common/url_state_storage_service'; interface UrlStateContainerProps { urlState: UrlState | undefined; diff --git a/x-pack/plugins/infra/public/utils/use_url_state.ts b/x-pack/plugins/infra/public/utils/use_url_state.ts index 3d269f9eb058c..8fc03d2d9dda2 100644 --- a/x-pack/plugins/infra/public/utils/use_url_state.ts +++ b/x-pack/plugins/infra/public/utils/use_url_state.ts @@ -10,7 +10,7 @@ import { Location } from 'history'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { decode, RisonValue } from '@kbn/rison'; import { useHistory } from 'react-router-dom'; -import { replaceStateKeyInQueryString } from '../../common/log_views'; +import { replaceStateKeyInQueryString } from '../../common/url_state_storage_service'; export const useUrlState = ({ defaultState, diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index a1b1a7b729193..e9fec4a5b4f5d 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; +import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server'; import { LOG_DOCUMENT_COUNT_RULE_TYPE_ID } from '../common/alerting/logs/log_threshold/types'; import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, @@ -14,7 +15,6 @@ import { } from '../common/alerting/metrics'; import { LOGS_FEATURE_ID, METRICS_FEATURE_ID } from '../common/constants'; import { infraSourceConfigurationSavedObjectName } from './lib/sources/saved_object_type'; -import { logViewSavedObjectName } from './saved_objects'; export const METRICS_FEATURE = { id: METRICS_FEATURE_ID, diff --git a/x-pack/plugins/infra/server/infra_server.ts b/x-pack/plugins/infra/server/infra_server.ts index 4d29974ceb75f..e54713faba76a 100644 --- a/x-pack/plugins/infra/server/infra_server.ts +++ b/x-pack/plugins/infra/server/infra_server.ts @@ -22,12 +22,6 @@ import { initValidateLogAnalysisDatasetsRoute, initValidateLogAnalysisIndicesRoute, } from './routes/log_analysis'; -import { - initLogEntriesHighlightsRoute, - initLogEntriesSummaryHighlightsRoute, - initLogEntriesSummaryRoute, -} from './routes/log_entries'; -import { initLogViewRoutes } from './routes/log_views'; import { initMetadataRoute } from './routes/metadata'; import { initMetricsAPIRoute } from './routes/metrics_api'; import { initMetricExplorerRoute } from './routes/metrics_explorer'; @@ -55,10 +49,6 @@ export const initInfraServer = (libs: InfraBackendLibs) => { initValidateLogAnalysisDatasetsRoute(libs); initValidateLogAnalysisIndicesRoute(libs); initGetLogEntryExamplesRoute(libs); - initLogEntriesHighlightsRoute(libs); - initLogEntriesSummaryRoute(libs); - initLogEntriesSummaryHighlightsRoute(libs); - initLogViewRoutes(libs); initMetricExplorerRoute(libs); initMetricsExplorerViewRoutes(libs); initMetricsAPIRoute(libs); diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts index 22351750fbab4..61c8b935806ac 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts @@ -24,6 +24,7 @@ import { PluginSetupContract as AlertingPluginContract } from '@kbn/alerting-plu import { MlPluginSetup } from '@kbn/ml-plugin/server'; import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/server'; import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; +import { LogsSharedPluginSetup, LogsSharedPluginStart } from '@kbn/logs-shared-plugin/server'; import { VersionedRouteConfig } from '@kbn/core-http-server'; export interface InfraServerPluginSetupDeps { @@ -38,11 +39,13 @@ export interface InfraServerPluginSetupDeps { usageCollection: UsageCollectionSetup; visTypeTimeseries: VisTypeTimeseriesSetup; ml?: MlPluginSetup; + logsShared: LogsSharedPluginSetup; } export interface InfraServerPluginStartDeps { data: DataPluginStart; dataViews: DataViewsPluginStart; + logsShared: LogsSharedPluginStart; } export interface CallWithRequestParams extends estypes.RequestBase { diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts index 0860da5c7a184..d0a301726138e 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.test.ts @@ -29,6 +29,7 @@ import { createInventoryMetricThresholdExecutor } from './inventory_metric_thres import { ConditionResult } from './evaluate_condition'; import { InfraBackendLibs } from '../../infra_types'; import { infraPluginMock } from '../../../mocks'; +import { logsSharedPluginMock } from '@kbn/logs-shared-plugin/server/mocks'; jest.mock('./evaluate_condition', () => ({ evaluateCondition: jest.fn() })); @@ -121,7 +122,7 @@ const mockLibs = { }, getStartServices: () => [ null, - infraPluginMock.createSetupContract(), + { logsShared: logsSharedPluginMock.createStartContract() }, infraPluginMock.createStartContract(), ], configuration: createMockStaticConfiguration({}), diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index 5a1dba9faae14..0754c79a99688 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -162,8 +162,8 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = } const source = await libs.sources.getSourceConfiguration(savedObjectsClient, sourceId); - const [, , { logViews }] = await libs.getStartServices(); - const logQueryFields: LogQueryFields | undefined = await logViews + const [, { logsShared }] = await libs.getStartServices(); + const logQueryFields: LogQueryFields | undefined = await logsShared.logViews .getClient(savedObjectsClient, esClient) .getResolvedLogView({ type: 'log-view-reference', diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts index 97c43ea578e73..f54334ef22e5c 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { ResolvedLogView } from '@kbn/logs-shared-plugin/common'; import { ExecutionTimeRange, GroupedSearchQueryResponse, @@ -19,7 +20,6 @@ import { Point, Series, } from '../../../../common/http_api'; -import { ResolvedLogView } from '../../../../common/log_views'; import { decodeOrThrow } from '../../../../common/runtime_types'; import type { InfraPluginRequestHandlerContext } from '../../../types'; import { KibanaFramework } from '../../adapters/framework/kibana_framework_adapter'; diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index 7091fc62a2bba..9b93e021ae8f1 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -201,12 +201,12 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => return alert; }; - const [, , { logViews }] = await libs.getStartServices(); + const [, { logsShared }] = await libs.getStartServices(); try { const validatedParams = decodeOrThrow(ruleParamsRT)(params); - const { indices, timestampField, runtimeMappings } = await logViews + const { indices, timestampField, runtimeMappings } = await logsShared.logViews .getClient(savedObjectsClient, scopedClusterClient.asCurrentUser) .getResolvedLogView(validatedParams.logView); diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts index 7a44311b40fcd..12b67b6f260e4 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_references_manager.ts @@ -6,9 +6,9 @@ */ import type { SavedObjectReference } from '@kbn/core-saved-objects-common'; -import { logViewSavedObjectName } from '../../../saved_objects'; +import { logViewReferenceRT } from '@kbn/logs-shared-plugin/common'; +import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server'; import { RuleParams, ruleParamsRT } from '../../../../common/alerting/logs/log_threshold'; -import { logViewReferenceRT } from '../../../../common/log_views'; import { decodeOrThrow } from '../../../../common/runtime_types'; export const LOG_VIEW_REFERENCE_NAME = 'log-view-reference-0'; diff --git a/x-pack/plugins/infra/server/lib/infra_types.ts b/x-pack/plugins/infra/server/lib/infra_types.ts index f9fe976f692a5..e31bad1b5ffeb 100644 --- a/x-pack/plugins/infra/server/lib/infra_types.ts +++ b/x-pack/plugins/infra/server/lib/infra_types.ts @@ -10,18 +10,18 @@ import type { IBasePath } from '@kbn/core/server'; import type { handleEsError } from '@kbn/es-ui-shared-plugin/server'; import type { AlertsLocatorParams } from '@kbn/observability-plugin/common'; import type { LocatorPublic } from '@kbn/share-plugin/common'; +import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server'; import { RulesServiceSetup } from '../services/rules'; import { InfraConfig, InfraPluginStartServicesAccessor } from '../types'; import { KibanaFramework } from './adapters/framework/kibana_framework_adapter'; import { InfraFieldsDomain } from './domains/fields_domain'; -import { InfraLogEntriesDomain } from './domains/log_entries_domain'; import { InfraMetricsDomain } from './domains/metrics_domain'; import { InfraSources } from './sources'; import { InfraSourceStatus } from './source_status'; export interface InfraDomainLibs { fields: InfraFieldsDomain; - logEntries: InfraLogEntriesDomain; + logEntries: ILogsSharedLogEntriesDomain; metrics: InfraMetricsDomain; } diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts index b17afa68d2d4d..591376450be38 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts @@ -6,6 +6,7 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { PersistedLogViewReference, ResolvedLogView } from '@kbn/logs-shared-plugin/common'; import { AnomaliesSort, getJobId, @@ -16,7 +17,6 @@ import { logEntryRateJobTypes, Pagination, } from '../../../common/log_analysis'; -import { PersistedLogViewReference, ResolvedLogView } from '../../../common/log_views'; import { startTracingSpan, TracingSpan } from '../../../common/performance_tracing'; import { decodeOrThrow } from '../../../common/runtime_types'; import type { diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts index d8eb18e4890b5..88678f4c79c53 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts @@ -7,6 +7,11 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ElasticsearchClient } from '@kbn/core/server'; +import { + LogEntryContext, + PersistedLogViewReference, + ResolvedLogView, +} from '@kbn/logs-shared-plugin/common'; import { CategoriesSort, compareDatasetsByMaximumAnomalyScore, @@ -14,8 +19,6 @@ import { jobCustomSettingsRT, logEntryCategoriesJobTypes, } from '../../../common/log_analysis'; -import { LogEntryContext } from '../../../common/log_entry'; -import { PersistedLogViewReference, ResolvedLogView } from '../../../common/log_views'; import { startTracingSpan } from '../../../common/performance_tracing'; import { decodeOrThrow } from '../../../common/runtime_types'; import type { MlAnomalyDetectors, MlSystem } from '../../types'; diff --git a/x-pack/plugins/infra/server/mocks.ts b/x-pack/plugins/infra/server/mocks.ts index 7e5a349cb1e01..a15575572a076 100644 --- a/x-pack/plugins/infra/server/mocks.ts +++ b/x-pack/plugins/infra/server/mocks.ts @@ -5,18 +5,21 @@ * 2.0. */ -import { createInventoryViewsServiceStartMock } from './services/inventory_views/inventory_views_service.mock'; import { - createLogViewsServiceSetupMock, - createLogViewsServiceStartMock, -} from './services/log_views/log_views_service.mock'; -import { createMetricsExplorerViewsServiceStartMock } from './services/metrics_explorer_views/metrics_explorer_views_service.mock'; + createInventoryViewsServiceSetupMock, + createInventoryViewsServiceStartMock, +} from './services/inventory_views/inventory_views_service.mock'; +import { + createMetricsExplorerViewsServiceSetupMock, + createMetricsExplorerViewsServiceStartMock, +} from './services/metrics_explorer_views/metrics_explorer_views_service.mock'; import { InfraPluginSetup, InfraPluginStart } from './types'; const createInfraSetupMock = () => { const infraSetupMock: jest.Mocked = { defineInternalSourceConfiguration: jest.fn(), - logViews: createLogViewsServiceSetupMock(), + inventoryViews: createInventoryViewsServiceSetupMock(), + metricsExplorerViews: createMetricsExplorerViewsServiceSetupMock(), }; return infraSetupMock; @@ -26,7 +29,6 @@ const createInfraStartMock = () => { const infraStartMock: jest.Mocked = { getMetricIndices: jest.fn(), inventoryViews: createInventoryViewsServiceStartMock(), - logViews: createLogViewsServiceStartMock(), metricsExplorerViews: createMetricsExplorerViewsServiceStartMock(), }; return infraStartMock; diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index 04fea926a2083..2449293dfa3aa 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -24,7 +24,6 @@ import { LOGS_FEATURE_ID, METRICS_FEATURE_ID, } from '../common/constants'; -import { defaultLogViewsStaticConfig } from '../common/log_views'; import { publicConfigKeys } from '../common/plugin_config_types'; import { configDeprecations, getInfraDeprecationsFactory } from './deprecations'; import { LOGS_FEATURE, METRICS_FEATURE } from './features'; @@ -32,7 +31,6 @@ import { initInfraServer } from './infra_server'; import { FrameworkFieldsAdapter } from './lib/adapters/fields/framework_fields_adapter'; import { InfraServerPluginSetupDeps, InfraServerPluginStartDeps } from './lib/adapters/framework'; import { KibanaFramework } from './lib/adapters/framework/kibana_framework_adapter'; -import { InfraKibanaLogEntriesAdapter } from './lib/adapters/log_entries/kibana_log_entries_adapter'; import { KibanaMetricsAdapter } from './lib/adapters/metrics/kibana_metrics_adapter'; import { InfraElasticsearchSourceStatusAdapter } from './lib/adapters/source_status'; import { registerRuleTypes } from './lib/alerting'; @@ -41,20 +39,13 @@ import { METRICS_RULES_ALERT_CONTEXT, } from './lib/alerting/register_rule_types'; import { InfraFieldsDomain } from './lib/domains/fields_domain'; -import { InfraLogEntriesDomain } from './lib/domains/log_entries_domain'; import { InfraMetricsDomain } from './lib/domains/metrics_domain'; import { InfraBackendLibs, InfraDomainLibs } from './lib/infra_types'; import { makeGetMetricIndices } from './lib/metrics/make_get_metric_indices'; import { infraSourceConfigurationSavedObjectType, InfraSources } from './lib/sources'; import { InfraSourceStatus } from './lib/source_status'; -import { - inventoryViewSavedObjectType, - logViewSavedObjectType, - metricsExplorerViewSavedObjectType, -} from './saved_objects'; +import { inventoryViewSavedObjectType, metricsExplorerViewSavedObjectType } from './saved_objects'; import { InventoryViewsService } from './services/inventory_views'; -import { LogEntriesService } from './services/log_entries'; -import { LogViewsService } from './services/log_views'; import { MetricsExplorerViewsService } from './services/metrics_explorer_views'; import { RulesService } from './services/rules'; import { @@ -65,6 +56,7 @@ import { InfraPluginStart, } from './types'; import { UsageCollector } from './usage/usage_collector'; +import { mapSourceToLogView } from './utils/map_source_to_log_view'; export const config: PluginConfigDescriptor = { schema: schema.object({ @@ -138,7 +130,6 @@ export class InfraServerPlugin private logsRules: RulesService; private metricsRules: RulesService; private inventoryViews: InventoryViewsService; - private logViews: LogViewsService; private metricsExplorerViews: MetricsExplorerViewsService; constructor(context: PluginInitializerContext) { @@ -157,7 +148,6 @@ export class InfraServerPlugin ); this.inventoryViews = new InventoryViewsService(this.logger.get('inventoryViews')); - this.logViews = new LogViewsService(this.logger.get('logViews')); this.metricsExplorerViews = new MetricsExplorerViewsService( this.logger.get('metricsExplorerViews') ); @@ -170,18 +160,16 @@ export class InfraServerPlugin }); const sourceStatus = new InfraSourceStatus( new InfraElasticsearchSourceStatusAdapter(framework), - { - sources, - } + { sources } ); + + // Setup infra services const inventoryViews = this.inventoryViews.setup(); - const logViews = this.logViews.setup(); const metricsExplorerViews = this.metricsExplorerViews.setup(); - // register saved object types + // Register saved object types core.savedObjects.registerType(infraSourceConfigurationSavedObjectType); core.savedObjects.registerType(inventoryViewSavedObjectType); - core.savedObjects.registerType(logViewSavedObjectType); core.savedObjects.registerType(metricsExplorerViewSavedObjectType); // TODO: separate these out individually and do away with "domains" as a temporary group @@ -191,10 +179,7 @@ export class InfraServerPlugin fields: new InfraFieldsDomain(new FrameworkFieldsAdapter(framework), { sources, }), - logEntries: new InfraLogEntriesDomain(new InfraKibanaLogEntriesAdapter(framework), { - framework, - getStartServices: () => core.getStartServices(), - }), + logEntries: plugins.logsShared.logEntries, metrics: new InfraMetricsDomain(new KibanaMetricsAdapter(framework)), }; @@ -216,6 +201,19 @@ export class InfraServerPlugin plugins.features.registerKibanaFeature(METRICS_FEATURE); plugins.features.registerKibanaFeature(LOGS_FEATURE); + // Register an handler to retrieve the fallback logView starting from a source configuration + plugins.logsShared.logViews.registerLogViewFallbackHandler(async (sourceId, { soClient }) => { + const sourceConfiguration = await sources.getSourceConfiguration(soClient, sourceId); + return mapSourceToLogView(sourceConfiguration); + }); + plugins.logsShared.logViews.setLogViewsStaticConfig({ + messageFields: this.config.sources?.default?.fields?.message, + }); + + plugins.logsShared.registerUsageCollectorActions({ + countLogs: () => UsageCollector.countLogs(), + }); + plugins.home.sampleData.addAppLinksToSampleDataset('logs', [ { sampleObject: null, // indicates that there is no sample object associated with this app link's path @@ -247,9 +245,6 @@ export class InfraServerPlugin // Telemetry UsageCollector.registerUsageCollector(plugins.usageCollection); - const logEntriesService = new LogEntriesService(); - logEntriesService.setup(core, plugins); - // register deprecated source configuration fields core.deprecations.registerDeprecations({ getDeprecations: getInfraDeprecationsFactory(sources), @@ -258,29 +253,16 @@ export class InfraServerPlugin return { defineInternalSourceConfiguration: sources.defineInternalSourceConfiguration.bind(sources), inventoryViews, - logViews, metricsExplorerViews, } as InfraPluginSetup; } - start(core: CoreStart, plugins: InfraServerPluginStartDeps) { + start(core: CoreStart) { const inventoryViews = this.inventoryViews.start({ infraSources: this.libs.sources, savedObjects: core.savedObjects, }); - const logViews = this.logViews.start({ - infraSources: this.libs.sources, - savedObjects: core.savedObjects, - dataViews: plugins.dataViews, - elasticsearch: core.elasticsearch, - config: { - messageFields: - this.config.sources?.default?.fields?.message ?? - defaultLogViewsStaticConfig.messageFields, - }, - }); - const metricsExplorerViews = this.metricsExplorerViews.start({ infraSources: this.libs.sources, savedObjects: core.savedObjects, @@ -288,7 +270,6 @@ export class InfraServerPlugin return { inventoryViews, - logViews, metricsExplorerViews, getMetricIndices: makeGetMetricIndices(this.libs.sources), }; diff --git a/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts b/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts index 9a963c3f84e72..1c6be6bf56c28 100644 --- a/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts +++ b/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts @@ -38,8 +38,10 @@ export const initGetLogAlertsChartPreviewDataRoute = ({ data: { logView, buckets, alertParams, executionTimeRange }, } = request.body; - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews + .getScopedClient(request) + .getResolvedLogView(logView); try { const { series } = await getChartPreviewData( diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts index b17a50d23974d..5e9a57768828c 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts @@ -45,8 +45,10 @@ export const initGetLogEntryCategoryExamplesRoute = ({ }, } = request.body; - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews + .getScopedClient(request) + .getResolvedLogView(logView); try { const infraMlContext = await assertHasInfraMlPlugins(requestContext); diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts index 2b413dce7f294..8b3b2f0449c58 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts @@ -46,8 +46,10 @@ export const initGetLogEntryExamplesRoute = ({ }, } = request.body; - const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); + const [, { logsShared }] = await getStartServices(); + const resolvedLogView = await logsShared.logViews + .getScopedClient(request) + .getResolvedLogView(logView); try { const infraMlContext = await assertHasInfraMlPlugins(requestContext); diff --git a/x-pack/plugins/infra/server/routes/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/index.ts index 0c893171b5b67..085be4584e2a7 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/index.ts @@ -40,8 +40,8 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { const soClient = (await requestContext.core).savedObjects.client; const source = await libs.sources.getSourceConfiguration(soClient, snapshotRequest.sourceId); const compositeSize = libs.configuration.inventory.compositeSize; - const [, , { logViews }] = await libs.getStartServices(); - const logQueryFields: LogQueryFields | undefined = await logViews + const [, { logsShared }] = await libs.getStartServices(); + const logQueryFields: LogQueryFields | undefined = await logsShared.logViews .getScopedClient(request) .getResolvedLogView({ type: 'log-view-reference', diff --git a/x-pack/plugins/infra/server/saved_objects/index.ts b/x-pack/plugins/infra/server/saved_objects/index.ts index cf6906fc733f7..c64f4b46808c4 100644 --- a/x-pack/plugins/infra/server/saved_objects/index.ts +++ b/x-pack/plugins/infra/server/saved_objects/index.ts @@ -6,5 +6,4 @@ */ export * from './inventory_view'; -export * from './log_view'; export * from './metrics_explorer_view'; diff --git a/x-pack/plugins/infra/server/types.ts b/x-pack/plugins/infra/server/types.ts index 49dbca9b276b2..0a4ad94c09d43 100644 --- a/x-pack/plugins/infra/server/types.ts +++ b/x-pack/plugins/infra/server/types.ts @@ -14,9 +14,11 @@ import type { SearchRequestHandlerContext } from '@kbn/data-plugin/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; import type { InfraStaticSourceConfiguration } from '../common/source_configuration/source_configuration'; import { InfraServerPluginStartDeps } from './lib/adapters/framework'; -import { InventoryViewsServiceStart } from './services/inventory_views'; -import { LogViewsServiceSetup, LogViewsServiceStart } from './services/log_views/types'; -import { MetricsExplorerViewsServiceStart } from './services/metrics_explorer_views'; +import { InventoryViewsServiceSetup, InventoryViewsServiceStart } from './services/inventory_views'; +import { + MetricsExplorerViewsServiceSetup, + MetricsExplorerViewsServiceStart, +} from './services/metrics_explorer_views'; export type { InfraConfig } from '../common/plugin_config_types'; @@ -28,12 +30,12 @@ export interface InfraPluginSetup { sourceId: string, sourceProperties: InfraStaticSourceConfiguration ) => void; - logViews: LogViewsServiceSetup; + inventoryViews: InventoryViewsServiceSetup; + metricsExplorerViews: MetricsExplorerViewsServiceSetup; } export interface InfraPluginStart { inventoryViews: InventoryViewsServiceStart; - logViews: LogViewsServiceStart; metricsExplorerViews: MetricsExplorerViewsServiceStart; getMetricIndices: ( savedObjectsClient: SavedObjectsClientContract, diff --git a/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts b/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts index e2dbf02ae2d06..20f0aeb2e2f0a 100644 --- a/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts +++ b/x-pack/plugins/infra/server/utils/elasticsearch_runtime_types.ts @@ -17,8 +17,6 @@ export const shardFailureRT = rt.partial({ shard: rt.number, }); -export type ShardFailure = rt.TypeOf; - export const commonSearchSuccessResponseFieldsRT = rt.type({ _shards: rt.intersection([ rt.type({ @@ -34,8 +32,3 @@ export const commonSearchSuccessResponseFieldsRT = rt.type({ timed_out: rt.boolean, took: rt.number, }); - -export const commonHitFieldsRT = rt.type({ - _index: rt.string, - _id: rt.string, -}); diff --git a/x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts b/x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts new file mode 100644 index 0000000000000..38db985a28280 --- /dev/null +++ b/x-pack/plugins/infra/server/utils/map_source_to_log_view.test.ts @@ -0,0 +1,59 @@ +/* + * 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 { InfraSource } from '../lib/sources'; +import { getAttributesFromSourceConfiguration } from './map_source_to_log_view'; + +describe('getAttributesFromSourceConfiguration function', () => { + it('converts the index_pattern log indices type to data_view', () => { + const logViewAttributes = getAttributesFromSourceConfiguration(basicTestSourceConfiguration); + + expect(logViewAttributes.logIndices).toEqual({ + type: 'data_view', + dataViewId: 'INDEX_PATTERN_ID', + }); + }); + + it('preserves the index_name log indices type', () => { + const logViewAttributes = getAttributesFromSourceConfiguration({ + ...basicTestSourceConfiguration, + configuration: { + ...basicTestSourceConfiguration.configuration, + logIndices: { + type: 'index_name', + indexName: 'INDEX_NAME', + }, + }, + }); + + expect(logViewAttributes.logIndices).toEqual({ + type: 'index_name', + indexName: 'INDEX_NAME', + }); + }); +}); + +const basicTestSourceConfiguration: InfraSource = { + id: 'ID', + origin: 'stored', + configuration: { + name: 'NAME', + description: 'DESCRIPTION', + logIndices: { + type: 'index_pattern', + indexPatternId: 'INDEX_PATTERN_ID', + }, + logColumns: [], + fields: { + message: [], + }, + metricAlias: 'METRIC_ALIAS', + inventoryDefaultView: 'INVENTORY_DEFAULT_VIEW', + metricsExplorerDefaultView: 'METRICS_EXPLORER_DEFAULT_VIEW', + anomalyThreshold: 0, + }, +}; diff --git a/x-pack/plugins/infra/server/utils/map_source_to_log_view.ts b/x-pack/plugins/infra/server/utils/map_source_to_log_view.ts new file mode 100644 index 0000000000000..5dd5d021ccd6a --- /dev/null +++ b/x-pack/plugins/infra/server/utils/map_source_to_log_view.ts @@ -0,0 +1,38 @@ +/* + * 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 { LogIndexReference, LogView, LogViewAttributes } from '@kbn/logs-shared-plugin/common'; +import { LogIndexReference as SourceConfigurationLogIndexReference } from '../../common/source_configuration/source_configuration'; +import { InfraSource } from '../lib/sources'; + +export const mapSourceToLogView = (sourceConfiguration: InfraSource): LogView => { + return { + id: sourceConfiguration.id, + version: sourceConfiguration.version, + updatedAt: sourceConfiguration.updatedAt, + origin: `infra-source-${sourceConfiguration.origin}`, + attributes: getAttributesFromSourceConfiguration(sourceConfiguration), + }; +}; + +export const getAttributesFromSourceConfiguration = ({ + configuration: { name, description, logIndices, logColumns }, +}: InfraSource): LogViewAttributes => ({ + name, + description, + logIndices: getLogIndicesFromSourceConfigurationLogIndices(logIndices), + logColumns, +}); + +const getLogIndicesFromSourceConfigurationLogIndices = ( + logIndices: SourceConfigurationLogIndexReference +): LogIndexReference => + logIndices.type === 'index_pattern' + ? { + type: 'data_view', + dataViewId: logIndices.indexPatternId, + } + : logIndices; diff --git a/x-pack/plugins/infra/tsconfig.json b/x-pack/plugins/infra/tsconfig.json index 997fbf24ea9c9..3f1ece70501de 100644 --- a/x-pack/plugins/infra/tsconfig.json +++ b/x-pack/plugins/infra/tsconfig.json @@ -38,7 +38,6 @@ "@kbn/shared-ux-page-kibana-template", "@kbn/safer-lodash-set", "@kbn/test-jest-helpers", - "@kbn/test-subj-selector", "@kbn/controls-plugin", "@kbn/securitysolution-io-ts-types", "@kbn/config-schema", @@ -67,6 +66,7 @@ "@kbn/aiops-plugin", "@kbn/field-formats-plugin", "@kbn/core-http-server", + "@kbn/logs-shared-plugin", "@kbn/licensing-plugin", ], "exclude": ["target/**/*"] diff --git a/x-pack/plugins/logs_shared/README.md b/x-pack/plugins/logs_shared/README.md new file mode 100755 index 0000000000000..16483a988ec4a --- /dev/null +++ b/x-pack/plugins/logs_shared/README.md @@ -0,0 +1,3 @@ +# Logs Shared + +Exposes the shared components and APIs to access and visualize logs. diff --git a/x-pack/plugins/logs_shared/common/constants.ts b/x-pack/plugins/logs_shared/common/constants.ts new file mode 100644 index 0000000000000..7e49b14458a9e --- /dev/null +++ b/x-pack/plugins/logs_shared/common/constants.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const TIMESTAMP_FIELD = '@timestamp'; +export const MESSAGE_FIELD = 'message'; +export const TIEBREAKER_FIELD = '_doc'; diff --git a/x-pack/plugins/logs_shared/common/dynamic.tsx b/x-pack/plugins/logs_shared/common/dynamic.tsx new file mode 100644 index 0000000000000..a66dbaa10b5aa --- /dev/null +++ b/x-pack/plugins/logs_shared/common/dynamic.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { lazy, Suspense } from 'react'; + +type LoadableComponent = () => any; + +interface DynamicOptions { + fallback?: React.ReactNode; +} + +/** + * Lazy load and wrap with Suspense any component. + * + * @example + * const Header = dynamic(() => import('./components/header')) + */ +export function dynamic(loader: LoadableComponent, options: DynamicOptions = {}) { + const Component = lazy(loader); + + return (props: any) => ( + + + + ); +} diff --git a/x-pack/plugins/logs_shared/common/formatters/datetime.ts b/x-pack/plugins/logs_shared/common/formatters/datetime.ts new file mode 100644 index 0000000000000..270dd7aa73808 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/formatters/datetime.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. + */ + +import { i18n } from '@kbn/i18n'; + +export function localizedDate(dateTime: number | Date, locale: string = i18n.getLocale()) { + const formatter = new Intl.DateTimeFormat(locale, { + year: 'numeric', + month: 'short', + day: 'numeric', + }); + + return formatter.format(dateTime); +} diff --git a/x-pack/plugins/logs_shared/common/http_api/index.ts b/x-pack/plugins/logs_shared/common/http_api/index.ts new file mode 100644 index 0000000000000..939f72786183b --- /dev/null +++ b/x-pack/plugins/logs_shared/common/http_api/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/** + * Exporting versioned APIs types + */ +export * from './latest'; +export * as logEntriesV1 from './log_entries/v1'; +export * as logViewsV1 from './log_views/v1'; diff --git a/x-pack/plugins/logs_shared/common/http_api/latest.ts b/x-pack/plugins/logs_shared/common/http_api/latest.ts new file mode 100644 index 0000000000000..63f58bf4f92c0 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/http_api/latest.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 './log_entries/v1'; +export * from './log_views/v1'; diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/highlights.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/highlights.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/highlights.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/highlights.ts diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/index.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/index.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/index.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/index.ts diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/summary.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/summary.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary.ts diff --git a/x-pack/plugins/infra/common/http_api/log_entries/v1/summary_highlights.ts b/x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary_highlights.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_entries/v1/summary_highlights.ts rename to x-pack/plugins/logs_shared/common/http_api/log_entries/v1/summary_highlights.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/common.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/common.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/common.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/common.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/index.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/index.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/index.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/index.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/v1/get_log_view.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/v1/get_log_view.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/v1/get_log_view.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/v1/get_log_view.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/v1/index.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/v1/index.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/v1/index.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/v1/index.ts diff --git a/x-pack/plugins/infra/common/http_api/log_views/v1/put_log_view.ts b/x-pack/plugins/logs_shared/common/http_api/log_views/v1/put_log_view.ts similarity index 100% rename from x-pack/plugins/infra/common/http_api/log_views/v1/put_log_view.ts rename to x-pack/plugins/logs_shared/common/http_api/log_views/v1/put_log_view.ts diff --git a/x-pack/plugins/logs_shared/common/index.ts b/x-pack/plugins/logs_shared/common/index.ts new file mode 100644 index 0000000000000..07f029868b22a --- /dev/null +++ b/x-pack/plugins/logs_shared/common/index.ts @@ -0,0 +1,58 @@ +/* + * 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. + */ + +// LogView runtime +export { + defaultFilterStateKey, + defaultPositionStateKey, + DEFAULT_LOG_VIEW, + DEFAULT_REFRESH_INTERVAL, + logDataViewReferenceRT, + logIndexNameReferenceRT, + logViewColumnConfigurationRT, + logViewReferenceRT, + persistedLogViewReferenceRT, + defaultLogViewAttributes, +} from './log_views'; + +// LogView types +export type { + LogDataViewReference, + LogIndexNameReference, + LogIndexReference, + LogView, + LogViewAttributes, + LogViewColumnConfiguration, + LogViewReference, + LogViewStatus, + PersistedLogViewReference, + ResolvedLogView, + ResolvedLogViewField, +} from './log_views'; + +// LogView errors +export { + FetchLogViewError, + FetchLogViewStatusError, + ResolveLogViewError, +} from './log_views/errors'; + +// eslint-disable-next-line @kbn/eslint/no_export_all +export * from './log_entry'; + +// Http types +export type { LogEntriesSummaryBucket, LogEntriesSummaryHighlightsBucket } from './http_api'; + +// Http runtime +export { + LOG_ENTRIES_HIGHLIGHTS_PATH, + LOG_ENTRIES_SUMMARY_PATH, + logEntriesHighlightsRequestRT, + logEntriesHighlightsResponseRT, + logEntriesSummaryRequestRT, + logEntriesSummaryResponseRT, +} from './http_api'; diff --git a/x-pack/plugins/infra/common/log_entry/index.ts b/x-pack/plugins/logs_shared/common/log_entry/index.ts similarity index 100% rename from x-pack/plugins/infra/common/log_entry/index.ts rename to x-pack/plugins/logs_shared/common/log_entry/index.ts diff --git a/x-pack/plugins/infra/common/log_entry/log_entry.ts b/x-pack/plugins/logs_shared/common/log_entry/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/common/log_entry/log_entry.ts rename to x-pack/plugins/logs_shared/common/log_entry/log_entry.ts diff --git a/x-pack/plugins/infra/common/log_entry/log_entry_cursor.ts b/x-pack/plugins/logs_shared/common/log_entry/log_entry_cursor.ts similarity index 100% rename from x-pack/plugins/infra/common/log_entry/log_entry_cursor.ts rename to x-pack/plugins/logs_shared/common/log_entry/log_entry_cursor.ts diff --git a/x-pack/plugins/logs_shared/common/log_text_scale/index.ts b/x-pack/plugins/logs_shared/common/log_text_scale/index.ts new file mode 100644 index 0000000000000..11ae6d0adc7ff --- /dev/null +++ b/x-pack/plugins/logs_shared/common/log_text_scale/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 './log_text_scale'; diff --git a/x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts b/x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts new file mode 100644 index 0000000000000..7fc774c4b59e0 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/log_text_scale/log_text_scale.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type TextScale = 'small' | 'medium' | 'large'; + +export function isTextScale(maybeTextScale: string): maybeTextScale is TextScale { + return ['small', 'medium', 'large'].includes(maybeTextScale); +} diff --git a/x-pack/plugins/infra/common/log_views/defaults.ts b/x-pack/plugins/logs_shared/common/log_views/defaults.ts similarity index 82% rename from x-pack/plugins/infra/common/log_views/defaults.ts rename to x-pack/plugins/logs_shared/common/log_views/defaults.ts index 155ce6465b2fa..2d7f26c6d9407 100644 --- a/x-pack/plugins/infra/common/log_views/defaults.ts +++ b/x-pack/plugins/logs_shared/common/log_views/defaults.ts @@ -5,8 +5,7 @@ * 2.0. */ -import { defaultSourceConfiguration } from '../source_configuration/defaults'; -import { LogViewAttributes, LogViewsStaticConfig } from './types'; +import { DefaultLogViewsStaticConfig, LogViewAttributes } from './types'; export const defaultLogViewId = 'default'; export const defaultFilterStateKey = 'logFilter'; @@ -41,8 +40,8 @@ export const defaultLogViewAttributes: LogViewAttributes = { ], }; -export const defaultLogViewsStaticConfig: LogViewsStaticConfig = { - messageFields: defaultSourceConfiguration.fields.message, +export const defaultLogViewsStaticConfig: DefaultLogViewsStaticConfig = { + messageFields: ['message', '@message'], }; export const DEFAULT_LOG_VIEW = { diff --git a/x-pack/plugins/infra/common/log_views/errors.ts b/x-pack/plugins/logs_shared/common/log_views/errors.ts similarity index 100% rename from x-pack/plugins/infra/common/log_views/errors.ts rename to x-pack/plugins/logs_shared/common/log_views/errors.ts diff --git a/x-pack/plugins/infra/common/log_views/index.ts b/x-pack/plugins/logs_shared/common/log_views/index.ts similarity index 89% rename from x-pack/plugins/infra/common/log_views/index.ts rename to x-pack/plugins/logs_shared/common/log_views/index.ts index 22176058622c0..dd0cdaece4316 100644 --- a/x-pack/plugins/infra/common/log_views/index.ts +++ b/x-pack/plugins/logs_shared/common/log_views/index.ts @@ -9,4 +9,3 @@ export * from './defaults'; export * from './errors'; export * from './resolved_log_view'; export * from './types'; -export * from './url_state_storage_service'; diff --git a/x-pack/plugins/infra/common/log_views/log_view.mock.ts b/x-pack/plugins/logs_shared/common/log_views/log_view.mock.ts similarity index 100% rename from x-pack/plugins/infra/common/log_views/log_view.mock.ts rename to x-pack/plugins/logs_shared/common/log_views/log_view.mock.ts diff --git a/x-pack/plugins/infra/common/log_views/resolved_log_view.mock.ts b/x-pack/plugins/logs_shared/common/log_views/resolved_log_view.mock.ts similarity index 100% rename from x-pack/plugins/infra/common/log_views/resolved_log_view.mock.ts rename to x-pack/plugins/logs_shared/common/log_views/resolved_log_view.mock.ts diff --git a/x-pack/plugins/infra/common/log_views/resolved_log_view.ts b/x-pack/plugins/logs_shared/common/log_views/resolved_log_view.ts similarity index 91% rename from x-pack/plugins/infra/common/log_views/resolved_log_view.ts rename to x-pack/plugins/logs_shared/common/log_views/resolved_log_view.ts index 391c6be18fb9d..b9419fbd51f22 100644 --- a/x-pack/plugins/infra/common/log_views/resolved_log_view.ts +++ b/x-pack/plugins/logs_shared/common/log_views/resolved_log_view.ts @@ -8,6 +8,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { DataView, DataViewsContract, FieldSpec } from '@kbn/data-views-plugin/common'; import { TIEBREAKER_FIELD, TIMESTAMP_FIELD } from '../constants'; +import { defaultLogViewsStaticConfig } from './defaults'; import { ResolveLogViewError } from './errors'; import { LogViewAttributes, LogViewColumnConfiguration, LogViewsStaticConfig } from './types'; @@ -26,16 +27,16 @@ export interface ResolvedLogView { dataViewReference: DataView; } -export const resolveLogView = async ( +export const resolveLogView = ( logViewId: string, logViewAttributes: LogViewAttributes, dataViewsService: DataViewsContract, config: LogViewsStaticConfig ): Promise => { if (logViewAttributes.logIndices.type === 'index_name') { - return await resolveLegacyReference(logViewId, logViewAttributes, dataViewsService, config); + return resolveLegacyReference(logViewId, logViewAttributes, dataViewsService, config); } else { - return await resolveDataViewReference(logViewAttributes, dataViewsService); + return resolveDataViewReference(logViewAttributes, dataViewsService); } }; @@ -71,7 +72,7 @@ const resolveLegacyReference = async ( indices, timestampField: TIMESTAMP_FIELD, tiebreakerField: TIEBREAKER_FIELD, - messageField: config.messageFields, + messageField: config.messageFields ?? defaultLogViewsStaticConfig.messageFields, fields: dataViewReference.fields, runtimeMappings: {}, columns: logViewAttributes.logColumns, diff --git a/x-pack/plugins/infra/common/log_views/types.ts b/x-pack/plugins/logs_shared/common/log_views/types.ts similarity index 96% rename from x-pack/plugins/infra/common/log_views/types.ts rename to x-pack/plugins/logs_shared/common/log_views/types.ts index ca6dd95330f8c..f94601f9e0f84 100644 --- a/x-pack/plugins/infra/common/log_views/types.ts +++ b/x-pack/plugins/logs_shared/common/log_views/types.ts @@ -7,10 +7,12 @@ import * as rt from 'io-ts'; -export interface LogViewsStaticConfig { +export interface DefaultLogViewsStaticConfig { messageFields: string[]; } +export type LogViewsStaticConfig = Partial; + export const logViewOriginRT = rt.keyof({ stored: null, internal: null, diff --git a/x-pack/plugins/logs_shared/common/mocks.ts b/x-pack/plugins/logs_shared/common/mocks.ts new file mode 100644 index 0000000000000..06ff3df3eb00d --- /dev/null +++ b/x-pack/plugins/logs_shared/common/mocks.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 { createResolvedLogViewMock } from './log_views/resolved_log_view.mock'; diff --git a/x-pack/plugins/logs_shared/common/runtime_types.ts b/x-pack/plugins/logs_shared/common/runtime_types.ts new file mode 100644 index 0000000000000..89a6b4323b89a --- /dev/null +++ b/x-pack/plugins/logs_shared/common/runtime_types.ts @@ -0,0 +1,69 @@ +/* + * 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 { RouteValidationFunction } from '@kbn/core/server'; +import { fold } from 'fp-ts/lib/Either'; +import { identity } from 'fp-ts/lib/function'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { Context, Errors, IntersectionType, Type, UnionType, ValidationError } from 'io-ts'; + +type ErrorFactory = (message: string) => Error; + +const getErrorPath = ([first, ...rest]: Context): string[] => { + if (typeof first === 'undefined') { + return []; + } else if (first.type instanceof IntersectionType) { + const [, ...next] = rest; + return getErrorPath(next); + } else if (first.type instanceof UnionType) { + const [, ...next] = rest; + return [first.key, ...getErrorPath(next)]; + } + + return [first.key, ...getErrorPath(rest)]; +}; + +const getErrorType = ({ context }: ValidationError) => + context[context.length - 1]?.type?.name ?? 'unknown'; + +const formatError = (error: ValidationError) => + error.message ?? + `in ${getErrorPath(error.context).join('/')}: ${JSON.stringify( + error.value + )} does not match expected type ${getErrorType(error)}`; + +export const formatErrors = (errors: ValidationError[]) => + `Failed to validate: \n${errors.map((error) => ` ${formatError(error)}`).join('\n')}`; + +export const createPlainError = (message: string) => new Error(message); + +export const throwErrors = (createError: ErrorFactory) => (errors: Errors) => { + throw createError(formatErrors(errors)); +}; + +export const decodeOrThrow = + ( + runtimeType: Type, + createError: ErrorFactory = createPlainError + ) => + (inputValue: InputValue) => + pipe(runtimeType.decode(inputValue), fold(throwErrors(createError), identity)); + +type ValdidationResult = ReturnType>; + +export const createValidationFunction = + ( + runtimeType: Type + ): RouteValidationFunction => + (inputValue, { badRequest, ok }) => + pipe( + runtimeType.decode(inputValue), + fold>( + (errors: Errors) => badRequest(formatErrors(errors)), + (result: DecodedValue) => ok(result) + ) + ); diff --git a/x-pack/plugins/logs_shared/common/search_strategies/common/errors.ts b/x-pack/plugins/logs_shared/common/search_strategies/common/errors.ts new file mode 100644 index 0000000000000..4114af07619dc --- /dev/null +++ b/x-pack/plugins/logs_shared/common/search_strategies/common/errors.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 * as rt from 'io-ts'; + +const abortedRequestSearchStrategyErrorRT = rt.type({ + type: rt.literal('aborted'), +}); + +export type AbortedRequestSearchStrategyError = rt.TypeOf< + typeof abortedRequestSearchStrategyErrorRT +>; + +const genericSearchStrategyErrorRT = rt.type({ + type: rt.literal('generic'), + message: rt.string, +}); + +export type GenericSearchStrategyError = rt.TypeOf; + +const shardFailureSearchStrategyErrorRT = rt.type({ + type: rt.literal('shardFailure'), + shardInfo: rt.type({ + shard: rt.union([rt.number, rt.null]), + index: rt.union([rt.string, rt.null]), + node: rt.union([rt.string, rt.null]), + }), + message: rt.union([rt.string, rt.null]), +}); + +export type ShardFailureSearchStrategyError = rt.TypeOf; + +export const searchStrategyErrorRT = rt.union([ + abortedRequestSearchStrategyErrorRT, + genericSearchStrategyErrorRT, + shardFailureSearchStrategyErrorRT, +]); + +export type SearchStrategyError = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts new file mode 100644 index 0000000000000..f8daaa1b9227b --- /dev/null +++ b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entries.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import * as rt from 'io-ts'; +import { + logEntryAfterCursorRT, + logEntryBeforeCursorRT, + logEntryCursorRT, + logEntryRT, +} from '../../log_entry'; +import { logViewColumnConfigurationRT, logViewReferenceRT } from '../../log_views'; +import { jsonObjectRT } from '../../typed_json'; +import { searchStrategyErrorRT } from '../common/errors'; + +export const LOG_ENTRIES_SEARCH_STRATEGY = 'infra-log-entries'; + +const logEntriesBaseSearchRequestParamsRT = rt.intersection([ + rt.type({ + logView: logViewReferenceRT, + startTimestamp: rt.number, + endTimestamp: rt.number, + size: rt.number, + }), + rt.partial({ + query: jsonObjectRT, + columns: rt.array(logViewColumnConfigurationRT), + highlightPhrase: rt.string, + }), +]); + +export const logEntriesBeforeSearchRequestParamsRT = rt.intersection([ + logEntriesBaseSearchRequestParamsRT, + logEntryBeforeCursorRT, +]); + +export const logEntriesAfterSearchRequestParamsRT = rt.intersection([ + logEntriesBaseSearchRequestParamsRT, + logEntryAfterCursorRT, +]); + +export const logEntriesSearchRequestParamsRT = rt.union([ + logEntriesBaseSearchRequestParamsRT, + logEntriesBeforeSearchRequestParamsRT, + logEntriesAfterSearchRequestParamsRT, +]); + +export type LogEntriesSearchRequestParams = rt.TypeOf; + +export type LogEntriesSearchRequestQuery = estypes.QueryDslQueryContainer; + +export const logEntriesSearchResponsePayloadRT = rt.intersection([ + rt.type({ + data: rt.intersection([ + rt.type({ + entries: rt.array(logEntryRT), + topCursor: rt.union([logEntryCursorRT, rt.null]), + bottomCursor: rt.union([logEntryCursorRT, rt.null]), + }), + rt.partial({ + hasMoreBefore: rt.boolean, + hasMoreAfter: rt.boolean, + }), + ]), + }), + rt.partial({ + errors: rt.array(searchStrategyErrorRT), + }), +]); + +export type LogEntriesSearchResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.ts b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.ts new file mode 100644 index 0000000000000..6d2a7891264d1 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/search_strategies/log_entries/log_entry.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 * as rt from 'io-ts'; +import { logEntryCursorRT, logEntryFieldRT } from '../../log_entry'; +import { logViewReferenceRT } from '../../log_views'; +import { searchStrategyErrorRT } from '../common/errors'; + +export const LOG_ENTRY_SEARCH_STRATEGY = 'infra-log-entry'; + +export const logEntrySearchRequestParamsRT = rt.type({ + logView: logViewReferenceRT, + logEntryId: rt.string, +}); + +export type LogEntrySearchRequestParams = rt.TypeOf; + +export const logEntryRT = rt.type({ + id: rt.string, + index: rt.string, + fields: rt.array(logEntryFieldRT), + cursor: logEntryCursorRT, +}); + +export type LogEntry = rt.TypeOf; + +export const logEntrySearchResponsePayloadRT = rt.intersection([ + rt.type({ + data: rt.union([logEntryRT, rt.null]), + }), + rt.partial({ + errors: rt.array(searchStrategyErrorRT), + }), +]); + +export type LogEntrySearchResponsePayload = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/common/time/index.ts b/x-pack/plugins/logs_shared/common/time/index.ts new file mode 100644 index 0000000000000..c6a68995c024a --- /dev/null +++ b/x-pack/plugins/logs_shared/common/time/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 './time_key'; diff --git a/x-pack/plugins/logs_shared/common/time/time_key.ts b/x-pack/plugins/logs_shared/common/time/time_key.ts new file mode 100644 index 0000000000000..4c78158dd5bf6 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/time/time_key.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 { ascending, bisector } from 'd3-array'; +import * as rt from 'io-ts'; + +export const minimalTimeKeyRT = rt.type({ + time: rt.number, + tiebreaker: rt.number, +}); + +export const timeKeyRT = rt.intersection([ + minimalTimeKeyRT, + rt.partial({ + gid: rt.string, + fromAutoReload: rt.boolean, + }), +]); +export type TimeKey = rt.TypeOf; + +export interface UniqueTimeKey extends TimeKey { + gid: string; +} + +export type Comparator = (firstValue: any, secondValue: any) => number; + +export function compareTimeKeys( + firstKey: TimeKey, + secondKey: TimeKey, + compareValues: Comparator = ascending +): number { + const timeComparison = compareValues(firstKey.time, secondKey.time); + + if (timeComparison === 0) { + const tiebreakerComparison = compareValues(firstKey.tiebreaker, secondKey.tiebreaker); + + if ( + tiebreakerComparison === 0 && + typeof firstKey.gid !== 'undefined' && + typeof secondKey.gid !== 'undefined' + ) { + return compareValues(firstKey.gid, secondKey.gid); + } + + return tiebreakerComparison; + } + + return timeComparison; +} + +export const compareToTimeKey = + (keyAccessor: (value: Value) => TimeKey, compareValues?: Comparator) => + (value: Value, key: TimeKey) => + compareTimeKeys(keyAccessor(value), key, compareValues); + +export const getIndexAtTimeKey = ( + keyAccessor: (value: Value) => TimeKey, + compareValues?: Comparator +) => { + const comparator = compareToTimeKey(keyAccessor, compareValues); + const collectionBisector = bisector(comparator); + + return (collection: Value[], key: TimeKey): number | null => { + const index = collectionBisector.left(collection, key); + + if (index >= collection.length) { + return null; + } + + if (comparator(collection[index], key) !== 0) { + return null; + } + + return index; + }; +}; diff --git a/x-pack/plugins/logs_shared/common/typed_json.ts b/x-pack/plugins/logs_shared/common/typed_json.ts new file mode 100644 index 0000000000000..95d5d4274c3b6 --- /dev/null +++ b/x-pack/plugins/logs_shared/common/typed_json.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 * as rt from 'io-ts'; +import { JsonArray, JsonObject, JsonValue } from '@kbn/utility-types'; + +export type { JsonArray, JsonObject, JsonValue }; + +export const jsonScalarRT = rt.union([rt.null, rt.boolean, rt.number, rt.string]); +export type JsonScalar = rt.TypeOf; + +export const jsonValueRT: rt.Type = rt.recursion('JsonValue', () => + rt.union([jsonScalarRT, jsonArrayRT, jsonObjectRT]) +); + +export const jsonArrayRT: rt.Type = rt.recursion('JsonArray', () => + rt.array(jsonValueRT) +); + +export const jsonObjectRT: rt.Type = rt.recursion('JsonObject', () => + rt.record(rt.string, jsonValueRT) +); diff --git a/x-pack/plugins/logs_shared/jest.config.js b/x-pack/plugins/logs_shared/jest.config.js new file mode 100644 index 0000000000000..4d4168f2dbda4 --- /dev/null +++ b/x-pack/plugins/logs_shared/jest.config.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../..', + roots: ['/x-pack/plugins/logs_shared'], + coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/logs_shared', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/logs_shared/{common,public,server}/**/*.{ts,tsx}', + ], +}; diff --git a/x-pack/plugins/logs_shared/kibana.jsonc b/x-pack/plugins/logs_shared/kibana.jsonc new file mode 100644 index 0000000000000..fea2ccc878485 --- /dev/null +++ b/x-pack/plugins/logs_shared/kibana.jsonc @@ -0,0 +1,22 @@ +{ + "type": "plugin", + "id": "@kbn/logs-shared-plugin", + "owner": "@elastic/infra-monitoring-ui", + "description": "Exposes the shared components and APIs to access and visualize logs.", + "plugin": { + "id": "logsShared", + "server": true, + "browser": true, + "configPath": ["xpack", "logs_shared"], + "requiredPlugins": ["data", "dataViews", "usageCollection", "observabilityShared"], + "optionalPlugins": ["observability"], + "requiredBundles": [ + "observability", + "kibanaUtils", + "kibanaReact", + ], + "extraPublicDirs": [ + "common", + ] + } +} diff --git a/x-pack/plugins/logs_shared/public/components/auto_sizer.tsx b/x-pack/plugins/logs_shared/public/components/auto_sizer.tsx new file mode 100644 index 0000000000000..a983502fa85b7 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/components/auto_sizer.tsx @@ -0,0 +1,188 @@ +/* + * 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 React from 'react'; + +interface Measurement { + width?: number; + height?: number; +} + +interface Measurements { + bounds: Measurement; + content: Measurement; +} + +interface AutoSizerProps { + detectAnyWindowResize?: boolean | 'height' | 'width'; + bounds?: boolean; + content?: boolean; + onResize?: (size: Measurements) => void; + children: ( + args: { measureRef: (instance: HTMLElement | null) => any } & Measurements + ) => React.ReactNode; +} + +interface AutoSizerState { + boundsMeasurement: Measurement; + contentMeasurement: Measurement; +} + +export class AutoSizer extends React.PureComponent { + public element: HTMLElement | null = null; + public resizeObserver: ResizeObserver | null = null; + public windowWidth: number = -1; + public windowHeight: number = -1; + + public readonly state = { + boundsMeasurement: { + height: void 0, + width: void 0, + }, + contentMeasurement: { + height: void 0, + width: void 0, + }, + }; + + constructor(props: AutoSizerProps) { + super(props); + if (this.props.detectAnyWindowResize) { + window.addEventListener('resize', this.updateMeasurement); + } + this.resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => { + entries.forEach((entry) => { + if (entry.target === this.element) { + this.measure(entry); + } + }); + }); + } + + public componentWillUnmount() { + if (this.resizeObserver) { + this.resizeObserver.disconnect(); + this.resizeObserver = null; + } + if (this.props.detectAnyWindowResize) { + window.removeEventListener('resize', this.updateMeasurement); + } + } + + public measure = (entry: ResizeObserverEntry | null) => { + if (!this.element) { + return; + } + + const { content = true, bounds = false } = this.props; + const { + boundsMeasurement: previousBoundsMeasurement, + contentMeasurement: previousContentMeasurement, + } = this.state; + + const boundsRect = bounds ? this.element.getBoundingClientRect() : null; + const boundsMeasurement = boundsRect + ? { + height: boundsRect.height, + width: boundsRect.width, + } + : previousBoundsMeasurement; + + if (this.props.detectAnyWindowResize && boundsMeasurement) { + if ( + boundsMeasurement.width && + this.windowWidth !== -1 && + this.windowWidth > window.innerWidth + ) { + const gap = this.windowWidth - window.innerWidth; + boundsMeasurement.width = boundsMeasurement.width - gap; + } + if ( + boundsMeasurement.height && + this.windowHeight !== -1 && + this.windowHeight > window.innerHeight + ) { + const gap = this.windowHeight - window.innerHeight; + boundsMeasurement.height = boundsMeasurement.height - gap; + } + } + this.windowWidth = window.innerWidth; + this.windowHeight = window.innerHeight; + const contentRect = content && entry ? entry.contentRect : null; + const contentMeasurement = + contentRect && entry + ? { + height: entry.contentRect.height, + width: entry.contentRect.width, + } + : previousContentMeasurement; + if ( + isEqual(boundsMeasurement, previousBoundsMeasurement) && + isEqual(contentMeasurement, previousContentMeasurement) + ) { + return; + } + + requestAnimationFrame(() => { + if (!this.resizeObserver) { + return; + } + + this.setState({ boundsMeasurement, contentMeasurement }); + + if (this.props.onResize) { + this.props.onResize({ + bounds: boundsMeasurement, + content: contentMeasurement, + }); + } + }); + }; + + public render() { + const { children } = this.props; + const { boundsMeasurement, contentMeasurement } = this.state; + return children({ + bounds: boundsMeasurement, + content: contentMeasurement, + measureRef: this.storeRef, + }); + } + + private updateMeasurement = () => + requestAnimationFrame(() => { + const { detectAnyWindowResize } = this.props; + if (!detectAnyWindowResize) return; + switch (detectAnyWindowResize) { + case 'height': + if (this.windowHeight !== window.innerHeight) { + this.measure(null); + } + break; + case 'width': + if (this.windowWidth !== window.innerWidth) { + this.measure(null); + } + break; + default: + this.measure(null); + } + }); + + private storeRef = (element: HTMLElement | null) => { + if (this.element && this.resizeObserver) { + this.resizeObserver.unobserve(this.element); + } + + if (element && this.resizeObserver) { + this.resizeObserver.observe(element); + } + + this.element = element; + }; +} diff --git a/x-pack/plugins/infra/public/components/centered_flyout_body.tsx b/x-pack/plugins/logs_shared/public/components/centered_flyout_body.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/centered_flyout_body.tsx rename to x-pack/plugins/logs_shared/public/components/centered_flyout_body.tsx diff --git a/x-pack/plugins/infra/public/components/data_search_error_callout.stories.tsx b/x-pack/plugins/logs_shared/public/components/data_search_error_callout.stories.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/data_search_error_callout.stories.tsx rename to x-pack/plugins/logs_shared/public/components/data_search_error_callout.stories.tsx diff --git a/x-pack/plugins/infra/public/components/data_search_error_callout.tsx b/x-pack/plugins/logs_shared/public/components/data_search_error_callout.tsx similarity index 92% rename from x-pack/plugins/infra/public/components/data_search_error_callout.tsx rename to x-pack/plugins/logs_shared/public/components/data_search_error_callout.tsx index dd63b22db683d..52e36002de73f 100644 --- a/x-pack/plugins/infra/public/components/data_search_error_callout.tsx +++ b/x-pack/plugins/logs_shared/public/components/data_search_error_callout.tsx @@ -35,7 +35,7 @@ export const DataSearchErrorCallout: React.FC<{ onClick={onRetry} > @@ -59,7 +59,7 @@ const AbortedRequestErrorMessage: React.FC<{ }> = ({}) => ( ); @@ -73,7 +73,7 @@ const ShardFailureErrorMessage: React.FC<{ error: ShardFailureSearchStrategyErro }) => ( void; + testString?: string; +} + +export const NoData: React.FC = ({ + titleText, + bodyText, + refetchText, + onRefetch, + testString, +}) => ( + {titleText}} + titleSize="m" + body={

{bodyText}

} + actions={ + + {refetchText} + + } + data-test-subj={testString} + /> +); + +const CenteredEmptyPrompt = euiStyled(EuiEmptyPrompt)` + align-self: center; +`; diff --git a/x-pack/plugins/infra/public/components/formatted_time.tsx b/x-pack/plugins/logs_shared/public/components/formatted_time.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/formatted_time.tsx rename to x-pack/plugins/logs_shared/public/components/formatted_time.tsx diff --git a/x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx b/x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx new file mode 100644 index 0000000000000..879d8a2328ebc --- /dev/null +++ b/x-pack/plugins/logs_shared/public/components/loading/__examples__/index.stories.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Meta, Story } from '@storybook/react/types-6-0'; +import React from 'react'; +import { LogsSharedLoadingPanel } from '..'; +import { decorateWithGlobalStorybookThemeProviders } from '../../../test_utils/use_global_storybook_theme'; + +export default { + title: 'logs_shared/LogsSharedLoadingPanel', + decorators: [ + (wrappedStory) =>
{wrappedStory()}
, + decorateWithGlobalStorybookThemeProviders, + ], +} as Meta; + +export const LoadingPanel: Story = () => ( + +); diff --git a/x-pack/plugins/logs_shared/public/components/loading/index.tsx b/x-pack/plugins/logs_shared/public/components/loading/index.tsx new file mode 100644 index 0000000000000..ca032885a8958 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/components/loading/index.tsx @@ -0,0 +1,49 @@ +/* + * 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 { EuiLoadingChart, EuiPanel, EuiText } from '@elastic/eui'; +import * as React from 'react'; + +import { euiStyled } from '@kbn/kibana-react-plugin/common'; + +interface LogsSharedLoadingProps { + text: string | JSX.Element; + height: number | string; + width: number | string; +} + +export class LogsSharedLoadingPanel extends React.PureComponent { + public render() { + const { height, text, width } = this.props; + return ( + + + + + +

{text}

+
+
+
+
+ ); + } +} + +export const LogsSharedLoadingStaticPanel = euiStyled.div` + position: relative; + overflow: hidden; + display: flex; + flex-direction: column; + justify-content: center; +`; + +export const LogsSharedLoadingStaticContentPanel = euiStyled.div` + flex: 0 0 auto; + align-self: center; + text-align: center; +`; diff --git a/x-pack/plugins/infra/public/components/log_stream/index.ts b/x-pack/plugins/logs_shared/public/components/log_stream/index.ts similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/index.ts rename to x-pack/plugins/logs_shared/public/components/log_stream/index.ts diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx similarity index 91% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx index b6e1d5f7fe0d8..36bddaf0a11d2 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.mdx +++ b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.mdx @@ -1,15 +1,15 @@ import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks'; - + # Embeddable `` component The purpose of this component is to allow you, the developer, to have your very own Log Stream in your plugin. -The component is exposed through `infra/public`. Since Kibana uses relative paths, it is up to you to find how to import it (sorry). +The component is exposed through `logs_shared/public`. Since Kibana uses relative paths, it is up to you to find how to import it (sorry). ```tsx -import { LogStream } from '../../../../../../infra/public'; +import { LogStream } from '../../../../../../logs_shared/public'; // ^^ Modify appropriately ``` @@ -17,7 +17,7 @@ import { LogStream } from '../../../../../../infra/public'; To use the component your plugin needs to follow certain criteria: -- Ensure `"infra"` and `"data"` are specified as a `requiredPlugins` in your plugin's `kibana.json`. +- Ensure `"logsShared"` and `"data"` are specified as a `requiredPlugins` in your plugin's `kibana.json`. - Ensure the `` component is mounted inside the hierachy of a [`kibana-react` provider](https://github.com/elastic/kibana/blob/b2d0aa7b7fae1c89c8f9e8854ae73e71be64e765/src/plugins/kibana_react/README.md#L45). At a minimum, the kibana-react provider must pass `http` (from core start services) and `data` (from core plugin start dependencies). - Ensure the `` component is mounted inside the hierachy of a [`KibanaThemeProvider`](https://github.com/elastic/kibana/blob/31d2db035c905fb5819fa6dc2354f3be795a34cf/src/plugins/kibana_react/public/theme/kibana_theme_provider.tsx#L27). - Ensure the `` component is mounted inside the hierachy of a [`EuiThemeProvider`](https://github.com/elastic/kibana/blob/main/src/plugins/kibana_react/common/eui_styled_components.tsx). This is not the same as the provider exported by EUI. It bridges the gap between EUI and styled components and predates the css-in-js support in EUI. @@ -35,7 +35,7 @@ const startTimestamp = endTimestamp - 15 * 60 * 1000; // 15 minutes This will show a list of log entries between the specified timestamps. - + ## Query log entries @@ -80,7 +80,7 @@ The component also has a `filters` prop that accepts valid es-query `filters`. T ## Center the view on a specific entry -By default the component will load at the bottom of the list, showing the newest entries. You can change the rendering point with the `center` prop. The prop takes a [`LogEntriesCursor`](https://github.com/elastic/kibana/blob/0a6c748cc837c016901f69ff05d81395aa2d41c8/x-pack/plugins/infra/common/http_api/log_entries/common.ts#L9-L13). +By default the component will load at the bottom of the list, showing the newest entries. You can change the rendering point with the `center` prop. The prop takes a [`LogEntriesCursor`](https://github.com/elastic/kibana/blob/0a6c748cc837c016901f69ff05d81395aa2d41c8/x-pack/plugins/logs_shared/common/http_api/log_entries/common.ts#L9-L13). ```tsx ``` - + ## Highlight a specific entry @@ -100,7 +100,7 @@ The component can highlight a specific line via the `highlight` prop. It takes t ``` - + ## Column configuration @@ -131,7 +131,7 @@ The easiest way is to specify what columns you want with the `columns` prop. /> ``` - + The rendering of the column headers and the cell contents can also be customized with the following properties: @@ -206,7 +206,7 @@ The rendering of the column headers and the cell contents can also be customized /> ``` - + ### With a static log view configuration @@ -262,4 +262,4 @@ The component can render a button on the row that opens a flyout, via the `showF showFlyoutAction /> ``` - + diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.stories.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.stories.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.stories.tsx diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.story_decorators.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.story_decorators.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.story_decorators.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.story_decorators.tsx diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/log_stream/log_stream.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream.tsx diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream_error_boundary.tsx b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream_error_boundary.tsx similarity index 93% rename from x-pack/plugins/infra/public/components/log_stream/log_stream_error_boundary.tsx rename to x-pack/plugins/logs_shared/public/components/log_stream/log_stream_error_boundary.tsx index c2e025dcd5e75..cf60b902e3b33 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream_error_boundary.tsx +++ b/x-pack/plugins/logs_shared/public/components/log_stream/log_stream_error_boundary.tsx @@ -33,7 +33,7 @@ const LogStreamErrorContent: React.FC<{ @@ -46,7 +46,7 @@ const LogStreamErrorContent: React.FC<{ diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/index.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/index.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/index.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/index.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.test.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx similarity index 90% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx index e06149dd90d5c..e99304a61b453 100644 --- a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_actions_menu.tsx @@ -8,7 +8,6 @@ import { EuiButton, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { useMemo } from 'react'; -import { getApmTraceUrl } from '@kbn/observability-plugin/public'; import { useLinkProps, LinkDescriptor } from '@kbn/observability-shared-plugin/public'; import { useVisibilityState } from '../../../utils/use_visibility_state'; import { LogEntry } from '../../../../common/search_strategies/log_entries/log_entry'; @@ -45,7 +44,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => { {...uptimeLinkProps} > , @@ -57,7 +56,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => { {...apmLinkProps} > , @@ -78,7 +77,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => { onClick={toggle} > @@ -142,3 +141,15 @@ const getAPMLink = (logEntry: LogEntry): LinkDescriptor | undefined => { pathname: getApmTraceUrl({ traceId, rangeFrom, rangeTo }), }; }; + +function getApmTraceUrl({ + traceId, + rangeFrom, + rangeTo, +}: { + traceId: string; + rangeFrom: string; + rangeTo: string; +}) { + return `/link-to/trace/${traceId}?` + new URLSearchParams({ rangeFrom, rangeTo }).toString(); +} diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx similarity index 90% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx index a503c05011246..09b8381859354 100644 --- a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx @@ -47,7 +47,7 @@ export const LogEntryFieldsTable: React.FC<{ () => [ { field: 'field', - name: i18n.translate('xpack.infra.logFlyout.fieldColumnLabel', { + name: i18n.translate('xpack.logsShared.logFlyout.fieldColumnLabel', { defaultMessage: 'Field', }), sortable: true, @@ -66,7 +66,7 @@ export const LogEntryFieldsTable: React.FC<{ }, { field: 'value', - name: i18n.translate('xpack.infra.logFlyout.valueColumnLabel', { + name: i18n.translate('xpack.logsShared.logFlyout.valueColumnLabel', { defaultMessage: 'Value', }), render: (_name: string, item: LogEntryField) => ( @@ -107,11 +107,11 @@ const searchOptions = { }, }; -const setFilterButtonLabel = i18n.translate('xpack.infra.logFlyout.filterAriaLabel', { +const setFilterButtonLabel = i18n.translate('xpack.logsShared.logFlyout.filterAriaLabel', { defaultMessage: 'Filter', }); -const setFilterButtonDescription = i18n.translate('xpack.infra.logFlyout.setFilterTooltip', { +const setFilterButtonDescription = i18n.translate('xpack.logsShared.logFlyout.setFilterTooltip', { defaultMessage: 'View event with filter', }); diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx similarity index 91% rename from x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx index 8237a36f5557d..e06064c676a63 100644 --- a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx @@ -146,7 +146,7 @@ export const LogEntryFlyout = ({

{logEntryId} : '', }} @@ -158,7 +158,7 @@ export const LogEntryFlyout = ({ {logEntry.index}, @@ -237,18 +237,24 @@ export const LogEntryFlyout = ({ ); }; -const explainLogMessageTitle = i18n.translate('xpack.infra.logFlyout.explainLogMessageTitle', { +const explainLogMessageTitle = i18n.translate('xpack.logsShared.logFlyout.explainLogMessageTitle', { defaultMessage: "What's this message?", }); -const similarLogMessagesTitle = i18n.translate('xpack.infra.logFlyout.similarLogMessagesTitle', { - defaultMessage: 'How do I find similar log messages?', -}); +const similarLogMessagesTitle = i18n.translate( + 'xpack.logsShared.logFlyout.similarLogMessagesTitle', + { + defaultMessage: 'How do I find similar log messages?', + } +); -const loadingProgressMessage = i18n.translate('xpack.infra.logFlyout.loadingMessage', { +const loadingProgressMessage = i18n.translate('xpack.logsShared.logFlyout.loadingMessage', { defaultMessage: 'Searching log entry in shards', }); -const loadingErrorCalloutTitle = i18n.translate('xpack.infra.logFlyout.loadingErrorCalloutTitle', { - defaultMessage: 'Error while searching the log entry', -}); +const loadingErrorCalloutTitle = i18n.translate( + 'xpack.logsShared.logFlyout.loadingErrorCalloutTitle', + { + defaultMessage: 'Error while searching the log entry', + } +); diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/column_headers.tsx similarity index 96% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/column_headers.tsx index 30355ea1a9a23..9e1d9330f7b87 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/column_headers.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/column_headers.tsx @@ -43,7 +43,7 @@ export const LogColumnHeaders: React.FunctionComponent<{ } else { columnHeader = firstVisiblePosition ? localizedDate(firstVisiblePosition.time) - : i18n.translate('xpack.infra.logs.stream.timestampColumnTitle', { + : i18n.translate('xpack.logsShared.logs.stream.timestampColumnTitle', { defaultMessage: 'Timestamp', }); } @@ -64,7 +64,7 @@ export const LogColumnHeaders: React.FunctionComponent<{ } else if (typeof columnConfiguration.messageColumn.header === 'string') { columnHeader = columnConfiguration.messageColumn.header; } else { - columnHeader = i18n.translate('xpack.infra.logs.stream.messageColumnTitle', { + columnHeader = i18n.translate('xpack.logsShared.logs.stream.messageColumnTitle', { defaultMessage: 'Message', }); } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/field_value.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/field_value.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/highlighting.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/highlighting.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/highlighting.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/highlighting.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/index.ts b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/index.ts similarity index 79% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/index.ts rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/index.ts index dbd5bd49d0240..dfccaae6dd8c9 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/index.ts +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/index.ts @@ -5,11 +5,14 @@ * 2.0. */ +export type { LogEntryStreamItem } from './item'; export type { LogEntryColumnWidths } from './log_entry_column'; -export { LogEntryColumn, useColumnWidths, iconColumnId } from './log_entry_column'; + +export { LogColumnHeader, LogColumnHeadersWrapper } from './column_headers'; +export { iconColumnId, LogEntryColumn, useColumnWidths } from './log_entry_column'; +export { LogEntryContextMenu } from './log_entry_context_menu'; export { LogEntryFieldColumn } from './log_entry_field_column'; export { LogEntryMessageColumn } from './log_entry_message_column'; export { LogEntryRowWrapper } from './log_entry_row'; export { LogEntryTimestampColumn } from './log_entry_timestamp_column'; export { ScrollableLogTextStreamView } from './scrollable_log_text_stream_view'; -export { LogEntryContextMenu } from './log_entry_context_menu'; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/item.ts b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/item.ts similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/item.ts rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/item.ts diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/jump_to_tail.tsx similarity index 93% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/jump_to_tail.tsx index 81bb3f299db57..1f3f35d0d1a17 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/jump_to_tail.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/jump_to_tail.tsx @@ -24,7 +24,7 @@ export class LogTextStreamJumpToTail extends React.PureComponent @@ -36,7 +36,7 @@ export class LogTextStreamJumpToTail extends React.PureComponent diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/loading_item_view.tsx similarity index 89% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/loading_item_view.tsx index f0b0fc4236bfc..9cd7c91250528 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/loading_item_view.tsx @@ -118,19 +118,19 @@ const ProgressMessage: React.FC = ({ timestamp, position, const message = position === 'start' ? ( ) : isStreaming ? ( ) : ( @@ -152,12 +152,12 @@ const ProgressSpinner: React.FC<{ kind: 'streaming' | 'loading' }> = ({ kind }) {kind === 'streaming' ? ( ) : ( )} @@ -182,7 +182,7 @@ const ProgressCta: React.FC = ({ if (rangeEdge === 'now' && position === 'end') { return ( - + ); } @@ -217,7 +217,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'ms': return ( @@ -225,7 +225,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 's': return ( @@ -233,7 +233,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'm': return ( @@ -241,7 +241,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'h': return ( @@ -249,7 +249,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'd': return ( @@ -257,7 +257,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'w': return ( @@ -265,7 +265,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'M': return ( @@ -273,7 +273,7 @@ const ProgressExtendMessage: React.FC<{ amount: number; unit: Unit }> = ({ amoun case 'y': return ( diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_date_row.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_date_row.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_date_row.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_date_row.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_context_menu.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_context_menu.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_context_menu.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_context_menu.tsx index ba87fa8c09bc4..17c7fb9dd7e9f 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_context_menu.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_context_menu.tsx @@ -35,7 +35,7 @@ interface LogEntryContextMenuProps { } const DEFAULT_MENU_LABEL = i18n.translate( - 'xpack.infra.logEntryItemView.logEntryActionsMenuToolTip', + 'xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip', { defaultMessage: 'View actions for line', } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.test.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_field_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.test.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.test.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.test.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_message_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_row.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_row.tsx index 4a137ca361a40..2963a3e1aac14 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_row.tsx @@ -32,16 +32,16 @@ import { LogEntryMessageColumn } from './log_entry_message_column'; import { LogEntryTimestampColumn } from './log_entry_timestamp_column'; import { highlightedContentStyle, hoveredContentStyle, monospaceTextStyle } from './text_styles'; -const MENU_LABEL = i18n.translate('xpack.infra.logEntryItemView.logEntryActionsMenuToolTip', { +const MENU_LABEL = i18n.translate('xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip', { defaultMessage: 'View actions for line', }); -const LOG_DETAILS_LABEL = i18n.translate('xpack.infra.logs.logEntryActionsDetailsButton', { +const LOG_DETAILS_LABEL = i18n.translate('xpack.logsShared.logs.logEntryActionsDetailsButton', { defaultMessage: 'View details', }); const LOG_VIEW_IN_CONTEXT_LABEL = i18n.translate( - 'xpack.infra.lobs.logEntryActionsViewInContextButton', + 'xpack.logsShared.lobs.logEntryActionsViewInContextButton', { defaultMessage: 'View in context', } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_text_separator.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/log_text_separator.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/log_text_separator.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/measurable_item_view.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/measurable_item_view.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/measurable_item_view.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/measurable_item_view.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx index 4c11bd21daa19..8a0a120a3a7d5 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx @@ -16,7 +16,7 @@ import { TimeKey, UniqueTimeKey } from '../../../../common/time'; import { callWithoutRepeats } from '../../../utils/handlers'; import { AutoSizer } from '../../auto_sizer'; import { NoData } from '../../empty_states'; -import { InfraLoadingPanel } from '../../loading'; +import { LogsSharedLoadingPanel } from '../../loading'; import { getStreamItemBeforeTimeKey, getStreamItemId, parseStreamItemId, StreamItem } from './item'; import { LogColumnHeaders } from './column_headers'; import { LogTextStreamLoadingItemView } from './loading_item_view'; @@ -160,27 +160,30 @@ export class ScrollableLogTextStreamView extends React.PureComponent< return ( {isReloading && (!isStreaming || !hasItems) ? ( - } /> ) : !hasItems ? ( @@ -368,6 +371,9 @@ export class ScrollableLogTextStreamView extends React.PureComponent< }; } +// eslint-disable-next-line import/no-default-export +export default ScrollableLogTextStreamView; + /** * If the above component wasn't a class component, this wouldn't be necessary * since the `useColumnWidths` hook could have been used directly. diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/text_styles.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/text_styles.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_text_stream/vertical_scroll_panel.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx rename to x-pack/plugins/logs_shared/public/components/logging/log_text_stream/vertical_scroll_panel.tsx diff --git a/x-pack/plugins/infra/public/components/resettable_error_boundary.tsx b/x-pack/plugins/logs_shared/public/components/resettable_error_boundary.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/resettable_error_boundary.tsx rename to x-pack/plugins/logs_shared/public/components/resettable_error_boundary.tsx diff --git a/x-pack/plugins/infra/public/containers/logs/log_entry.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_entry.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_entry.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_entry_highlights.tsx similarity index 98% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_entry_highlights.tsx index ea0e1fa326c78..6e13ff542add6 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_entry_highlights.tsx @@ -6,7 +6,7 @@ */ import { useEffect, useMemo, useState } from 'react'; -import { LogViewReference } from '../../../../common/log_views'; +import { LogViewReference } from '../../../../common'; import { LogEntriesHighlightsResponse } from '../../../../common/http_api'; import { LogEntry } from '../../../../common/log_entry'; import { TimeKey } from '../../../../common/time'; diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_highlights.tsx similarity index 96% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_highlights.tsx index 0a6710731bcb1..aa963925d7ac9 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_highlights.tsx @@ -8,12 +8,13 @@ import createContainer from 'constate'; import { useState } from 'react'; import useThrottle from 'react-use/lib/useThrottle'; -import { LogViewReference } from '../../../../common/log_views'; + +import { LogViewReference } from '../../../../common'; import { useLogEntryHighlights } from './log_entry_highlights'; import { useLogSummaryHighlights } from './log_summary_highlights'; import { useNextAndPrevious } from './next_and_previous'; -import { useLogPositionStateContext } from '../log_position'; import { TimeKey } from '../../../../common/time'; +import { useLogPositionStateContext } from '../log_position'; const FETCH_THROTTLE_INTERVAL = 3000; @@ -25,7 +26,7 @@ interface UseLogHighlightsStateProps { filterQuery: string | null; } -export const useLogHighlightsState = ({ +const useLogHighlightsState = ({ logViewReference, sourceVersion, centerCursor, diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_summary_highlights.ts similarity index 97% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_summary_highlights.ts index 8c5f7fb7ae778..61a1a02618e7a 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/log_summary_highlights.ts @@ -8,7 +8,7 @@ import { useEffect, useMemo, useState } from 'react'; import { debounce } from 'lodash'; -import { LogViewReference } from '../../../../common/log_views'; +import { LogViewReference } from '../../../../common'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { fetchLogSummaryHighlights } from './api/fetch_log_summary_highlights'; import { LogEntriesSummaryHighlightsResponse } from '../../../../common/http_api'; diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/next_and_previous.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_highlights/next_and_previous.tsx similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_highlights/next_and_previous.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_highlights/next_and_previous.tsx diff --git a/x-pack/plugins/infra/public/containers/logs/log_position/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_position/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_position/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_position/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_position/use_log_position.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_position/use_log_position.ts similarity index 80% rename from x-pack/plugins/infra/public/containers/logs/log_position/use_log_position.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_position/use_log_position.ts index 2471acf6e9283..236e59093d450 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_position/use_log_position.ts +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_position/use_log_position.ts @@ -5,15 +5,28 @@ * 2.0. */ +import { TimeRange } from '@kbn/es-query'; import createContainer from 'constate'; import { useMemo } from 'react'; -import { VisiblePositions } from '../../../observability_logs/log_stream_position_state/src/types'; -import { - LogStreamPageActorRef, - LogStreamPageCallbacks, -} from '../../../observability_logs/log_stream_page/state'; -import { MatchedStateFromActor } from '../../../observability_logs/xstate_helpers'; +import { ActorRefWithDeprecatedState } from 'xstate'; import { TimeKey } from '../../../../common/time'; +import { + MatchedStateFromActor, + OmitDeprecatedState, +} from '../../../observability_logs/xstate_helpers'; + +type LogStreamPageState = MatchedStateFromActor< + OmitDeprecatedState>, + { hasLogViewIndices: 'initialized' } +>; + +interface VisiblePositions { + startKey: TimeKey | null; + middleKey: TimeKey | null; + endKey: TimeKey | null; + pagesAfterEnd: number; + pagesBeforeStart: number; +} type TimeKeyOrNull = TimeKey | null; @@ -46,6 +59,15 @@ export interface LogPositionCallbacks { updateDateRange: UpdateDateRangeFn; } +export interface LogStreamPageCallbacks { + updateTimeRange: (timeRange: Partial) => void; + jumpToTargetPosition: (targetPosition: TimeKey | null) => void; + jumpToTargetPositionTime: (time: number) => void; + reportVisiblePositions: (visiblePositions: VisiblePositions) => void; + startLiveStreaming: () => void; + stopLiveStreaming: () => void; +} + type UpdateDateRangeFn = ( newDateRange: Partial> ) => void; @@ -54,7 +76,7 @@ export const useLogPositionState = ({ logStreamPageState, logStreamPageCallbacks, }: { - logStreamPageState: InitializedLogStreamPageState; + logStreamPageState: LogStreamPageState; logStreamPageCallbacks: LogStreamPageCallbacks; }): LogPositionStateParams & LogPositionCallbacks => { const dateRange = useMemo(() => getLegacyDateRange(logStreamPageState), [logStreamPageState]); @@ -119,7 +141,7 @@ export const useLogPositionState = ({ export const [LogPositionStateProvider, useLogPositionStateContext] = createContainer(useLogPositionState); -const getLegacyDateRange = (logStreamPageState: InitializedLogStreamPageState): DateRange => { +const getLegacyDateRange = (logStreamPageState: LogStreamPageState): DateRange => { return { startDateExpression: logStreamPageState.context.timeRange.from, endDateExpression: logStreamPageState.context.timeRange.to, @@ -130,8 +152,3 @@ const getLegacyDateRange = (logStreamPageState: InitializedLogStreamPageState): timestampsLastUpdate: logStreamPageState.context.timestamps.lastChangedTimestamp, }; }; - -type InitializedLogStreamPageState = MatchedStateFromActor< - LogStreamPageActorRef, - { hasLogViewIndices: 'initialized' } ->; diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_after.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_after.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_around.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_around.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_before.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_stream/use_fetch_log_entries_before.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/api/fetch_log_summary.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/api/fetch_log_summary.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/bucket_size.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/bucket_size.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/bucket_size.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/bucket_size.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/index.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/index.ts similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/index.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/index.ts diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.test.tsx similarity index 100% rename from x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.test.tsx diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.tsx similarity index 97% rename from x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.tsx index c2792300c5f34..0360d6d381ada 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/log_summary.tsx @@ -8,7 +8,7 @@ import { useEffect } from 'react'; import { exhaustMap, map, Observable } from 'rxjs'; import { HttpHandler } from '@kbn/core-http-browser'; -import { LogViewReference } from '../../../../common/log_views'; +import { LogViewReference } from '../../../../common'; import { useObservableState, useReplaySubject } from '../../../utils/use_observable'; import { fetchLogSummary } from './api/fetch_log_summary'; import { LogEntriesSummaryRequest, LogEntriesSummaryResponse } from '../../../../common/http_api'; diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/with_summary.ts similarity index 66% rename from x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts rename to x-pack/plugins/logs_shared/public/containers/logs/log_summary/with_summary.ts index 1dc5c7021d253..5d18926cca294 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts +++ b/x-pack/plugins/logs_shared/public/containers/logs/log_summary/with_summary.ts @@ -5,32 +5,24 @@ * 2.0. */ -import { useSelector } from '@xstate/react'; -import stringify from 'json-stable-stringify'; import useThrottle from 'react-use/lib/useThrottle'; -import { useLogViewContext } from '../../../hooks/use_log_view'; -import { useLogStreamPageStateContext } from '../../../observability_logs/log_stream_page/state'; +import { useLogPositionStateContext, useLogViewContext } from '../../..'; import { RendererFunction } from '../../../utils/typed_react'; -import { useLogPositionStateContext } from '../log_position'; import { LogSummaryBuckets, useLogSummary } from './log_summary'; const FETCH_THROTTLE_INTERVAL = 3000; -export const WithSummary = ({ - children, -}: { +export interface WithSummaryProps { + serializedParsedQuery: string | null; children: RendererFunction<{ buckets: LogSummaryBuckets; start: number | null; end: number | null; }>; -}) => { +} + +export const WithSummary = ({ serializedParsedQuery, children }: WithSummaryProps) => { const { logViewReference } = useLogViewContext(); - const serializedParsedQuery = useSelector(useLogStreamPageStateContext(), (logStreamPageState) => - logStreamPageState.matches({ hasLogViewIndices: 'initialized' }) - ? stringify(logStreamPageState.context.parsedQuery) - : null - ); const { startTimestamp, endTimestamp } = useLogPositionStateContext(); // Keep it reasonably updated for the `now` case, but don't reload all the time when the user scrolls diff --git a/x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx b/x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx new file mode 100644 index 0000000000000..09032b4b644a2 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/hooks/use_kibana.tsx @@ -0,0 +1,71 @@ +/* + * 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 { PropsOf } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { CoreStart } from '@kbn/core/public'; +import { + createKibanaReactContext, + KibanaReactContextValue, + useKibana, +} from '@kbn/kibana-react-plugin/public'; +import { + LogsSharedClientCoreSetup, + LogsSharedClientStartDeps, + LogsSharedClientStartExports, +} from '../types'; + +export type PluginKibanaContextValue = CoreStart & + LogsSharedClientStartDeps & + LogsSharedClientStartExports; + +export const createKibanaContextForPlugin = ( + core: CoreStart, + plugins: LogsSharedClientStartDeps, + pluginStart: LogsSharedClientStartExports +) => + createKibanaReactContext({ + ...core, + ...plugins, + ...pluginStart, + }); + +export const useKibanaContextForPlugin = + useKibana as () => KibanaReactContextValue; + +export const useKibanaContextForPluginProvider = ( + core: CoreStart, + plugins: LogsSharedClientStartDeps, + pluginStart: LogsSharedClientStartExports +) => { + const { Provider } = useMemo( + () => createKibanaContextForPlugin(core, plugins, pluginStart), + [core, pluginStart, plugins] + ); + + return Provider; +}; + +export const createLazyComponentWithKibanaContext = >( + coreSetup: LogsSharedClientCoreSetup, + lazyComponentFactory: () => Promise<{ default: T }> +) => + React.lazy(() => + Promise.all([lazyComponentFactory(), coreSetup.getStartServices()]).then( + ([{ default: LazilyLoadedComponent }, [core, plugins, pluginStart]]) => { + const { Provider } = createKibanaContextForPlugin(core, plugins, pluginStart); + + return { + default: (props: PropsOf) => ( + + + + ), + }; + } + ) + ); diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/logs_shared/public/hooks/use_log_view.ts similarity index 100% rename from x-pack/plugins/infra/public/hooks/use_log_view.ts rename to x-pack/plugins/logs_shared/public/hooks/use_log_view.ts diff --git a/x-pack/plugins/logs_shared/public/index.ts b/x-pack/plugins/logs_shared/public/index.ts new file mode 100644 index 0000000000000..63692bbdeae54 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/index.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 { dynamic } from '../common/dynamic'; +import { LogsSharedPlugin } from './plugin'; + +export type { + LogsSharedClientSetupExports, + LogsSharedClientStartExports, + LogsSharedClientSetupDeps, + LogsSharedClientStartDeps, +} from './types'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. +export function plugin() { + return new LogsSharedPlugin(); +} + +// Containers & Hook +export { LogViewProvider, useLogViewContext, useLogView } from './hooks/use_log_view'; +export { LogStreamProvider, useLogStreamContext } from './containers/logs/log_stream'; +export { + LogPositionStateProvider, + useLogPositionStateContext, +} from './containers/logs/log_position'; +export { + LogHighlightsStateProvider, + useLogHighlightsStateContext, +} from './containers/logs/log_highlights'; +export type { LogSummaryBuckets, WithSummaryProps } from './containers/logs/log_summary'; +export { useLogSummary, WithSummary } from './containers/logs/log_summary'; +export { useLogEntryFlyout } from './components/logging/log_entry_flyout'; + +// Shared components +export type { + LogEntryStreamItem, + LogEntryColumnWidths, +} from './components/logging/log_text_stream'; +export { + iconColumnId, + useColumnWidths, +} from './components/logging/log_text_stream/log_entry_column'; +export { LogEntryFlyout } from './components/logging/log_entry_flyout'; +export type { LogStreamProps } from './components/log_stream/log_stream'; + +export const LogStream = dynamic(() => import('./components/log_stream/log_stream')); +export const LogColumnHeader = dynamic( + () => import('./components/logging/log_text_stream/column_headers') +); +export const LogColumnHeadersWrapper = dynamic( + () => import('./components/logging/log_text_stream/column_headers') +); +export const LogEntryColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_column') +); +export const LogEntryContextMenu = dynamic( + () => import('./components/logging/log_text_stream/log_entry_context_menu') +); +export const LogEntryFieldColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_field_column') +); +export const LogEntryMessageColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_message_column') +); +export const LogEntryRowWrapper = dynamic( + () => import('./components/logging/log_text_stream/log_entry_row') +); +export const LogEntryTimestampColumn = dynamic( + () => import('./components/logging/log_text_stream/log_entry_timestamp_column') +); +export const ScrollableLogTextStreamView = dynamic( + () => import('./components/logging/log_text_stream/scrollable_log_text_stream_view') +); + +// State machine utils +export { + getLogViewReferenceFromUrl, + initializeFromUrl, + listenForUrlChanges, + updateContextInUrl, +} from './observability_logs/log_view_state'; +export type { + LogViewContextWithError, + LogViewContextWithResolvedLogView, + LogViewNotificationChannel, + LogViewNotificationEvent, +} from './observability_logs/log_view_state'; diff --git a/x-pack/plugins/logs_shared/public/mocks.tsx b/x-pack/plugins/logs_shared/public/mocks.tsx new file mode 100644 index 0000000000000..963480d8fd90f --- /dev/null +++ b/x-pack/plugins/logs_shared/public/mocks.tsx @@ -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 { createLogViewsServiceStartMock } from './services/log_views/log_views_service.mock'; +import { LogsSharedClientStartExports } from './types'; + +export const createLogsSharedPluginStartMock = (): jest.Mocked => ({ + logViews: createLogViewsServiceStartMock(), +}); + +export const _ensureTypeCompatibility = (): LogsSharedClientStartExports => + createLogsSharedPluginStartMock(); diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/README.md b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/README.md similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/README.md rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/README.md diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/index.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/index.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/index.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/index.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/index.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/notifications.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/notifications.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/state_machine.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/state_machine.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/types.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/types.ts diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts b/x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/url_state_storage_service.ts similarity index 100% rename from x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts rename to x-pack/plugins/logs_shared/public/observability_logs/log_view_state/src/url_state_storage_service.ts diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md new file mode 100644 index 0000000000000..337f65add4226 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/README.md @@ -0,0 +1,3 @@ +# @kbn/observability-logs-xstate-helpers + +Helpers to design well-typed state machines with XState diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/index.ts new file mode 100644 index 0000000000000..3b2a320ae181f --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/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 './src'; diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/index.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/index.ts new file mode 100644 index 0000000000000..340087bb31fc8 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/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 './notification_channel'; +export * from './types'; diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts new file mode 100644 index 0000000000000..0108ab0225176 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/notification_channel.ts @@ -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 { ReplaySubject } from 'rxjs'; +import { ActionFunction, EventObject, Expr, Subscribable } from 'xstate'; + +export interface NotificationChannel { + createService: () => Subscribable; + notify: ( + eventExpr: Expr + ) => ActionFunction; +} + +export const createNotificationChannel = < + TContext, + TEvent extends EventObject, + TSentEvent +>(): NotificationChannel => { + const eventsSubject = new ReplaySubject(1); + + const createService = () => eventsSubject.asObservable(); + + const notify = + (eventExpr: Expr) => + (context: TContext, event: TEvent) => { + const eventToSend = eventExpr(context, event); + + if (eventToSend != null) { + eventsSubject.next(eventToSend); + } + }; + + return { + createService, + notify, + }; +}; diff --git a/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.ts b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.ts new file mode 100644 index 0000000000000..05e75c5fe6e45 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/observability_logs/xstate_helpers/src/types.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 type { ActorRef, ActorRefWithDeprecatedState, EmittedFrom, State, StateValue } from 'xstate'; + +export type OmitDeprecatedState> = Omit< + T, + 'state' +>; + +export type MatchedState< + TState extends State, + TStateValue extends StateValue +> = TState extends State< + any, + infer TEvent, + infer TStateSchema, + infer TTypestate, + infer TResolvedTypesMeta +> + ? State< + (TTypestate extends any + ? { value: TStateValue; context: any } extends TTypestate + ? TTypestate + : never + : never)['context'], + TEvent, + TStateSchema, + TTypestate, + TResolvedTypesMeta + > & { + value: TStateValue; + } + : never; + +export type MatchedStateFromActor< + TActorRef extends ActorRef, + TStateValue extends StateValue +> = MatchedState, TStateValue>; diff --git a/x-pack/plugins/logs_shared/public/plugin.ts b/x-pack/plugins/logs_shared/public/plugin.ts new file mode 100644 index 0000000000000..47ded2e3df835 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/plugin.ts @@ -0,0 +1,38 @@ +/* + * 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 { CoreStart } from '@kbn/core/public'; +import { LogViewsService } from './services/log_views'; +import { LogsSharedClientPluginClass, LogsSharedClientStartDeps } from './types'; + +export class LogsSharedPlugin implements LogsSharedClientPluginClass { + private logViews: LogViewsService; + + constructor() { + this.logViews = new LogViewsService(); + } + + public setup() { + const logViews = this.logViews.setup(); + + return { logViews }; + } + + public start(core: CoreStart, plugins: LogsSharedClientStartDeps) { + const logViews = this.logViews.start({ + http: core.http, + dataViews: plugins.dataViews, + search: plugins.data.search, + }); + + return { + logViews, + }; + } + + public stop() {} +} diff --git a/x-pack/plugins/infra/public/services/log_views/index.ts b/x-pack/plugins/logs_shared/public/services/log_views/index.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/index.ts rename to x-pack/plugins/logs_shared/public/services/log_views/index.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_client.mock.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_client.mock.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/log_views_client.mock.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_client.mock.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_client.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/log_views_client.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_client.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_service.mock.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_service.mock.ts similarity index 100% rename from x-pack/plugins/infra/public/services/log_views/log_views_service.mock.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_service.mock.ts diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_service.ts b/x-pack/plugins/logs_shared/public/services/log_views/log_views_service.ts similarity index 61% rename from x-pack/plugins/infra/public/services/log_views/log_views_service.ts rename to x-pack/plugins/logs_shared/public/services/log_views/log_views_service.ts index 9e081a8df5028..712196c95205c 100644 --- a/x-pack/plugins/infra/public/services/log_views/log_views_service.ts +++ b/x-pack/plugins/logs_shared/public/services/log_views/log_views_service.ts @@ -5,17 +5,23 @@ * 2.0. */ -import { LogViewsStaticConfig } from '../../../common/log_views'; +import { defaultLogViewsStaticConfig, LogViewsStaticConfig } from '../../../common/log_views'; import { LogViewsClient } from './log_views_client'; import { LogViewsServiceStartDeps, LogViewsServiceSetup, LogViewsServiceStart } from './types'; export class LogViewsService { - constructor(private readonly config: LogViewsStaticConfig) {} + private logViewsStaticConfig: LogViewsStaticConfig = defaultLogViewsStaticConfig; - public setup(): LogViewsServiceSetup {} + public setup(): LogViewsServiceSetup { + return { + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => { + this.logViewsStaticConfig = config; + }, + }; + } public start({ dataViews, http, search }: LogViewsServiceStartDeps): LogViewsServiceStart { - const client = new LogViewsClient(dataViews, http, search.search, this.config); + const client = new LogViewsClient(dataViews, http, search.search, this.logViewsStaticConfig); return { client, diff --git a/x-pack/plugins/infra/public/services/log_views/types.ts b/x-pack/plugins/logs_shared/public/services/log_views/types.ts similarity index 90% rename from x-pack/plugins/infra/public/services/log_views/types.ts rename to x-pack/plugins/logs_shared/public/services/log_views/types.ts index 6fd7a4d208b3c..58a504be789bc 100644 --- a/x-pack/plugins/infra/public/services/log_views/types.ts +++ b/x-pack/plugins/logs_shared/public/services/log_views/types.ts @@ -12,11 +12,14 @@ import { LogView, LogViewAttributes, LogViewReference, + LogViewsStaticConfig, LogViewStatus, ResolvedLogView, } from '../../../common/log_views'; -export type LogViewsServiceSetup = void; +export interface LogViewsServiceSetup { + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => void; +} export interface LogViewsServiceStart { client: ILogViewsClient; diff --git a/x-pack/plugins/logs_shared/public/test_utils/entries.ts b/x-pack/plugins/logs_shared/public/test_utils/entries.ts new file mode 100644 index 0000000000000..4dc3732fd49d5 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/test_utils/entries.ts @@ -0,0 +1,75 @@ +/* + * 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 faker from 'faker'; +import { LogEntry } from '../../common/log_entry'; +import { LogViewColumnConfiguration } from '../../common/log_views'; + +export const ENTRIES_EMPTY = { + data: { + entries: [], + topCursor: null, + bottomCursor: null, + }, +}; + +export function generateFakeEntries( + count: number, + startTimestamp: number, + endTimestamp: number, + columns: LogViewColumnConfiguration[] +): LogEntry[] { + const entries: LogEntry[] = []; + const timestampStep = Math.floor((endTimestamp - startTimestamp) / count); + for (let i = 0; i < count; i++) { + const timestamp = i === count - 1 ? endTimestamp : startTimestamp + timestampStep * i; + entries.push({ + id: `entry-${i}`, + index: 'logs-fake', + context: {}, + cursor: { time: timestamp, tiebreaker: i }, + columns: columns.map((column) => { + if ('timestampColumn' in column) { + return { columnId: column.timestampColumn.id, timestamp }; + } else if ('messageColumn' in column) { + return { + columnId: column.messageColumn.id, + message: [{ field: 'message', value: [fakeColumnValue('message')], highlights: [] }], + }; + } else { + return { + columnId: column.fieldColumn.id, + field: column.fieldColumn.field, + value: [fakeColumnValue(column.fieldColumn.field)], + highlights: [], + }; + } + }), + }); + } + + return entries; +} + +function fakeColumnValue(field: string): string { + switch (field) { + case 'message': + return faker.fake( + '{{internet.ip}} - [{{date.past}}] "GET {{internet.url}} HTTP/1.1" 200 {{random.number}} "-" "{{internet.userAgent}}"' + ); + case 'event.dataset': + return faker.fake('{{hacker.noun}}.{{hacker.noun}}'); + case 'log.file.path': + return faker.system.filePath(); + case 'log.level': + return faker.random.arrayElement(['debug', 'info', 'warn', 'error']); + case 'host.name': + return faker.hacker.noun(); + default: + return faker.lorem.sentence(); + } +} diff --git a/x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx b/x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx new file mode 100644 index 0000000000000..4d1feb4617dcf --- /dev/null +++ b/x-pack/plugins/logs_shared/public/test_utils/use_global_storybook_theme.tsx @@ -0,0 +1,59 @@ +/* + * 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 { DecoratorFn } from '@storybook/react'; +import React, { useEffect, useMemo, useState } from 'react'; +import { BehaviorSubject } from 'rxjs'; +import type { CoreTheme } from '@kbn/core/public'; +import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; + +type StoryContext = Parameters[1]; + +export const useGlobalStorybookTheme = ({ globals: { euiTheme } }: StoryContext) => { + const theme = useMemo(() => euiThemeFromId(euiTheme), [euiTheme]); + const [theme$] = useState(() => new BehaviorSubject(theme)); + + useEffect(() => { + theme$.next(theme); + }, [theme$, theme]); + + return { + theme, + theme$, + }; +}; + +export const GlobalStorybookThemeProviders: React.FC<{ storyContext: StoryContext }> = ({ + children, + storyContext, +}) => { + const { theme, theme$ } = useGlobalStorybookTheme(storyContext); + return ( + + {children} + + ); +}; + +export const decorateWithGlobalStorybookThemeProviders: DecoratorFn = ( + wrappedStory, + storyContext +) => ( + + {wrappedStory()} + +); + +const euiThemeFromId = (themeId: string): CoreTheme => { + switch (themeId) { + case 'v8.dark': + return { darkMode: true }; + default: + return { darkMode: false }; + } +}; diff --git a/x-pack/plugins/logs_shared/public/types.ts b/x-pack/plugins/logs_shared/public/types.ts new file mode 100644 index 0000000000000..f2563ccb3433f --- /dev/null +++ b/x-pack/plugins/logs_shared/public/types.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. + */ + +/* + * 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 { CoreSetup, CoreStart, Plugin as PluginClass } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +// import type { OsqueryPluginStart } from '../../osquery/public'; +import { LogViewsServiceSetup, LogViewsServiceStart } from './services/log_views'; + +// Our own setup and start contract values +export interface LogsSharedClientSetupExports { + logViews: LogViewsServiceSetup; +} + +export interface LogsSharedClientStartExports { + logViews: LogViewsServiceStart; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface LogsSharedClientSetupDeps {} + +export interface LogsSharedClientStartDeps { + data: DataPublicPluginStart; + dataViews: DataViewsPublicPluginStart; + uiActions: UiActionsStart; +} + +export type LogsSharedClientCoreSetup = CoreSetup< + LogsSharedClientStartDeps, + LogsSharedClientStartExports +>; +export type LogsSharedClientCoreStart = CoreStart; +export type LogsSharedClientPluginClass = PluginClass< + LogsSharedClientSetupExports, + LogsSharedClientStartExports, + LogsSharedClientSetupDeps, + LogsSharedClientStartDeps +>; + +export type UnwrapPromise> = T extends Promise ? Value : never; + +export type LogsSharedClientStartServicesAccessor = LogsSharedClientCoreSetup['getStartServices']; +export type LogsSharedClientStartServices = UnwrapPromise< + ReturnType +>; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx b/x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx new file mode 100644 index 0000000000000..a8854692caa36 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/data_search.stories.mdx @@ -0,0 +1,152 @@ +import { Canvas, Meta, Story } from '@storybook/addon-docs/blocks'; + + + +# The `data` plugin and `SearchStrategies` + +The search functionality abstraction provided by the `search` service of the +`data` plugin is pretty powerful: + +- The execution of the request is delegated to a search strategy, which is + executed on the Kibana server side. +- Any plugin can register custom search strategies with custom parameters and + response shapes. +- Search requests can be cancelled via an `AbortSignal`. +- Search requests are decoupled from the transport layer. The service will poll + for new results transparently. +- Partial responses can be returned as they become available if the search + takes longer. + +# Working with `data.search.search()` in the Browser + +The following chapters describe a set of React components and hooks that aim to +make it easy to take advantage of these characteristics from client-side React +code. They implement a producer/consumer pattern that decouples the craeation +of search requests from the consumption of the responses. This keeps each +code-path small and encourages the use of reactive processing, which in turn +reduces the risk of race conditions and incorrect assumptions about the +response timing. + +## Issuing new requests + +The main API to issue new requests is the `data.search.search()` function. It +returns an `Observable` representing the stream of partial and final results +without the consumer having to know the underlying transport mechanisms. +Besides receiving a search-strategy-specific parameter object, it supports +selection of the search strategy as well an `AbortSignal` used for request +cancellation. + +The hook `useDataSearch()` is designed to ease the integration between the +`Observable` world and the React world. It uses the function it is given to +derive the parameters to use for the next search request. The request can then +be issued by calling the returned `search()` function. For each new request the +hook emits an object describing the request and its state in the `requests$` +`Observable`. + +Since the specific response shape depends on the data strategy used, the hook +takes a projection function, that is responsible for decoding the response in +an appropriate way. Because most response projections follow a similar pattern +there's a helper `normalizeDataSearchResponses(initialResponse, +parseRawResponse)`, which generates an RxJS operator, that... + +- emits an initial response containing the given `initialResponse` value +- applies `parseRawResponse` to the `rawResponse` property of each emitted response +- transforms transport layer errors as well as parsing errors into + `SearchStrategyError`s + +```typescript +const parseMyCustomSearchResponse = normalizeDataSearchResponses( + 'initial value', + decodeOrThrow(myCustomSearchResponsePayloadRT) +); + +const { search, requests$ } = useDataSearch({ + getRequest: useCallback((searchTerm: string) => ({ + request: { + params: { + searchTerm + }, + options: { + strategy: 'my-custom-search-strategy', + }, + }, + }), []), + parseResponses: parseMyCustomSearchResponse, +}); +``` + +## Executing requests and consuming the responses + +The response `Observable`s emitted by `data.search.search()` is "cold", so it +won't be executed unless a subscriber subscribes to it. And in order to cleanly +cancel and garbage collect the subscription it should be integrated with the +React component life-cycle. + +The `useLatestPartialDataSearchResponse()` does that in such a way that the +newest response observable is subscribed to and that any previous response +observables are unsubscribed from for proper cancellation if a new request has +been created. This uses RxJS's `switchMap()` operator under the hood. The hook +also makes sure that all observables are unsubscribed from on unmount. + +A request can fail due to various reasons that include servers-side errors, +Elasticsearch shard failures and network failures. The intention is to map all +of them to a common `SearchStrategyError` interface. While the +`useLatestPartialDataSearchResponse()` hook does that for errors emitted +natively by the response `Observable`, it's the responsibility of the +projection function to handle errors that are encoded in the response body, +which includes most server-side errors. Note that errors and partial results in +a response are not mutually exclusive. + +The request status (running, partial, etc), the response +and the errors are turned in to React component state so they can be used in +the usual rendering cycle: + +```typescript +const { + cancelRequest, + isRequestRunning, + isResponsePartial, + latestResponseData, + latestResponseErrors, + loaded, + total, +} = useLatestPartialDataSearchResponse(requests$); +``` + +## Representing the request state to the user + +After the values have been made available to the React rendering process using +the `useLatestPartialDataSearchResponse()` hook, normal component hierarchies +can be used to make the request state and result available to the user. The +following utility components can make that even easier. + +### Undetermined progress + +If `total` and `loaded` are not (yet) known, we can show an undetermined +progress bar. + + + + + +### Known progress + +If `total` and `loaded` are returned by the search strategy, they can be used +to show a progress bar with the option to cancel the request if it takes too +long. + + + + + +### Failed requests + +Assuming the errors are represented as an array of `SearchStrategyError`s in +the `latestResponseErrors` return value, they can be rendered as appropriate +for the respective part of the UI. For many cases a `EuiCallout` is suitable, +so the `DataSearchErrorCallout` can serve as a starting point: + + + + + diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts b/x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts new file mode 100644 index 0000000000000..52f08f39bc2d4 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/flatten_data_search_response.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { map } from 'rxjs/operators'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { ParsedDataSearchRequestDescriptor } from './types'; + +export const flattenDataSearchResponseDescriptor = < + Request extends IKibanaSearchRequest, + Response +>({ + abortController, + options, + request, + response$, +}: ParsedDataSearchRequestDescriptor) => + response$.pipe( + map((response) => { + return { + abortController, + options, + request, + response, + }; + }) + ); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/index.ts b/x-pack/plugins/logs_shared/public/utils/data_search/index.ts new file mode 100644 index 0000000000000..bd1881a6935e9 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './flatten_data_search_response'; +export * from './normalize_data_search_responses'; +export * from './types'; +export * from './use_data_search_request'; +export * from './use_data_search_response_state'; +export * from './use_latest_partial_data_search_response'; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts b/x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts new file mode 100644 index 0000000000000..0056b7466759a --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/normalize_data_search_responses.ts @@ -0,0 +1,81 @@ +/* + * 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 { Observable, of } from 'rxjs'; +import { catchError, map, startWith } from 'rxjs/operators'; +import { IKibanaSearchResponse } from '@kbn/data-plugin/public'; +import { AbortError } from '@kbn/kibana-utils-plugin/public'; +import { SearchStrategyError } from '../../../common/search_strategies/common/errors'; +import { ParsedKibanaSearchResponse } from './types'; + +export type RawResponseParser = (rawResponse: RawResponse) => { + data: Response; + errors?: SearchStrategyError[]; +}; + +/** + * An operator factory that normalizes each {@link IKibanaSearchResponse} by + * parsing it into a {@link ParsedKibanaSearchResponse} and adding initial + * responses and error handling. + * + * @param initialResponse - The initial value to emit when a new request is + * handled. + * @param projectResponse - The projection function to apply to each response + * payload. It should validate that the response payload is of the type {@link + * RawResponse} and decode it to a {@link Response}. + * + * @return An operator that adds parsing and error handling transformations to + * each response payload using the arguments given above. + */ +export const normalizeDataSearchResponses = + ( + initialResponse: InitialResponse, + parseRawResponse: RawResponseParser + ) => + ( + response$: Observable> + ): Observable> => + response$.pipe( + map((response) => { + const { data, errors = [] } = parseRawResponse(response.rawResponse); + return { + data, + errors, + isPartial: response.isPartial ?? false, + isRunning: response.isRunning ?? false, + loaded: response.loaded, + total: response.total, + }; + }), + startWith({ + data: initialResponse, + errors: [], + isPartial: true, + isRunning: true, + loaded: 0, + total: undefined, + }), + catchError((error) => + of({ + data: initialResponse, + errors: [ + error instanceof AbortError + ? { + type: 'aborted' as const, + } + : { + type: 'generic' as const, + message: `${error.message ?? error}`, + }, + ], + isPartial: true, + isRunning: false, + loaded: 0, + total: undefined, + }) + ) + ); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/types.ts b/x-pack/plugins/logs_shared/public/utils/data_search/types.ts new file mode 100644 index 0000000000000..3e2c6a15487b8 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/types.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 { Observable } from 'rxjs'; +import { + IKibanaSearchRequest, + IKibanaSearchResponse, + ISearchOptions, +} from '@kbn/data-plugin/public'; +import { SearchStrategyError } from '../../../common/search_strategies/common/errors'; + +export interface DataSearchRequestDescriptor { + request: Request; + options: ISearchOptions; + response$: Observable>; + abortController: AbortController; +} + +export interface ParsedDataSearchRequestDescriptor< + Request extends IKibanaSearchRequest, + ResponseData +> { + request: Request; + options: ISearchOptions; + response$: Observable>; + abortController: AbortController; +} + +export interface ParsedKibanaSearchResponse { + total?: number; + loaded?: number; + isRunning: boolean; + isPartial: boolean; + data: ResponseData; + errors: SearchStrategyError[]; +} + +export interface ParsedDataSearchResponseDescriptor< + Request extends IKibanaSearchRequest, + Response +> { + request: Request; + options: ISearchOptions; + response: ParsedKibanaSearchResponse; + abortController: AbortController; +} diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx new file mode 100644 index 0000000000000..06f8ca1b82eb7 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.test.tsx @@ -0,0 +1,198 @@ +/* + * 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 { act, renderHook } from '@testing-library/react-hooks'; +import React from 'react'; +import { firstValueFrom, Observable, of, Subject } from 'rxjs'; +import { + DataPublicPluginStart, + IKibanaSearchResponse, + ISearchGeneric, + ISearchStart, +} from '@kbn/data-plugin/public'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; +import { PluginKibanaContextValue } from '../../hooks/use_kibana'; +import { normalizeDataSearchResponses } from './normalize_data_search_responses'; +import { useDataSearch } from './use_data_search_request'; + +describe('useDataSearch hook', () => { + it('forwards the search function arguments to the getRequest function', async () => { + const dataMock = createDataPluginMock(); + const { Provider: KibanaContextProvider } = createKibanaReactContext< + Partial + >({ + data: dataMock, + }); + + const getRequest = jest.fn((_firstArgument: string, _secondArgument: string) => null); + + const { result } = renderHook( + () => + useDataSearch({ + getRequest, + parseResponses: noopParseResponse, + }), + { + wrapper: ({ children }) => {children}, + } + ); + + act(() => { + result.current.search('first', 'second'); + }); + + expect(getRequest).toHaveBeenLastCalledWith('first', 'second'); + expect(dataMock.search.search).not.toHaveBeenCalled(); + }); + + it('creates search requests with the given params and options and parses the responses', async () => { + const dataMock = createDataPluginMock(); + const searchResponseMock$ = of({ + rawResponse: { + firstKey: 'firstValue', + }, + }); + dataMock.search.search.mockReturnValue(searchResponseMock$); + const { Provider: KibanaContextProvider } = createKibanaReactContext< + Partial + >({ + data: dataMock, + }); + + const getRequest = jest.fn((firstArgument: string, secondArgument: string) => ({ + request: { + params: { + firstArgument, + secondArgument, + }, + }, + options: { + strategy: 'test-search-strategy', + }, + })); + + const { result } = renderHook( + () => + useDataSearch({ + getRequest, + parseResponses: noopParseResponse, + }), + { + wrapper: ({ children }) => {children}, + } + ); + + // the request execution is lazy + expect(dataMock.search.search).not.toHaveBeenCalled(); + + // execute requests$ observable + const firstRequestPromise = firstValueFrom(result.current.requests$); + + act(() => { + result.current.search('first', 'second'); + }); + + const firstRequest = await firstRequestPromise; + + expect(dataMock.search.search).toHaveBeenLastCalledWith( + { + params: { firstArgument: 'first', secondArgument: 'second' }, + }, + { + abortSignal: expect.any(Object), + strategy: 'test-search-strategy', + } + ); + expect(firstRequest).toHaveProperty('abortController', expect.any(Object)); + expect(firstRequest).toHaveProperty('request.params', { + firstArgument: 'first', + secondArgument: 'second', + }); + expect(firstRequest).toHaveProperty('options.strategy', 'test-search-strategy'); + expect(firstRequest).toHaveProperty('response$', expect.any(Observable)); + await expect(firstRequest.response$.toPromise()).resolves.toMatchObject({ + data: { + firstKey: 'firstValue', // because this specific response parser just copies the raw response + }, + errors: [], + }); + }); + + it('aborts the request when the response observable looses the last subscriber', async () => { + const dataMock = createDataPluginMock(); + const searchResponseMock$ = new Subject(); + dataMock.search.search.mockReturnValue(searchResponseMock$); + const { Provider: KibanaContextProvider } = createKibanaReactContext< + Partial + >({ + data: dataMock, + }); + + const getRequest = jest.fn((firstArgument: string, secondArgument: string) => ({ + request: { + params: { + firstArgument, + secondArgument, + }, + }, + options: { + strategy: 'test-search-strategy', + }, + })); + + const { result } = renderHook( + () => + useDataSearch({ + getRequest, + parseResponses: noopParseResponse, + }), + { + wrapper: ({ children }) => {children}, + } + ); + + // the request execution is lazy + expect(dataMock.search.search).not.toHaveBeenCalled(); + + // execute requests$ observable + const firstRequestPromise = firstValueFrom(result.current.requests$); + + act(() => { + result.current.search('first', 'second'); + }); + + const firstRequest = await firstRequestPromise; + + // execute requests$ observable + const firstResponseSubscription = firstRequest.response$.subscribe({ + next: jest.fn(), + }); + + // get the abort signal + const [, firstRequestOptions] = dataMock.search.search.mock.calls[0]; + + expect(firstRequestOptions?.abortSignal?.aborted).toBe(false); + + // unsubscribe + firstResponseSubscription.unsubscribe(); + + expect(firstRequestOptions?.abortSignal?.aborted).toBe(true); + }); +}); + +const createDataPluginMock = () => { + const dataMock = dataPluginMock.createStartContract() as DataPublicPluginStart & { + search: ISearchStart & { search: jest.MockedFunction }; + }; + return dataMock; +}; + +const noopParseResponse = normalizeDataSearchResponses( + null, + (response: Response) => ({ data: response }) +); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts new file mode 100644 index 0000000000000..230c2d87e0654 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_request.ts @@ -0,0 +1,104 @@ +/* + * 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 { useCallback } from 'react'; +import { OperatorFunction, ReplaySubject } from 'rxjs'; +import { share, tap } from 'rxjs/operators'; +import { + IKibanaSearchRequest, + IKibanaSearchResponse, + ISearchOptions, +} from '@kbn/data-plugin/public'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; +import { tapUnsubscribe, useObservable } from '../use_observable'; +import { ParsedDataSearchRequestDescriptor, ParsedKibanaSearchResponse } from './types'; + +export type DataSearchRequestFactory = ( + ...args: Args +) => + | { + request: Request; + options: ISearchOptions; + } + | null + | undefined; + +type ParseResponsesOperator = OperatorFunction< + IKibanaSearchResponse, + ParsedKibanaSearchResponse +>; + +export const useDataSearch = < + RequestFactoryArgs extends any[], + RequestParams, + Request extends IKibanaSearchRequest, + RawResponse, + Response +>({ + getRequest, + parseResponses, +}: { + getRequest: DataSearchRequestFactory; + parseResponses: ParseResponsesOperator; +}) => { + const { services } = useKibanaContextForPlugin(); + const requests$ = useObservable( + () => new ReplaySubject>(1), + [] + ); + + const search = useCallback( + (...args: RequestFactoryArgs) => { + const requestArgs = getRequest(...args); + + if (requestArgs == null) { + return; + } + + const abortController = new AbortController(); + let isAbortable = true; + + const newRequestDescriptor = { + ...requestArgs, + abortController, + response$: services.data.search + .search>(requestArgs.request, { + abortSignal: abortController.signal, + ...requestArgs.options, + }) + .pipe( + // avoid aborting failed or completed requests + tap({ + error: () => { + isAbortable = false; + }, + complete: () => { + isAbortable = false; + }, + }), + tapUnsubscribe(() => { + if (isAbortable) { + abortController.abort(); + } + }), + parseResponses, + share() + ), + }; + + requests$.next(newRequestDescriptor); + + return newRequestDescriptor; + }, + [getRequest, services.data.search, parseResponses, requests$] + ); + + return { + requests$, + search, + }; +}; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts new file mode 100644 index 0000000000000..c8ec672beb842 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_data_search_response_state.ts @@ -0,0 +1,36 @@ +/* + * 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 { useCallback } from 'react'; +import { Observable } from 'rxjs'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { useObservableState } from '../use_observable'; +import { ParsedDataSearchResponseDescriptor } from './types'; + +export const useDataSearchResponseState = < + Request extends IKibanaSearchRequest, + Response, + InitialResponse +>( + response$: Observable> +) => { + const { latestValue } = useObservableState(response$, undefined); + + const cancelRequest = useCallback(() => { + latestValue?.abortController.abort(); + }, [latestValue]); + + return { + cancelRequest, + isRequestRunning: latestValue?.response.isRunning ?? false, + isResponsePartial: latestValue?.response.isPartial ?? false, + latestResponseData: latestValue?.response.data, + latestResponseErrors: latestValue?.response.errors, + loaded: latestValue?.response.loaded, + total: latestValue?.response.total, + }; +}; diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx new file mode 100644 index 0000000000000..a48cf2c7ccdc4 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.test.tsx @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act, renderHook } from '@testing-library/react-hooks'; +import { BehaviorSubject, Observable, of, Subject } from 'rxjs'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { ParsedDataSearchRequestDescriptor, ParsedKibanaSearchResponse } from './types'; +import { useLatestPartialDataSearchResponse } from './use_latest_partial_data_search_response'; + +describe('useLatestPartialDataSearchResponse hook', () => { + it("subscribes to the latest request's response observable", () => { + const firstRequest = { + abortController: new AbortController(), + options: {}, + request: { params: 'firstRequestParam' }, + response$: new BehaviorSubject>({ + data: 'initial', + isRunning: true, + isPartial: true, + errors: [], + }), + }; + + const secondRequest = { + abortController: new AbortController(), + options: {}, + request: { params: 'secondRequestParam' }, + response$: new BehaviorSubject>({ + data: 'initial', + isRunning: true, + isPartial: true, + errors: [], + }), + }; + + const requests$ = new Subject< + ParsedDataSearchRequestDescriptor, string> + >(); + + const { result } = renderHook(() => useLatestPartialDataSearchResponse(requests$)); + + expect(result).toHaveProperty('current.isRequestRunning', false); + expect(result).toHaveProperty('current.latestResponseData', undefined); + + // first request is started + act(() => { + requests$.next(firstRequest); + }); + + expect(result).toHaveProperty('current.isRequestRunning', true); + expect(result).toHaveProperty('current.latestResponseData', 'initial'); + + // first response of the first request arrives + act(() => { + firstRequest.response$.next({ + data: 'request-1-response-1', + isRunning: true, + isPartial: true, + errors: [], + }); + }); + + expect(result).toHaveProperty('current.isRequestRunning', true); + expect(result).toHaveProperty('current.latestResponseData', 'request-1-response-1'); + + // second request is started before the second response of the first request arrives + act(() => { + requests$.next(secondRequest); + secondRequest.response$.next({ + data: 'request-2-response-1', + isRunning: true, + isPartial: true, + errors: [], + }); + }); + + expect(result).toHaveProperty('current.isRequestRunning', true); + expect(result).toHaveProperty('current.latestResponseData', 'request-2-response-1'); + + // second response of the second request arrives + act(() => { + secondRequest.response$.next({ + data: 'request-2-response-2', + isRunning: false, + isPartial: false, + errors: [], + }); + }); + + expect(result).toHaveProperty('current.isRequestRunning', false); + expect(result).toHaveProperty('current.latestResponseData', 'request-2-response-2'); + }); + + it("unsubscribes from the latest request's response observable on unmount", () => { + const onUnsubscribe = jest.fn(); + + const firstRequest = { + abortController: new AbortController(), + options: {}, + request: { params: 'firstRequestParam' }, + response$: new Observable>(() => { + return onUnsubscribe; + }), + }; + + const requests$ = + of, string>>(firstRequest); + + const { unmount } = renderHook(() => useLatestPartialDataSearchResponse(requests$)); + + expect(onUnsubscribe).not.toHaveBeenCalled(); + + unmount(); + + expect(onUnsubscribe).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.ts b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.ts new file mode 100644 index 0000000000000..48ff61eb676b9 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/data_search/use_latest_partial_data_search_response.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 { Observable } from 'rxjs'; +import { switchMap } from 'rxjs/operators'; +import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; +import { useOperator } from '../use_observable'; +import { flattenDataSearchResponseDescriptor } from './flatten_data_search_response'; +import { ParsedDataSearchRequestDescriptor, ParsedDataSearchResponseDescriptor } from './types'; +import { useDataSearchResponseState } from './use_data_search_response_state'; + +export const useLatestPartialDataSearchResponse = ( + requests$: Observable> +) => { + const latestResponse$: Observable> = + useOperator(requests$, flattenLatestDataSearchResponse); + + const { + cancelRequest, + isRequestRunning, + isResponsePartial, + latestResponseData, + latestResponseErrors, + loaded, + total, + } = useDataSearchResponseState(latestResponse$); + + return { + cancelRequest, + isRequestRunning, + isResponsePartial, + latestResponseData, + latestResponseErrors, + loaded, + total, + }; +}; + +const flattenLatestDataSearchResponse = switchMap(flattenDataSearchResponseDescriptor); diff --git a/x-pack/plugins/logs_shared/public/utils/datemath.ts b/x-pack/plugins/logs_shared/public/utils/datemath.ts new file mode 100644 index 0000000000000..ab07ace52d05d --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/datemath.ts @@ -0,0 +1,293 @@ +/* + * 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 dateMath, { Unit } from '@kbn/datemath'; + +const JS_MAX_DATE = 8640000000000000; + +export function isValidDatemath(value: string): boolean { + const parsedValue = dateMath.parse(value); + return !!(parsedValue && parsedValue.isValid()); +} + +export function datemathToEpochMillis( + value: string, + round: 'down' | 'up' = 'down', + forceNow?: Date +): number | null { + const parsedValue = dateMath.parse(value, { roundUp: round === 'up', forceNow }); + if (!parsedValue || !parsedValue.isValid()) { + return null; + } + return parsedValue.valueOf(); +} + +type DatemathExtension = + | { + value: string; + diffUnit: Unit; + diffAmount: number; + } + | { value: 'now' }; + +const datemathNowExpression = /(\+|\-)(\d+)(ms|s|m|h|d|w|M|y)$/; + +/** + * Extend a datemath value + * @param value The value to extend + * @param {'before' | 'after'} direction Should the value move before or after in time + * @param oppositeEdge For absolute values, the value of the other edge of the range + */ +export function extendDatemath( + value: string, + direction: 'before' | 'after' = 'before', + oppositeEdge?: string +): DatemathExtension | undefined { + if (!isValidDatemath(value)) { + return undefined; + } + + // `now` cannot be extended + if (value === 'now') { + return { value: 'now' }; + } + + // The unit is relative + if (value.startsWith('now')) { + return extendRelativeDatemath(value, direction); + } else if (oppositeEdge && isValidDatemath(oppositeEdge)) { + return extendAbsoluteDatemath(value, direction, oppositeEdge); + } + + return undefined; +} + +function extendRelativeDatemath( + value: string, + direction: 'before' | 'after' +): DatemathExtension | undefined { + const [, operator, amount, unit] = datemathNowExpression.exec(value) || []; + if (!operator || !amount || !unit) { + return undefined; + } + + const mustIncreaseAmount = + (operator === '-' && direction === 'before') || (operator === '+' && direction === 'after'); + const parsedAmount = parseInt(amount, 10); + let newUnit: Unit = unit as Unit; + let newAmount: number; + + // Extend the amount + switch (unit) { + // For small units, always double or halve the amount + case 'ms': + case 's': + newAmount = mustIncreaseAmount ? parsedAmount * 2 : Math.floor(parsedAmount / 2); + break; + // For minutes, increase or decrease in doubles or halves, depending on + // the amount of minutes + case 'm': + let ratio; + const MINUTES_LARGE = 10; + if (mustIncreaseAmount) { + ratio = parsedAmount >= MINUTES_LARGE ? 0.5 : 1; + newAmount = parsedAmount + Math.floor(parsedAmount * ratio); + } else { + newAmount = + parsedAmount >= MINUTES_LARGE + ? Math.floor(parsedAmount / 1.5) + : parsedAmount - Math.floor(parsedAmount * 0.5); + } + break; + + // For hours, increase or decrease half an hour for 1 hour. Otherwise + // increase full hours + case 'h': + if (parsedAmount === 1) { + newAmount = mustIncreaseAmount ? 90 : 30; + newUnit = 'm'; + } else { + newAmount = mustIncreaseAmount ? parsedAmount + 1 : parsedAmount - 1; + } + break; + + // For the rest of units, increase or decrease one smaller unit for + // amounts of 1. Otherwise increase or decrease the unit + case 'd': + case 'w': + case 'M': + case 'y': + if (parsedAmount === 1) { + newUnit = dateMath.unitsDesc[dateMath.unitsDesc.indexOf(unit) + 1]; + newAmount = mustIncreaseAmount + ? convertDate(1, unit, newUnit) + 1 + : convertDate(1, unit, newUnit) - 1; + } else { + newAmount = mustIncreaseAmount ? parsedAmount + 1 : parsedAmount - 1; + } + break; + + default: + throw new TypeError('Unhandled datemath unit'); + } + + // normalize amount and unit (i.e. 120s -> 2m) + const { unit: normalizedUnit, amount: normalizedAmount } = normalizeDate(newAmount, newUnit); + + // How much have we changed the time? + const diffAmount = Math.abs(normalizedAmount - convertDate(parsedAmount, unit, normalizedUnit)); + // if `diffAmount` is not an integer after normalization, express the difference in the original unit + const shouldKeepDiffUnit = diffAmount % 1 !== 0; + + const nextValue = `now${operator}${normalizedAmount}${normalizedUnit}`; + + if (isDateInRange(nextValue)) { + return { + value: nextValue, + diffUnit: shouldKeepDiffUnit ? unit : newUnit, + diffAmount: shouldKeepDiffUnit ? Math.abs(newAmount - parsedAmount) : diffAmount, + }; + } else { + return undefined; + } +} + +function extendAbsoluteDatemath( + value: string, + direction: 'before' | 'after', + oppositeEdge: string +): DatemathExtension | undefined { + const valueTimestamp = datemathToEpochMillis(value)!; + const oppositeEdgeTimestamp = datemathToEpochMillis(oppositeEdge)!; + const actualTimestampDiff = Math.abs(valueTimestamp - oppositeEdgeTimestamp); + const normalizedDiff = normalizeDate(actualTimestampDiff, 'ms'); + const normalizedTimestampDiff = convertDate(normalizedDiff.amount, normalizedDiff.unit, 'ms'); + + const newValue = + direction === 'before' + ? valueTimestamp - normalizedTimestampDiff + : valueTimestamp + normalizedTimestampDiff; + + if (isDateInRange(newValue)) { + return { + value: new Date(newValue).toISOString(), + diffUnit: normalizedDiff.unit, + diffAmount: normalizedDiff.amount, + }; + } else { + return undefined; + } +} + +const CONVERSION_RATIOS: Record> = { + wy: [ + ['w', 52], // 1 year = 52 weeks + ['y', 1], + ], + w: [ + ['ms', 1000], + ['s', 60], + ['m', 60], + ['h', 24], + ['d', 7], // 1 week = 7 days + ['w', 4], // 1 month = 4 weeks = 28 days + ['M', 12], // 1 year = 12 months = 52 weeks = 364 days + ['y', 1], + ], + M: [ + ['ms', 1000], + ['s', 60], + ['m', 60], + ['h', 24], + ['d', 30], // 1 month = 30 days + ['M', 12], // 1 year = 12 months = 360 days + ['y', 1], + ], + default: [ + ['ms', 1000], + ['s', 60], + ['m', 60], + ['h', 24], + ['d', 365], // 1 year = 365 days + ['y', 1], + ], +}; + +function getRatioScale(from: Unit, to?: Unit) { + if ((from === 'y' && to === 'w') || (from === 'w' && to === 'y')) { + return CONVERSION_RATIOS.wy; + } else if (from === 'w' || to === 'w') { + return CONVERSION_RATIOS.w; + } else if (from === 'M' || to === 'M') { + return CONVERSION_RATIOS.M; + } else { + return CONVERSION_RATIOS.default; + } +} + +export function convertDate(value: number, from: Unit, to: Unit): number { + if (from === to) { + return value; + } + + const ratioScale = getRatioScale(from, to); + const fromIdx = ratioScale.findIndex((ratio) => ratio[0] === from); + const toIdx = ratioScale.findIndex((ratio) => ratio[0] === to); + + let convertedValue = value; + + if (fromIdx > toIdx) { + // `from` is the bigger unit. Multiply the value + for (let i = toIdx; i < fromIdx; i++) { + convertedValue *= ratioScale[i][1]; + } + } else { + // `from` is the smaller unit. Divide the value + for (let i = fromIdx; i < toIdx; i++) { + convertedValue /= ratioScale[i][1]; + } + } + + return convertedValue; +} + +export function normalizeDate(amount: number, unit: Unit): { amount: number; unit: Unit } { + // There is nothing after years + if (unit === 'y') { + return { amount, unit }; + } + + const nextUnit = dateMath.unitsAsc[dateMath.unitsAsc.indexOf(unit) + 1]; + const ratioScale = getRatioScale(unit, nextUnit); + const ratio = ratioScale.find((r) => r[0] === unit)![1]; + + const newAmount = amount / ratio; + + // Exact conversion + if (newAmount === 1) { + return { amount: newAmount, unit: nextUnit }; + } + + // Might be able to go one unit more, so try again, rounding the value + // 7200s => 120m => 2h + // 7249s ~> 120m ~> 2h + if (newAmount >= 2) { + return normalizeDate(Math.round(newAmount), nextUnit); + } + + // Cannot go one one unit above. Return as it is + return { amount, unit }; +} + +function isDateInRange(date: string | number): boolean { + try { + const epoch = typeof date === 'string' ? datemathToEpochMillis(date) ?? -1 : date; + return epoch >= 0 && epoch <= JS_MAX_DATE; + } catch { + return false; + } +} diff --git a/x-pack/plugins/logs_shared/public/utils/dev_mode.ts b/x-pack/plugins/logs_shared/public/utils/dev_mode.ts new file mode 100644 index 0000000000000..60571501b4193 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/dev_mode.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const getReduxDevtools = () => (window as any).__REDUX_DEVTOOLS_EXTENSION__; + +export const hasReduxDevtools = () => getReduxDevtools() != null; + +export const isDevMode = () => process.env.NODE_ENV !== 'production'; diff --git a/x-pack/plugins/logs_shared/public/utils/handlers.ts b/x-pack/plugins/logs_shared/public/utils/handlers.ts new file mode 100644 index 0000000000000..f79e2fa4766a2 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/handlers.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEqual } from 'lodash'; + +export function callWithoutRepeats( + func: (...args: any[]) => T, + isArgsEqual: (firstArgs: any, secondArgs: any) => boolean = isEqual +) { + let previousArgs: any[]; + let previousResult: T; + + return (...args: any[]) => { + if (!isArgsEqual(args, previousArgs)) { + previousArgs = args; + previousResult = func(...args); + } + + return previousResult; + }; +} diff --git a/x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx b/x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx new file mode 100644 index 0000000000000..ff4a24f1498a6 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/log_column_render_configuration.tsx @@ -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 { ReactNode } from 'react'; +import { JsonValue } from '@kbn/utility-types'; + +/** + * Interface for common configuration properties, regardless of the column type. + */ +interface CommonRenderConfiguration { + id: string; + width?: number | string; + header?: boolean | string; +} + +interface TimestampColumnRenderConfiguration { + timestampColumn: CommonRenderConfiguration & { + render?: (timestamp: number) => ReactNode; + }; +} + +interface MessageColumnRenderConfiguration { + messageColumn: CommonRenderConfiguration & { + render?: (message: string) => ReactNode; + }; +} + +interface FieldColumnRenderConfiguration { + fieldColumn: CommonRenderConfiguration & { + field: string; + render?: (value: JsonValue) => ReactNode; + }; +} + +export type LogColumnRenderConfiguration = + | TimestampColumnRenderConfiguration + | MessageColumnRenderConfiguration + | FieldColumnRenderConfiguration; + +export function isTimestampColumnRenderConfiguration( + column: LogColumnRenderConfiguration +): column is TimestampColumnRenderConfiguration { + return 'timestampColumn' in column; +} + +export function isMessageColumnRenderConfiguration( + column: LogColumnRenderConfiguration +): column is MessageColumnRenderConfiguration { + return 'messageColumn' in column; +} + +export function isFieldColumnRenderConfiguration( + column: LogColumnRenderConfiguration +): column is FieldColumnRenderConfiguration { + return 'fieldColumn' in column; +} + +export function columnWidthToCSS(width: number | string) { + return typeof width === 'number' ? `${width}px` : width; +} diff --git a/x-pack/plugins/infra/public/utils/log_entry/index.ts b/x-pack/plugins/logs_shared/public/utils/log_entry/index.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/log_entry/index.ts rename to x-pack/plugins/logs_shared/public/utils/log_entry/index.ts diff --git a/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts b/x-pack/plugins/logs_shared/public/utils/log_entry/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/log_entry/log_entry.ts rename to x-pack/plugins/logs_shared/public/utils/log_entry/log_entry.ts diff --git a/x-pack/plugins/infra/public/utils/log_entry/log_entry_highlight.ts b/x-pack/plugins/logs_shared/public/utils/log_entry/log_entry_highlight.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/log_entry/log_entry_highlight.ts rename to x-pack/plugins/logs_shared/public/utils/log_entry/log_entry_highlight.ts diff --git a/x-pack/plugins/infra/public/utils/styles.ts b/x-pack/plugins/logs_shared/public/utils/styles.ts similarity index 100% rename from x-pack/plugins/infra/public/utils/styles.ts rename to x-pack/plugins/logs_shared/public/utils/styles.ts diff --git a/x-pack/plugins/infra/public/components/log_stream/lazy_log_stream_wrapper.tsx b/x-pack/plugins/logs_shared/public/utils/typed_react.tsx similarity index 50% rename from x-pack/plugins/infra/public/components/log_stream/lazy_log_stream_wrapper.tsx rename to x-pack/plugins/logs_shared/public/utils/typed_react.tsx index 064e944378cab..664894e1bf05c 100644 --- a/x-pack/plugins/infra/public/components/log_stream/lazy_log_stream_wrapper.tsx +++ b/x-pack/plugins/logs_shared/public/utils/typed_react.tsx @@ -6,12 +6,6 @@ */ import React from 'react'; -import type { LogStreamProps } from './log_stream'; -const LazyLogStream = React.lazy(() => import('./log_stream')); - -export const LazyLogStreamWrapper = (props: LogStreamProps) => ( - }> - - -); +export type RendererResult = React.ReactElement | null; +export type RendererFunction = (args: RenderArgs) => Result; diff --git a/x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.ts b/x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.ts new file mode 100644 index 0000000000000..521cd0142303b --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_kibana_query_settings.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 type { EsQueryConfig } from '@kbn/es-query'; +import { SerializableRecord } from '@kbn/utility-types'; +import { useMemo } from 'react'; +import { UI_SETTINGS } from '@kbn/data-plugin/public'; +import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; + +export const useKibanaQuerySettings = (): EsQueryConfig => { + const [allowLeadingWildcards] = useUiSetting$(UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS); + const [queryStringOptions] = useUiSetting$(UI_SETTINGS.QUERY_STRING_OPTIONS); + const [dateFormatTZ] = useUiSetting$(UI_SETTINGS.DATEFORMAT_TZ); + const [ignoreFilterIfFieldNotInIndex] = useUiSetting$( + UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX + ); + + return useMemo( + () => ({ + allowLeadingWildcards, + queryStringOptions, + dateFormatTZ, + ignoreFilterIfFieldNotInIndex, + }), + [allowLeadingWildcards, dateFormatTZ, ignoreFilterIfFieldNotInIndex, queryStringOptions] + ); +}; diff --git a/x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.ts b/x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.ts new file mode 100644 index 0000000000000..e53e2b28cbdd4 --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_kibana_ui_setting.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 { useMemo } from 'react'; +import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; + +/** + * This hook behaves like a `useState` hook in that it provides a requested + * setting value (with an optional default) from the Kibana UI settings (also + * known as "advanced settings") and a setter to change that setting: + * + * ``` + * const [quickRanges, setQuickRanges] = useKibanaUiSetting('timepicker:quickRanges'); + * ``` + * + * This is not just a static consumption of the value, but will reactively + * update when the underlying setting subscription of the `UiSettingsClient` + * notifies of a change. + * + * Unlike the `useState`, it doesn't give type guarantees for the value, + * because the underlying `UiSettingsClient` doesn't support that. + */ + +export interface TimePickerQuickRange { + from: string; + to: string; + display: string; +} + +export function useKibanaUiSetting( + key: 'timepicker:quickRanges', + defaultValue?: TimePickerQuickRange[] +): [ + TimePickerQuickRange[], + (key: 'timepicker:quickRanges', value: TimePickerQuickRange[]) => Promise +]; + +export function useKibanaUiSetting( + key: string, + defaultValue?: any +): [any, (key: string, value: any) => Promise]; + +export function useKibanaUiSetting(key: string, defaultValue?: any) { + const [uiSetting, setUiSetting] = useUiSetting$(key); + const uiSettingValue = useMemo(() => { + return uiSetting ? uiSetting : defaultValue; + }, [uiSetting, defaultValue]); + return [uiSettingValue, setUiSetting]; +} diff --git a/x-pack/plugins/logs_shared/public/utils/use_observable.ts b/x-pack/plugins/logs_shared/public/utils/use_observable.ts new file mode 100644 index 0000000000000..00efc4900b82f --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_observable.ts @@ -0,0 +1,152 @@ +/* + * 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 { useEffect, useRef, useState } from 'react'; +import { + BehaviorSubject, + Observable, + OperatorFunction, + PartialObserver, + ReplaySubject, + Subscription, +} from 'rxjs'; +import { switchMap } from 'rxjs/operators'; + +export const useLatest = (value: Value) => { + const valueRef = useRef(value); + valueRef.current = value; + return valueRef; +}; + +export const useObservable = < + OutputValue, + OutputObservable extends Observable, + InputValues extends Readonly +>( + createObservableOnce: (inputValues: Observable) => OutputObservable, + inputValues: InputValues +) => { + const [output$, next] = useBehaviorSubject(createObservableOnce, () => inputValues); + + useEffect(() => { + next(inputValues); + // `inputValues` can't be statically analyzed + // eslint-disable-next-line react-hooks/exhaustive-deps + }, inputValues); + + return output$; +}; + +export const useBehaviorSubject = < + InputValue, + OutputValue, + OutputObservable extends Observable +>( + deriveObservableOnce: (input$: Observable) => OutputObservable, + createInitialValue: () => InputValue +) => { + const [[subject$, next], _] = useState(() => { + const newSubject$ = new BehaviorSubject(createInitialValue()); + const newNext = newSubject$.next.bind(newSubject$); + return [newSubject$, newNext] as const; + }); + const [output$] = useState(() => deriveObservableOnce(subject$)); + return [output$, next] as const; +}; + +export const useReplaySubject = < + InputValue, + OutputValue, + OutputObservable extends Observable +>( + deriveObservableOnce: (input$: Observable) => OutputObservable +) => { + const [[subject$, next], _] = useState(() => { + const newSubject$ = new ReplaySubject(); + const newNext = newSubject$.next.bind(newSubject$); + return [newSubject$, newNext] as const; + }); + const [output$] = useState(() => deriveObservableOnce(subject$)); + return [output$, next] as const; +}; + +export const useObservableState = ( + state$: Observable, + initialState: InitialState | (() => InitialState) +) => { + const [latestValue, setLatestValue] = useState(initialState); + const [latestError, setLatestError] = useState(); + + useSubscription(state$, { + next: setLatestValue, + error: setLatestError, + }); + + return { latestValue, latestError }; +}; + +export const useSubscription = ( + input$: Observable, + { next, error, complete, unsubscribe }: PartialObserver & { unsubscribe?: () => void } +) => { + const latestSubscription = useRef(); + const latestNext = useLatest(next); + const latestError = useLatest(error); + const latestComplete = useLatest(complete); + const latestUnsubscribe = useLatest(unsubscribe); + + useEffect(() => { + const fixedUnsubscribe = latestUnsubscribe.current; + + const subscription = input$.subscribe({ + next: (value) => { + return latestNext.current?.(value); + }, + error: (value) => latestError.current?.(value), + complete: () => latestComplete.current?.(), + }); + + latestSubscription.current = subscription; + + return () => { + subscription.unsubscribe(); + fixedUnsubscribe?.(); + }; + }, [input$, latestNext, latestError, latestComplete, latestUnsubscribe]); + + return latestSubscription.current; +}; + +export const useOperator = ( + input$: Observable, + operator: OperatorFunction +) => { + const latestOperator = useLatest(operator); + + return useObservable( + (inputs$) => + inputs$.pipe(switchMap(([currentInput$]) => latestOperator.current(currentInput$))), + [input$] as const + ); +}; + +export const tapUnsubscribe = + (onUnsubscribe: () => void) => + (source$: Observable) => { + return new Observable((subscriber) => { + const subscription = source$.subscribe({ + next: (value) => subscriber.next(value), + error: (error) => subscriber.error(error), + complete: () => subscriber.complete(), + }); + + return () => { + onUnsubscribe(); + subscription.unsubscribe(); + }; + }); + }; diff --git a/x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts b/x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts new file mode 100644 index 0000000000000..d12749ea69fdc --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_tracked_promise.ts @@ -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. + */ + +/* eslint-disable max-classes-per-file */ + +import { DependencyList, useEffect, useMemo, useRef, useState, useCallback } from 'react'; +import useMountedState from 'react-use/lib/useMountedState'; + +interface UseTrackedPromiseArgs { + createPromise: (...args: Arguments) => Promise; + onResolve?: (result: Result) => void; + onReject?: (value: unknown) => void; + cancelPreviousOn?: 'creation' | 'settlement' | 'resolution' | 'rejection' | 'never'; + triggerOrThrow?: 'always' | 'whenMounted'; +} + +/** + * This hook manages a Promise factory and can create new Promises from it. The + * state of these Promises is tracked and they can be canceled when superseded + * to avoid race conditions. + * + * ``` + * const [requestState, performRequest] = useTrackedPromise( + * { + * cancelPreviousOn: 'resolution', + * createPromise: async (url: string) => { + * return await fetchSomething(url) + * }, + * onResolve: response => { + * setSomeState(response.data); + * }, + * onReject: response => { + * setSomeError(response); + * }, + * }, + * [fetchSomething] + * ); + * ``` + * + * The `onResolve` and `onReject` handlers are registered separately, because + * the hook will inject a rejection when in case of a canellation. The + * `cancelPreviousOn` attribute can be used to indicate when the preceding + * pending promises should be canceled: + * + * 'never': No preceding promises will be canceled. + * + * 'creation': Any preceding promises will be canceled as soon as a new one is + * created. + * + * 'settlement': Any preceding promise will be canceled when a newer promise is + * resolved or rejected. + * + * 'resolution': Any preceding promise will be canceled when a newer promise is + * resolved. + * + * 'rejection': Any preceding promise will be canceled when a newer promise is + * rejected. + * + * Any pending promises will be canceled when the component using the hook is + * unmounted, but their status will not be tracked to avoid React warnings + * about memory leaks. + * + * The last argument is a normal React hook dependency list that indicates + * under which conditions a new reference to the configuration object should be + * used. + * + * The `onResolve`, `onReject` and possible uncatched errors are only triggered + * if the underlying component is mounted. To ensure they always trigger (i.e. + * if the promise is called in a `useLayoutEffect`) use the `triggerOrThrow` + * attribute: + * + * 'whenMounted': (default) they are called only if the component is mounted. + * + * 'always': they always call. The consumer is then responsible of ensuring no + * side effects happen if the underlying component is not mounted. + */ +export const useTrackedPromise = ( + { + createPromise, + onResolve = noOp, + onReject = noOp, + cancelPreviousOn = 'never', + triggerOrThrow = 'whenMounted', + }: UseTrackedPromiseArgs, + dependencies: DependencyList +) => { + const isComponentMounted = useMountedState(); + const shouldTriggerOrThrow = useCallback(() => { + switch (triggerOrThrow) { + case 'always': + return true; + case 'whenMounted': + return isComponentMounted(); + } + }, [isComponentMounted, triggerOrThrow]); + + /** + * If a promise is currently pending, this holds a reference to it and its + * cancellation function. + */ + const pendingPromises = useRef>>([]); + + /** + * The state of the promise most recently created by the `createPromise` + * factory. It could be uninitialized, pending, resolved or rejected. + */ + const [promiseState, setPromiseState] = useState>({ + state: 'uninitialized', + }); + + const reset = useCallback(() => { + setPromiseState({ + state: 'uninitialized', + }); + }, []); + + const execute = useMemo( + () => + (...args: Arguments) => { + let rejectCancellationPromise!: (value: any) => void; + const cancellationPromise = new Promise((_, reject) => { + rejectCancellationPromise = reject; + }); + + // remember the list of prior pending promises for cancellation + const previousPendingPromises = pendingPromises.current; + + const cancelPreviousPendingPromises = () => { + previousPendingPromises.forEach((promise) => promise.cancel()); + }; + + const newPromise = createPromise(...args); + const newCancelablePromise = Promise.race([newPromise, cancellationPromise]); + + // track this new state + setPromiseState({ + state: 'pending', + promise: newCancelablePromise, + }); + + if (cancelPreviousOn === 'creation') { + cancelPreviousPendingPromises(); + } + + const newPendingPromise: CancelablePromise = { + cancel: () => { + rejectCancellationPromise(new CanceledPromiseError()); + }, + cancelSilently: () => { + rejectCancellationPromise(new SilentCanceledPromiseError()); + }, + promise: newCancelablePromise.then( + (value) => { + if (['settlement', 'resolution'].includes(cancelPreviousOn)) { + cancelPreviousPendingPromises(); + } + + // remove itself from the list of pending promises + pendingPromises.current = pendingPromises.current.filter( + (pendingPromise) => pendingPromise.promise !== newPendingPromise.promise + ); + + if (onResolve && shouldTriggerOrThrow()) { + onResolve(value); + } + + setPromiseState((previousPromiseState) => + previousPromiseState.state === 'pending' && + previousPromiseState.promise === newCancelablePromise + ? { + state: 'resolved', + promise: newPendingPromise.promise, + value, + } + : previousPromiseState + ); + + return value; + }, + (value) => { + if (!(value instanceof SilentCanceledPromiseError)) { + if (['settlement', 'rejection'].includes(cancelPreviousOn)) { + cancelPreviousPendingPromises(); + } + + // remove itself from the list of pending promises + pendingPromises.current = pendingPromises.current.filter( + (pendingPromise) => pendingPromise.promise !== newPendingPromise.promise + ); + + if (shouldTriggerOrThrow()) { + if (onReject) { + onReject(value); + } else { + throw value; + } + } + + setPromiseState((previousPromiseState) => + previousPromiseState.state === 'pending' && + previousPromiseState.promise === newCancelablePromise + ? { + state: 'rejected', + promise: newCancelablePromise, + value, + } + : previousPromiseState + ); + } + } + ), + }; + + // add the new promise to the list of pending promises + pendingPromises.current = [...pendingPromises.current, newPendingPromise]; + + // silence "unhandled rejection" warnings + newPendingPromise.promise.catch(noOp); + + return newPendingPromise.promise; + }, + // the dependencies are managed by the caller + // eslint-disable-next-line react-hooks/exhaustive-deps + dependencies + ); + + /** + * Cancel any pending promises silently to avoid memory leaks and race + * conditions. + */ + useEffect( + () => () => { + pendingPromises.current.forEach((promise) => promise.cancelSilently()); + }, + [] + ); + + return [promiseState, execute, reset] as [typeof promiseState, typeof execute, typeof reset]; +}; + +export interface UninitializedPromiseState { + state: 'uninitialized'; +} + +export interface PendingPromiseState { + state: 'pending'; + promise: Promise; +} + +export interface ResolvedPromiseState { + state: 'resolved'; + promise: Promise; + value: ResolvedValue; +} + +export interface RejectedPromiseState { + state: 'rejected'; + promise: Promise; + value: RejectedValue; +} + +export type SettledPromiseState = + | ResolvedPromiseState + | RejectedPromiseState; + +export type PromiseState = + | UninitializedPromiseState + | PendingPromiseState + | SettledPromiseState; + +export const isRejectedPromiseState = ( + promiseState: PromiseState +): promiseState is RejectedPromiseState => promiseState.state === 'rejected'; + +interface CancelablePromise { + // reject the promise prematurely with a CanceledPromiseError + cancel: () => void; + // reject the promise prematurely with a SilentCanceledPromiseError + cancelSilently: () => void; + // the tracked promise + promise: Promise; +} + +export class CanceledPromiseError extends Error { + public isCanceled = true; + + constructor(message?: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + } +} + +export class SilentCanceledPromiseError extends CanceledPromiseError {} + +const noOp = () => undefined; diff --git a/x-pack/plugins/logs_shared/public/utils/use_visibility_state.ts b/x-pack/plugins/logs_shared/public/utils/use_visibility_state.ts new file mode 100644 index 0000000000000..cff9a7190d2bb --- /dev/null +++ b/x-pack/plugins/logs_shared/public/utils/use_visibility_state.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 { useCallback, useMemo, useState } from 'react'; + +export const useVisibilityState = (initialState: boolean) => { + const [isVisible, setIsVisible] = useState(initialState); + + const hide = useCallback(() => setIsVisible(false), []); + const show = useCallback(() => setIsVisible(true), []); + const toggle = useCallback(() => setIsVisible((state) => !state), []); + + return useMemo( + () => ({ + hide, + isVisible, + show, + toggle, + }), + [hide, isVisible, show, toggle] + ); +}; diff --git a/x-pack/plugins/logs_shared/server/index.ts b/x-pack/plugins/logs_shared/server/index.ts new file mode 100644 index 0000000000000..95f6741bb54b8 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/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 { PluginInitializerContext } from '@kbn/core/server'; +import { LogsSharedPlugin } from './plugin'; + +export type { LogsSharedPluginSetup, LogsSharedPluginStart } from './types'; +export type { + LogsSharedLogEntriesDomain, + ILogsSharedLogEntriesDomain, +} from './lib/domains/log_entries_domain'; + +export { logViewSavedObjectName } from './saved_objects'; + +export function plugin(context: PluginInitializerContext) { + return new LogsSharedPlugin(context); +} diff --git a/x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.ts new file mode 100644 index 0000000000000..46e77f48d3f4b --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/adapters/framework/adapter_types.ts @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { JsonArray, JsonValue } from '@kbn/utility-types'; +import { RouteMethod } from '@kbn/core/server'; +import { VersionedRouteConfig } from '@kbn/core-http-server'; + +export interface CallWithRequestParams extends estypes.RequestBase { + max_concurrent_shard_requests?: number; + name?: string; + index?: string | string[]; + ignore_unavailable?: boolean; + allow_no_indices?: boolean; + size?: number; + terminate_after?: number; + fields?: estypes.Fields; + path?: string; + query?: string | object; + track_total_hits?: boolean | number; + body?: any; +} + +export interface LogsSharedDatabaseResponse { + took: number; + timeout: boolean; +} + +export interface LogsSharedDatabaseSearchResponse + extends LogsSharedDatabaseResponse { + _shards: { + total: number; + successful: number; + skipped: number; + failed: number; + }; + timed_out: boolean; + aggregations?: Aggregations; + hits: { + total: { + value: number; + relation: string; + }; + hits: Hit[]; + }; +} + +export interface LogsSharedDatabaseMultiResponse + extends LogsSharedDatabaseResponse { + responses: Array>; +} + +export interface LogsSharedDatabaseGetIndicesAliasResponse { + [indexName: string]: { + aliases: { + [aliasName: string]: any; + }; + }; +} + +export interface LogsSharedDatabaseGetIndicesResponse { + [indexName: string]: { + aliases: { + [aliasName: string]: any; + }; + mappings: { + _meta: object; + dynamic_templates: any[]; + date_detection: boolean; + properties: { + [fieldName: string]: any; + }; + }; + settings: { index: object }; + }; +} + +export type SearchHit = estypes.SearchHit; + +export interface SortedSearchHit extends SearchHit { + sort: any[]; + _source: { + [field: string]: JsonValue; + }; + fields: { + [field: string]: JsonArray; + }; +} + +export type LogsSharedVersionedRouteConfig = { + method: RouteMethod; +} & VersionedRouteConfig; diff --git a/x-pack/plugins/logs_shared/server/lib/adapters/framework/index.ts b/x-pack/plugins/logs_shared/server/lib/adapters/framework/index.ts new file mode 100644 index 0000000000000..5d7c09c54b8c1 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/adapters/framework/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 './adapter_types'; diff --git a/x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts new file mode 100644 index 0000000000000..413ab3b333e82 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -0,0 +1,179 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { TransportRequestParams } from '@elastic/elasticsearch'; +import { CoreSetup, IRouter, RouteMethod } from '@kbn/core/server'; +import { UI_SETTINGS } from '@kbn/data-plugin/server'; +import type { + LogsSharedPluginRequestHandlerContext, + LogsSharedServerPluginSetupDeps, + LogsSharedServerPluginStartDeps, +} from '../../../types'; +import { + CallWithRequestParams, + LogsSharedDatabaseGetIndicesAliasResponse, + LogsSharedDatabaseGetIndicesResponse, + LogsSharedDatabaseMultiResponse, + LogsSharedDatabaseSearchResponse, + LogsSharedVersionedRouteConfig, +} from './adapter_types'; + +interface FrozenIndexParams { + ignore_throttled?: boolean; +} + +export class KibanaFramework { + public router: IRouter; + public plugins: LogsSharedServerPluginSetupDeps; + + constructor( + core: CoreSetup, + plugins: LogsSharedServerPluginSetupDeps + ) { + this.router = core.http.createRouter(); + this.plugins = plugins; + } + + public registerVersionedRoute( + config: LogsSharedVersionedRouteConfig + ) { + const defaultOptions = { + tags: ['access:infra'], + }; + const routeConfig = { + access: config.access, + path: config.path, + // Currently we have no use of custom options beyond tags, this can be extended + // beyond defaultOptions if it's needed. + options: defaultOptions, + }; + switch (config.method) { + case 'get': + return this.router.versioned.get(routeConfig); + case 'post': + return this.router.versioned.post(routeConfig); + case 'delete': + return this.router.versioned.delete(routeConfig); + case 'put': + return this.router.versioned.put(routeConfig); + case 'patch': + return this.router.versioned.patch(routeConfig); + default: + throw new RangeError( + `#registerVersionedRoute: "${config.method}" is not an accepted method` + ); + } + } + + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: 'search', + options?: CallWithRequestParams + ): Promise>; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: 'msearch', + options?: CallWithRequestParams + ): Promise>; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: 'indices.existsAlias', + options?: CallWithRequestParams + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + method: 'indices.getAlias', + options?: object + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + method: 'indices.get' | 'ml.getBuckets', + options?: object + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + method: 'transport.request', + options?: CallWithRequestParams + ): Promise; + callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: string, + options?: CallWithRequestParams + ): Promise; + public async callWithRequest( + requestContext: LogsSharedPluginRequestHandlerContext, + endpoint: string, + params: CallWithRequestParams + ) { + const { elasticsearch, uiSettings } = await requestContext.core; + + const includeFrozen = await uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); + if (endpoint === 'msearch') { + const maxConcurrentShardRequests = await uiSettings.client.get( + UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS + ); + if (maxConcurrentShardRequests > 0) { + params = { ...params, max_concurrent_shard_requests: maxConcurrentShardRequests }; + } + } + + // Only set the "ignore_throttled" value (to false) if the Kibana setting + // for "search:includeFrozen" is true (i.e. don't ignore throttled indices, a triple negative!) + // More information: + // - https://github.com/elastic/kibana/issues/113197 + // - https://github.com/elastic/elasticsearch/pull/77479 + // + // NOTE: these params only need to be spread onto the search and msearch calls below + const frozenIndicesParams: FrozenIndexParams = {}; + if (includeFrozen) { + frozenIndicesParams.ignore_throttled = false; + } + + let apiResult; + switch (endpoint) { + case 'search': + apiResult = elasticsearch.client.asCurrentUser.search({ + ...params, + ...frozenIndicesParams, + }); + break; + case 'msearch': + apiResult = elasticsearch.client.asCurrentUser.msearch({ + ...params, + ...frozenIndicesParams, + } as estypes.MsearchRequest); + break; + case 'indices.existsAlias': + apiResult = elasticsearch.client.asCurrentUser.indices.existsAlias({ + ...params, + } as estypes.IndicesExistsAliasRequest); + break; + case 'indices.getAlias': + apiResult = elasticsearch.client.asCurrentUser.indices.getAlias({ + ...params, + }); + break; + case 'indices.get': + apiResult = elasticsearch.client.asCurrentUser.indices.get({ + ...params, + } as estypes.IndicesGetRequest); + break; + case 'transport.request': + apiResult = elasticsearch.client.asCurrentUser.transport.request({ + ...params, + } as TransportRequestParams); + break; + case 'ml.getBuckets': + apiResult = elasticsearch.client.asCurrentUser.ml.getBuckets({ + ...params, + } as estypes.MlGetBucketsRequest); + break; + } + return apiResult ? await apiResult : undefined; + } +} diff --git a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts b/x-pack/plugins/logs_shared/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts similarity index 96% rename from x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts rename to x-pack/plugins/logs_shared/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts index 97ef51ded269d..66de5699cfb3e 100644 --- a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts +++ b/x-pack/plugins/logs_shared/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts @@ -12,7 +12,7 @@ import { pipe } from 'fp-ts/lib/pipeable'; import * as runtimeTypes from 'io-ts'; import { JsonArray } from '@kbn/utility-types'; import { compact } from 'lodash'; -import type { InfraPluginRequestHandlerContext } from '../../../types'; +import type { LogsSharedPluginRequestHandlerContext } from '../../../types'; import { LogEntriesAdapter, LogEntriesParams, @@ -28,11 +28,11 @@ import { TIMESTAMP_FIELD, TIEBREAKER_FIELD } from '../../../../common/constants' const TIMESTAMP_FORMAT = 'epoch_millis'; -export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { +export class LogsSharedKibanaLogEntriesAdapter implements LogEntriesAdapter { constructor(private readonly framework: KibanaFramework) {} public async getLogEntries( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, fields: string[], params: LogEntriesParams @@ -123,7 +123,7 @@ export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { } public async getContainedLogSummaryBuckets( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, startTimestamp: number, endTimestamp: number, @@ -318,5 +318,3 @@ const LogSummaryResponseRuntimeType = runtimeTypes.type({ }), }), }); - -export type LogSummaryResponse = runtimeTypes.TypeOf; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/index.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/index.ts similarity index 100% rename from x-pack/plugins/infra/server/lib/domains/log_entries_domain/index.ts rename to x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/index.ts diff --git a/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.ts new file mode 100644 index 0000000000000..74509f11ae4a7 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.mock.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ILogsSharedLogEntriesDomain } from './log_entries_domain'; + +export const createLogsSharedLogEntriesDomainMock = + (): jest.Mocked => { + return { + getLogEntriesAround: jest.fn(), + getLogEntries: jest.fn(), + getLogSummaryBucketsBetween: jest.fn(), + getLogSummaryHighlightBucketsBetween: jest.fn(), + getLogEntryDatasets: jest.fn(), + }; + }; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.ts similarity index 84% rename from x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts rename to x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.ts index fcda9b30b0dac..92829c676b935 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -26,8 +26,8 @@ import { Fields, Highlights, } from '../../../services/log_entries/message/message'; -import type { InfraPluginRequestHandlerContext } from '../../../types'; -import { InfraBackendLibs } from '../../infra_types'; +import type { LogsSharedPluginRequestHandlerContext } from '../../../types'; +import { LogsSharedBackendLibs } from '../../logs_shared_types'; import { CompositeDatasetKey, createLogEntryDatasetsQuery, @@ -59,14 +59,54 @@ const FIELDS_FROM_CONTEXT = ['log.file.path', 'host.name', 'container.id'] as co const COMPOSITE_AGGREGATION_BATCH_SIZE = 1000; -export class InfraLogEntriesDomain { +export interface ILogsSharedLogEntriesDomain { + getLogEntriesAround( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + params: LogEntriesAroundParams, + columnOverrides?: LogViewColumnConfiguration[] + ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }>; + getLogEntries( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + params: LogEntriesParams, + columnOverrides?: LogViewColumnConfiguration[] + ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }>; + getLogSummaryBucketsBetween( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + start: number, + end: number, + bucketSize: number, + filterQuery?: LogEntryQuery + ): Promise; + getLogSummaryHighlightBucketsBetween( + requestContext: LogsSharedPluginRequestHandlerContext, + logView: LogViewReference, + startTimestamp: number, + endTimestamp: number, + bucketSize: number, + highlightQueries: string[], + filterQuery?: LogEntryQuery + ): Promise; + getLogEntryDatasets( + requestContext: LogsSharedPluginRequestHandlerContext, + timestampField: string, + indexName: string, + startTime: number, + endTime: number, + runtimeMappings: estypes.MappingRuntimeFields + ): Promise; +} + +export class LogsSharedLogEntriesDomain implements ILogsSharedLogEntriesDomain { constructor( private readonly adapter: LogEntriesAdapter, - private readonly libs: Pick + private readonly libs: Pick ) {} public async getLogEntriesAround( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, params: LogEntriesAroundParams, columnOverrides?: LogViewColumnConfiguration[] @@ -126,7 +166,7 @@ export class InfraLogEntriesDomain { } public async getLogEntries( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, params: LogEntriesParams, columnOverrides?: LogViewColumnConfiguration[] @@ -184,7 +224,7 @@ export class InfraLogEntriesDomain { } public async getLogSummaryBucketsBetween( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, start: number, end: number, @@ -208,7 +248,7 @@ export class InfraLogEntriesDomain { } public async getLogSummaryHighlightBucketsBetween( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, logView: LogViewReference, startTimestamp: number, endTimestamp: number, @@ -255,7 +295,7 @@ export class InfraLogEntriesDomain { } public async getLogEntryDatasets( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, timestampField: string, indexName: string, startTime: number, @@ -298,14 +338,14 @@ export class InfraLogEntriesDomain { export interface LogEntriesAdapter { getLogEntries( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, fields: string[], params: LogEntriesParams ): Promise<{ documents: LogEntryDocument[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }>; getContainedLogSummaryBuckets( - requestContext: InfraPluginRequestHandlerContext, + requestContext: LogsSharedPluginRequestHandlerContext, resolvedLogView: ResolvedLogView, startTimestamp: number, endTimestamp: number, diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts similarity index 96% rename from x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts rename to x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts index a658c7deb317c..c2b966e86983f 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts +++ b/x-pack/plugins/logs_shared/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts @@ -99,5 +99,3 @@ export const logEntryDatasetsResponseRT = rt.intersection([ }), }), ]); - -export type LogEntryDatasetsResponse = rt.TypeOf; diff --git a/x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts b/x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts new file mode 100644 index 0000000000000..9d7ef50443c7f --- /dev/null +++ b/x-pack/plugins/logs_shared/server/lib/logs_shared_types.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/logging'; +import type { IBasePath } from '@kbn/core/server'; +import type { LogsSharedPluginStartServicesAccessor, UsageCollector } from '../types'; +import type { KibanaFramework } from './adapters/framework/kibana_framework_adapter'; +import type { ILogsSharedLogEntriesDomain } from './domains/log_entries_domain'; + +export interface LogsSharedDomainLibs { + logEntries: ILogsSharedLogEntriesDomain; +} + +export interface LogsSharedBackendLibs extends LogsSharedDomainLibs { + basePath: IBasePath; + framework: KibanaFramework; + getStartServices: LogsSharedPluginStartServicesAccessor; + logger: Logger; + getUsageCollector: () => UsageCollector; +} diff --git a/x-pack/plugins/logs_shared/server/logs_shared_server.ts b/x-pack/plugins/logs_shared/server/logs_shared_server.ts new file mode 100644 index 0000000000000..60dc17be61d2d --- /dev/null +++ b/x-pack/plugins/logs_shared/server/logs_shared_server.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 { LogsSharedBackendLibs } from './lib/logs_shared_types'; +import { + initLogEntriesHighlightsRoute, + initLogEntriesSummaryHighlightsRoute, + initLogEntriesSummaryRoute, +} from './routes/log_entries'; +import { initLogViewRoutes } from './routes/log_views'; + +export const initLogsSharedServer = (libs: LogsSharedBackendLibs) => { + initLogEntriesHighlightsRoute(libs); + initLogEntriesSummaryRoute(libs); + initLogEntriesSummaryHighlightsRoute(libs); + initLogViewRoutes(libs); +}; diff --git a/x-pack/plugins/logs_shared/server/mocks.ts b/x-pack/plugins/logs_shared/server/mocks.ts new file mode 100644 index 0000000000000..a8b16381d32f3 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/mocks.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createLogsSharedLogEntriesDomainMock } from './lib/domains/log_entries_domain/log_entries_domain.mock'; +import { + createLogViewsServiceSetupMock, + createLogViewsServiceStartMock, +} from './services/log_views/log_views_service.mock'; +import { LogsSharedPluginSetup, LogsSharedPluginStart } from './types'; + +const createLogsSharedSetupMock = () => { + const logsSharedSetupMock: jest.Mocked = { + logViews: createLogViewsServiceSetupMock(), + logEntries: createLogsSharedLogEntriesDomainMock(), + registerUsageCollectorActions: jest.fn(), + }; + + return logsSharedSetupMock; +}; + +const createLogsSharedStartMock = () => { + const logsSharedStartMock: jest.Mocked = { + logViews: createLogViewsServiceStartMock(), + }; + return logsSharedStartMock; +}; + +export const logsSharedPluginMock = { + createSetupContract: createLogsSharedSetupMock, + createStartContract: createLogsSharedStartMock, +}; diff --git a/x-pack/plugins/logs_shared/server/plugin.ts b/x-pack/plugins/logs_shared/server/plugin.ts new file mode 100644 index 0000000000000..6ccf743dba7f2 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/plugin.ts @@ -0,0 +1,98 @@ +/* + * 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 { PluginInitializerContext, CoreStart, Plugin, Logger } from '@kbn/core/server'; + +import { + LogsSharedPluginCoreSetup, + LogsSharedPluginSetup, + LogsSharedPluginStart, + LogsSharedServerPluginSetupDeps, + LogsSharedServerPluginStartDeps, + UsageCollector, +} from './types'; +import { logViewSavedObjectType } from './saved_objects'; +import { initLogsSharedServer } from './logs_shared_server'; +import { LogViewsService } from './services/log_views'; +import { KibanaFramework } from './lib/adapters/framework/kibana_framework_adapter'; +import { LogsSharedBackendLibs, LogsSharedDomainLibs } from './lib/logs_shared_types'; +import { LogsSharedLogEntriesDomain } from './lib/domains/log_entries_domain'; +import { LogsSharedKibanaLogEntriesAdapter } from './lib/adapters/log_entries/kibana_log_entries_adapter'; +import { LogEntriesService } from './services/log_entries'; + +export class LogsSharedPlugin + implements + Plugin< + LogsSharedPluginSetup, + LogsSharedPluginStart, + LogsSharedServerPluginSetupDeps, + LogsSharedServerPluginStartDeps + > +{ + private readonly logger: Logger; + private libs!: LogsSharedBackendLibs; + private logViews: LogViewsService; + private usageCollector: UsageCollector; + + constructor(context: PluginInitializerContext) { + this.logger = context.logger.get(); + this.usageCollector = {}; + + this.logViews = new LogViewsService(this.logger.get('logViews')); + } + + public setup(core: LogsSharedPluginCoreSetup, plugins: LogsSharedServerPluginSetupDeps) { + const framework = new KibanaFramework(core, plugins); + + const logViews = this.logViews.setup(); + + // Register saved objects + core.savedObjects.registerType(logViewSavedObjectType); + + const domainLibs: LogsSharedDomainLibs = { + logEntries: new LogsSharedLogEntriesDomain(new LogsSharedKibanaLogEntriesAdapter(framework), { + framework, + getStartServices: () => core.getStartServices(), + }), + }; + + this.libs = { + ...domainLibs, + basePath: core.http.basePath, + framework, + getStartServices: () => core.getStartServices(), + logger: this.logger, + getUsageCollector: () => this.usageCollector, + }; + + // Register server side APIs + initLogsSharedServer(this.libs); + + const logEntriesService = new LogEntriesService(); + logEntriesService.setup(core, plugins); + + return { + ...domainLibs, + logViews, + registerUsageCollectorActions: (usageCollector: UsageCollector) => { + Object.assign(this.usageCollector, usageCollector); + }, + }; + } + + public start(core: CoreStart, plugins: LogsSharedServerPluginStartDeps) { + const logViews = this.logViews.start({ + savedObjects: core.savedObjects, + dataViews: plugins.dataViews, + elasticsearch: core.elasticsearch, + }); + + return { logViews }; + } + + public stop() {} +} diff --git a/x-pack/plugins/infra/server/routes/log_entries/highlights.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/highlights.ts similarity index 96% rename from x-pack/plugins/infra/server/routes/log_entries/highlights.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/highlights.ts index 9d81e0d349f46..e8019c58d6000 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/highlights.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_entries/highlights.ts @@ -15,14 +15,14 @@ import { schema } from '@kbn/config-schema'; import { logEntriesV1 } from '../../../common/http_api'; import { throwErrors } from '../../../common/runtime_types'; -import { InfraBackendLibs } from '../../lib/infra_types'; +import { LogsSharedBackendLibs } from '../../lib/logs_shared_types'; import { parseFilterQuery } from '../../utils/serialized_query'; import { LogEntriesParams } from '../../lib/domains/log_entries_domain'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); -export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: InfraBackendLibs) => { +export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: LogsSharedBackendLibs) => { framework .registerVersionedRoute({ access: 'internal', diff --git a/x-pack/plugins/infra/server/routes/log_entries/index.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/index.ts similarity index 100% rename from x-pack/plugins/infra/server/routes/log_entries/index.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/index.ts diff --git a/x-pack/plugins/infra/server/routes/log_entries/summary.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/summary.ts similarity index 83% rename from x-pack/plugins/infra/server/routes/log_entries/summary.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/summary.ts index ee042f51d1dc8..2ac889ab9ffdf 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/summary.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_entries/summary.ts @@ -15,14 +15,17 @@ import { schema } from '@kbn/config-schema'; import { logEntriesV1 } from '../../../common/http_api'; import { throwErrors } from '../../../common/runtime_types'; -import { InfraBackendLibs } from '../../lib/infra_types'; +import { LogsSharedBackendLibs } from '../../lib/logs_shared_types'; import { parseFilterQuery } from '../../utils/serialized_query'; -import { UsageCollector } from '../../usage/usage_collector'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); -export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBackendLibs) => { +export const initLogEntriesSummaryRoute = ({ + framework, + logEntries, + getUsageCollector, +}: LogsSharedBackendLibs) => { framework .registerVersionedRoute({ access: 'internal', @@ -41,6 +44,8 @@ export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBacke ); const { logView, startTimestamp, endTimestamp, bucketSize, query } = payload; + const usageCollector = getUsageCollector(); + const buckets = await logEntries.getLogSummaryBucketsBetween( requestContext, logView, @@ -50,7 +55,9 @@ export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBacke parseFilterQuery(query) ); - UsageCollector.countLogs(); + if (typeof usageCollector.countLogs === 'function') { + usageCollector.countLogs(); + } return response.ok({ body: logEntriesV1.logEntriesSummaryResponseRT.encode({ diff --git a/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts b/x-pack/plugins/logs_shared/server/routes/log_entries/summary_highlights.ts similarity index 95% rename from x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts rename to x-pack/plugins/logs_shared/server/routes/log_entries/summary_highlights.ts index e831ec51c4145..b4093f1d6543b 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_entries/summary_highlights.ts @@ -15,7 +15,7 @@ import { schema } from '@kbn/config-schema'; import { logEntriesV1 } from '../../../common/http_api'; import { throwErrors } from '../../../common/runtime_types'; -import { InfraBackendLibs } from '../../lib/infra_types'; +import { LogsSharedBackendLibs } from '../../lib/logs_shared_types'; import { parseFilterQuery } from '../../utils/serialized_query'; @@ -24,7 +24,7 @@ const escapeHatch = schema.object({}, { unknowns: 'allow' }); export const initLogEntriesSummaryHighlightsRoute = ({ framework, logEntries, -}: InfraBackendLibs) => { +}: LogsSharedBackendLibs) => { framework .registerVersionedRoute({ access: 'internal', diff --git a/x-pack/plugins/infra/server/routes/log_views/get_log_view.ts b/x-pack/plugins/logs_shared/server/routes/log_views/get_log_view.ts similarity index 92% rename from x-pack/plugins/infra/server/routes/log_views/get_log_view.ts rename to x-pack/plugins/logs_shared/server/routes/log_views/get_log_view.ts index 0c3cb7cbac2af..ef6e69f07d0ef 100644 --- a/x-pack/plugins/infra/server/routes/log_views/get_log_view.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_views/get_log_view.ts @@ -9,14 +9,14 @@ import { logViewsV1 } from '../../../common/http_api'; import { LOG_VIEW_URL } from '../../../common/http_api/log_views'; import { createValidationFunction } from '../../../common/runtime_types'; import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter'; -import type { InfraPluginStartServicesAccessor } from '../../types'; +import type { LogsSharedPluginStartServicesAccessor } from '../../types'; export const initGetLogViewRoute = ({ framework, getStartServices, }: { framework: KibanaFramework; - getStartServices: InfraPluginStartServicesAccessor; + getStartServices: LogsSharedPluginStartServicesAccessor; }) => { framework .registerVersionedRoute({ diff --git a/x-pack/plugins/infra/server/routes/log_views/index.ts b/x-pack/plugins/logs_shared/server/routes/log_views/index.ts similarity index 82% rename from x-pack/plugins/infra/server/routes/log_views/index.ts rename to x-pack/plugins/logs_shared/server/routes/log_views/index.ts index fa7e6f6e1b9d3..b2670cfa3e40a 100644 --- a/x-pack/plugins/infra/server/routes/log_views/index.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_views/index.ts @@ -6,13 +6,13 @@ */ import { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter'; -import { InfraPluginStartServicesAccessor } from '../../types'; +import { LogsSharedPluginStartServicesAccessor } from '../../types'; import { initGetLogViewRoute } from './get_log_view'; import { initPutLogViewRoute } from './put_log_view'; export const initLogViewRoutes = (dependencies: { framework: KibanaFramework; - getStartServices: InfraPluginStartServicesAccessor; + getStartServices: LogsSharedPluginStartServicesAccessor; }) => { initGetLogViewRoute(dependencies); initPutLogViewRoute(dependencies); diff --git a/x-pack/plugins/infra/server/routes/log_views/put_log_view.ts b/x-pack/plugins/logs_shared/server/routes/log_views/put_log_view.ts similarity index 93% rename from x-pack/plugins/infra/server/routes/log_views/put_log_view.ts rename to x-pack/plugins/logs_shared/server/routes/log_views/put_log_view.ts index 310960156abfc..899200902aa1e 100644 --- a/x-pack/plugins/infra/server/routes/log_views/put_log_view.ts +++ b/x-pack/plugins/logs_shared/server/routes/log_views/put_log_view.ts @@ -9,14 +9,14 @@ import { logViewsV1 } from '../../../common/http_api'; import { LOG_VIEW_URL } from '../../../common/http_api/log_views'; import { createValidationFunction } from '../../../common/runtime_types'; import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter'; -import type { InfraPluginStartServicesAccessor } from '../../types'; +import type { LogsSharedPluginStartServicesAccessor } from '../../types'; export const initPutLogViewRoute = ({ framework, getStartServices, }: { framework: KibanaFramework; - getStartServices: InfraPluginStartServicesAccessor; + getStartServices: LogsSharedPluginStartServicesAccessor; }) => { framework .registerVersionedRoute({ diff --git a/x-pack/plugins/logs_shared/server/saved_objects/index.ts b/x-pack/plugins/logs_shared/server/saved_objects/index.ts new file mode 100644 index 0000000000000..bd7ecac5179a1 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/saved_objects/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 './log_view'; diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/index.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/index.ts similarity index 100% rename from x-pack/plugins/infra/server/saved_objects/log_view/index.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/index.ts diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/log_view_saved_object.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/log_view_saved_object.ts similarity index 100% rename from x-pack/plugins/infra/server/saved_objects/log_view/log_view_saved_object.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/log_view_saved_object.ts index 9202227867dca..246c398ea5a65 100644 --- a/x-pack/plugins/infra/server/saved_objects/log_view/log_view_saved_object.ts +++ b/x-pack/plugins/logs_shared/server/saved_objects/log_view/log_view_saved_object.ts @@ -5,9 +5,9 @@ * 2.0. */ +import { SavedObject, SavedObjectsType } from '@kbn/core/server'; import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; -import { SavedObject, SavedObjectsType } from '@kbn/core/server'; import { logViewSavedObjectRT } from './types'; export const logViewSavedObjectName = 'infrastructure-monitoring-log-view'; diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/references/index.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/references/index.ts similarity index 100% rename from x-pack/plugins/infra/server/saved_objects/log_view/references/index.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/references/index.ts diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/references/log_indices.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/references/log_indices.ts similarity index 85% rename from x-pack/plugins/infra/server/saved_objects/log_view/references/log_indices.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/references/log_indices.ts index ea45be30bc0b7..660f01f47eb5e 100644 --- a/x-pack/plugins/infra/server/saved_objects/log_view/references/log_indices.ts +++ b/x-pack/plugins/logs_shared/server/saved_objects/log_view/references/log_indices.ts @@ -7,24 +7,24 @@ import { SavedObjectReference } from '@kbn/core/server'; import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common'; -import { LogViewAttributes } from '../../../../common/log_views'; import { SavedObjectAttributesWithReferences, SavedObjectReferenceResolutionError, } from '../../references'; +import { LogViewSavedObjectAttributes } from '../types'; export const logIndicesDataViewReferenceName = 'log-indices-data-view-0'; export const extractLogIndicesSavedObjectReferences = ( - unextractedAttributes: LogViewAttributes -): SavedObjectAttributesWithReferences => { + unextractedAttributes: LogViewSavedObjectAttributes +): SavedObjectAttributesWithReferences => { if (unextractedAttributes.logIndices.type === 'data_view') { const logDataViewReference: SavedObjectReference = { id: unextractedAttributes.logIndices.dataViewId, type: DATA_VIEW_SAVED_OBJECT_TYPE, name: logIndicesDataViewReferenceName, }; - const attributes: LogViewAttributes = { + const attributes: LogViewSavedObjectAttributes = { ...unextractedAttributes, logIndices: { ...unextractedAttributes.logIndices, @@ -44,9 +44,9 @@ export const extractLogIndicesSavedObjectReferences = ( }; export const resolveLogIndicesSavedObjectReferences = ( - attributes: LogViewAttributes, + attributes: LogViewSavedObjectAttributes, references: SavedObjectReference[] -): LogViewAttributes => { +): LogViewSavedObjectAttributes => { if (attributes.logIndices?.type === 'data_view') { const logDataViewReference = references.find( (reference) => reference.name === logIndicesDataViewReferenceName diff --git a/x-pack/plugins/infra/server/saved_objects/log_view/types.ts b/x-pack/plugins/logs_shared/server/saved_objects/log_view/types.ts similarity index 95% rename from x-pack/plugins/infra/server/saved_objects/log_view/types.ts rename to x-pack/plugins/logs_shared/server/saved_objects/log_view/types.ts index 34387b5e33085..fb8bf49781a2d 100644 --- a/x-pack/plugins/infra/server/saved_objects/log_view/types.ts +++ b/x-pack/plugins/logs_shared/server/saved_objects/log_view/types.ts @@ -58,6 +58,8 @@ export const logViewSavedObjectAttributesRT = rt.strict({ logColumns: rt.array(logViewSavedObjectColumnConfigurationRT), }); +export type LogViewSavedObjectAttributes = rt.TypeOf; + export const logViewSavedObjectRT = rt.intersection([ rt.type({ id: rt.string, diff --git a/x-pack/plugins/logs_shared/server/saved_objects/references.test.ts b/x-pack/plugins/logs_shared/server/saved_objects/references.test.ts new file mode 100644 index 0000000000000..674aabbd9d058 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/saved_objects/references.test.ts @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SavedObjectReference } from '@kbn/core/server'; +import { + extractSavedObjectReferences, + resolveSavedObjectReferences, + SavedObjectAttributesWithReferences, +} from './references'; + +it('extractSavedObjectReferences extracts references using the given extractors', () => { + const { attributes, references } = extractSavedObjectReferences([ + extractReferenceA, + extractReferenceB, + ])({ + a: 'id-a', + b: 'id-b', + c: 'something-else', + }); + + expect(references).toMatchObject([ + { id: 'id-a', name: REFERENCE_A_NAME, type: 'some-reference' }, + { id: 'id-b', name: REFERENCE_B_NAME, type: 'some-reference' }, + ]); + expect(attributes).toMatchObject({ + a: REFERENCE_A_NAME, + b: REFERENCE_B_NAME, + c: 'something-else', + }); +}); + +it('resolveSavedObjectReferences resolves references using the given resolvers', () => { + const attributes = resolveSavedObjectReferences([resolveReferenceA, resolveReferenceB])( + { + a: REFERENCE_A_NAME, + b: REFERENCE_B_NAME, + c: 'something-else', + }, + [ + { id: 'id-a', name: REFERENCE_A_NAME, type: 'some-reference' }, + { id: 'id-b', name: REFERENCE_B_NAME, type: 'some-reference' }, + ] + ); + + expect(attributes).toMatchObject({ + a: 'id-a', + b: 'id-b', + c: 'something-else', + }); +}); + +interface TestSavedObjectAttributes { + a: string; + b: string; + c: string; +} + +const REFERENCE_A_NAME = 'reference-a'; +const REFERENCE_B_NAME = 'reference-b'; + +const extractReferenceA = ( + attributes: TestSavedObjectAttributes +): SavedObjectAttributesWithReferences => ({ + attributes: { ...attributes, a: REFERENCE_A_NAME }, + references: [ + { + id: attributes.a, + name: REFERENCE_A_NAME, + type: 'some-reference', + }, + ], +}); + +const extractReferenceB = ( + attributes: TestSavedObjectAttributes +): SavedObjectAttributesWithReferences => ({ + attributes: { ...attributes, b: REFERENCE_B_NAME }, + references: [ + { + id: attributes.b, + name: REFERENCE_B_NAME, + type: 'some-reference', + }, + ], +}); + +const resolveReferenceA = ( + attributes: TestSavedObjectAttributes, + references: SavedObjectReference[] +): TestSavedObjectAttributes => { + const referenceA = references.find((reference) => reference.name === REFERENCE_A_NAME); + + if (referenceA != null) { + return { + ...attributes, + a: referenceA.id, + }; + } else { + return attributes; + } +}; + +const resolveReferenceB = ( + attributes: TestSavedObjectAttributes, + references: SavedObjectReference[] +): TestSavedObjectAttributes => { + const referenceB = references.find((reference) => reference.name === REFERENCE_B_NAME); + + if (referenceB != null) { + return { + ...attributes, + b: referenceB.id, + }; + } else { + return attributes; + } +}; diff --git a/x-pack/plugins/logs_shared/server/saved_objects/references.ts b/x-pack/plugins/logs_shared/server/saved_objects/references.ts new file mode 100644 index 0000000000000..13b64ab6e6e73 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/saved_objects/references.ts @@ -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 * as rt from 'io-ts'; +import { SavedObject, SavedObjectReference } from '@kbn/core/server'; + +export type SavedObjectAttributesWithReferences = Pick< + SavedObject, + 'attributes' | 'references' +>; + +export type SavedObjectReferenceExtractor = ( + savedObjectAttributes: SavedObjectAttributes +) => SavedObjectAttributesWithReferences; + +export type SavedObjectReferenceResolver = ( + savedObjectAttributes: SavedObjectAttributes, + references: SavedObjectReference[] +) => SavedObjectAttributes; + +export const savedObjectReferenceRT = rt.strict({ + name: rt.string, + type: rt.string, + id: rt.string, +}); + +/** + * Rewrites a saved object such that well-known saved object references + * are extracted in the `references` array and replaced by the appropriate + * name. This is the inverse operation to `resolveSavedObjectReferences`. + */ +export const extractSavedObjectReferences = + ( + referenceExtractors: Array> + ) => + ( + savedObjectAttributes: SavedObjectAttributes + ): SavedObjectAttributesWithReferences => + referenceExtractors.reduce>( + ({ attributes: accumulatedAttributes, references: accumulatedReferences }, extract) => { + const { attributes, references } = extract(accumulatedAttributes); + return { + attributes, + references: [...accumulatedReferences, ...references], + }; + }, + { + attributes: savedObjectAttributes, + references: [], + } + ); + +/** + * Rewrites a source configuration such that well-known saved object references + * are resolved from the `references` argument and replaced by the real saved + * object ids. This is the inverse operation to `extractSavedObjectReferences`. + */ +export const resolveSavedObjectReferences = + ( + referenceResolvers: Array> + ) => + (attributes: SavedObjectAttributes, references: SavedObjectReference[]): SavedObjectAttributes => + referenceResolvers.reduce( + (accumulatedAttributes, resolve) => resolve(accumulatedAttributes, references), + attributes + ); + +export class SavedObjectReferenceResolutionError extends Error { + constructor(message?: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + this.name = 'SavedObjectReferenceResolutionError'; + } +} diff --git a/x-pack/plugins/infra/server/services/log_entries/index.ts b/x-pack/plugins/logs_shared/server/services/log_entries/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/index.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/index.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entries_search_strategy.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_service.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entries_service.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entries_service.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entries_service.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts b/x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/log_entry_search_strategy.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_apache2.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_auditd.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_haproxy.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_icinga.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_iis.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_iis.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_kafka.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_logstash.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mongodb.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_mysql.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_nginx.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_osquery.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_redis.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_redis.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_redis.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_redis.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_system.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_system.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_system.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_system.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/filebeat_traefik.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.test.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.test.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.test.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.test.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic_webserver.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic_webserver.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/generic_webserver.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/generic_webserver.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/helpers.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/helpers.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/helpers.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/helpers.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/index.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/builtin_rules/index.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/builtin_rules/index.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/index.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/index.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/index.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/message.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/message.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/message.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/message.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts b/x-pack/plugins/logs_shared/server/services/log_entries/message/rule_types.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/message/rule_types.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/queries/common.ts b/x-pack/plugins/logs_shared/server/services/log_entries/queries/common.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/queries/common.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/queries/common.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/queries/log_entries.ts b/x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entries.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/queries/log_entries.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entries.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/queries/log_entry.ts b/x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entry.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/queries/log_entry.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/queries/log_entry.ts diff --git a/x-pack/plugins/infra/server/services/log_entries/types.ts b/x-pack/plugins/logs_shared/server/services/log_entries/types.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_entries/types.ts rename to x-pack/plugins/logs_shared/server/services/log_entries/types.ts diff --git a/x-pack/plugins/infra/server/services/log_views/errors.ts b/x-pack/plugins/logs_shared/server/services/log_views/errors.ts similarity index 65% rename from x-pack/plugins/infra/server/services/log_views/errors.ts rename to x-pack/plugins/logs_shared/server/services/log_views/errors.ts index fb0dc3b031511..088dd6244bba6 100644 --- a/x-pack/plugins/infra/server/services/log_views/errors.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/errors.ts @@ -5,9 +5,18 @@ * 2.0. */ +/* eslint-disable max-classes-per-file */ + export class NotFoundError extends Error { constructor(message?: string) { super(message); Object.setPrototypeOf(this, new.target.prototype); } } + +export class LogViewFallbackUnregisteredError extends Error { + constructor(message?: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + } +} diff --git a/x-pack/plugins/infra/server/services/log_views/index.ts b/x-pack/plugins/logs_shared/server/services/log_views/index.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_views/index.ts rename to x-pack/plugins/logs_shared/server/services/log_views/index.ts diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_client.mock.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.mock.ts similarity index 100% rename from x-pack/plugins/infra/server/services/log_views/log_views_client.mock.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_client.mock.ts diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_client.test.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts similarity index 88% rename from x-pack/plugins/infra/server/services/log_views/log_views_client.test.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts index e517ae8aef7f0..5efdf9e125deb 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_client.test.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts @@ -17,42 +17,11 @@ import { LogViewsStaticConfig, } from '../../../common/log_views'; import { createLogViewMock } from '../../../common/log_views/log_view.mock'; -import { InfraSource } from '../../lib/sources'; -import { createInfraSourcesMock } from '../../lib/sources/mocks'; import { extractLogViewSavedObjectReferences, logViewSavedObjectName, } from '../../saved_objects/log_view'; -import { getAttributesFromSourceConfiguration, LogViewsClient } from './log_views_client'; - -describe('getAttributesFromSourceConfiguration function', () => { - it('converts the index_pattern log indices type to data_view', () => { - const logViewAttributes = getAttributesFromSourceConfiguration(basicTestSourceConfiguration); - - expect(logViewAttributes.logIndices).toEqual({ - type: 'data_view', - dataViewId: 'INDEX_PATTERN_ID', - }); - }); - - it('preserves the index_name log indices type', () => { - const logViewAttributes = getAttributesFromSourceConfiguration({ - ...basicTestSourceConfiguration, - configuration: { - ...basicTestSourceConfiguration.configuration, - logIndices: { - type: 'index_name', - indexName: 'INDEX_NAME', - }, - }, - }); - - expect(logViewAttributes.logIndices).toEqual({ - type: 'index_name', - indexName: 'INDEX_NAME', - }); - }); -}); +import { LogViewsClient } from './log_views_client'; describe('LogViewsClient class', () => { it('getLogView resolves the default id to a real saved object id if it exists', async () => { @@ -116,9 +85,9 @@ describe('LogViewsClient class', () => { }); it('getLogView preserves the default id for fallback lookups', async () => { - const { infraSources, logViewsClient, savedObjectsClient } = createLogViewsClient(); + const { logViewFallbackHandler, logViewsClient, savedObjectsClient } = createLogViewsClient(); - infraSources.getSourceConfiguration.mockResolvedValue(basicTestSourceConfiguration); + logViewFallbackHandler.mockResolvedValue(basicTestSourceConfiguration); savedObjectsClient.find.mockResolvedValue({ total: 0, @@ -129,10 +98,9 @@ describe('LogViewsClient class', () => { await logViewsClient.getLogView(defaultLogViewId); - expect(infraSources.getSourceConfiguration).toHaveBeenCalledWith( - savedObjectsClient, - defaultLogViewId - ); + expect(logViewFallbackHandler).toHaveBeenCalledWith(defaultLogViewId, { + soClient: savedObjectsClient, + }); }); it('putLogView resolves the default id to a real saved object id if one exists', async () => { @@ -364,7 +332,7 @@ const createLogViewsClient = () => { const logger = loggerMock.create(); const dataViews = dataViewsServiceMock; const savedObjectsClient = savedObjectsClientMock.create(); - const infraSources = createInfraSourcesMock(); + const logViewFallbackHandler = jest.fn(); const internalLogViews = new Map(); const logViewStaticConfig: LogViewsStaticConfig = { messageFields: ['message'], @@ -374,14 +342,14 @@ const createLogViewsClient = () => { logger, Promise.resolve(dataViews), savedObjectsClient, - infraSources, + logViewFallbackHandler, internalLogViews, logViewStaticConfig ); return { dataViews, - infraSources, + logViewFallbackHandler, internalLogViews, logViewStaticConfig, logViewsClient, @@ -389,7 +357,7 @@ const createLogViewsClient = () => { }; }; -const basicTestSourceConfiguration: InfraSource = { +const basicTestSourceConfiguration = { id: 'ID', origin: 'stored', configuration: { diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_client.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.ts similarity index 77% rename from x-pack/plugins/infra/server/services/log_views/log_views_client.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_client.ts index 3f832c6770717..452bc1b3b969e 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_client.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.ts @@ -16,7 +16,6 @@ import { import { defaultLogViewAttributes, defaultLogViewId, - LogIndexReference, LogView, LogViewAttributes, LogViewReference, @@ -26,16 +25,14 @@ import { resolveLogView, } from '../../../common/log_views'; import { decodeOrThrow } from '../../../common/runtime_types'; -import { LogIndexReference as SourceConfigurationLogIndexReference } from '../../../common/source_configuration/source_configuration'; -import type { IInfraSources, InfraSource } from '../../lib/sources'; import { extractLogViewSavedObjectReferences, logViewSavedObjectName, resolveLogViewSavedObjectReferences, } from '../../saved_objects/log_view'; import { logViewSavedObjectRT } from '../../saved_objects/log_view/types'; -import { NotFoundError } from './errors'; -import { ILogViewsClient } from './types'; +import { LogViewFallbackUnregisteredError, NotFoundError } from './errors'; +import { ILogViewsClient, LogViewFallbackHandler } from './types'; type DataViewsService = ReturnType; @@ -48,7 +45,7 @@ export class LogViewsClient implements ILogViewsClient { private readonly logger: Logger, private readonly dataViews: DataViewsService, private readonly savedObjectsClient: SavedObjectsClientContract, - private readonly infraSources: IInfraSources, + private readonly logViewFallbackHandler: LogViewFallbackHandler, private readonly internalLogViews: Map, private readonly config: LogViewsStaticConfig ) {} @@ -62,7 +59,7 @@ export class LogViewsClient implements ILogViewsClient { ) .catch((err) => err instanceof NotFoundError - ? this.getLogViewFromInfraSourceConfiguration(logViewId) + ? this.getLogViewFromLogsSharedSourceConfiguration(logViewId) : Promise.reject(err) ); } @@ -142,21 +139,16 @@ export class LogViewsClient implements ILogViewsClient { return internalLogView; } - private async getLogViewFromInfraSourceConfiguration(sourceId: string): Promise { - this.logger.debug(`Trying to load log view from source configuration "${sourceId}"...`); + private async getLogViewFromLogsSharedSourceConfiguration(sourceId: string): Promise { + this.logger.debug(`Trying to load log view from fallback configuration "${sourceId}"...`); - const sourceConfiguration = await this.infraSources.getSourceConfiguration( - this.savedObjectsClient, - sourceId - ); + if (this.logViewFallbackHandler === null) { + throw new LogViewFallbackUnregisteredError( + 'A fallback LogView handler is not registered. Register one in the setup method of your server plugin.' + ); + } - return { - id: sourceConfiguration.id, - version: sourceConfiguration.version, - updatedAt: sourceConfiguration.updatedAt, - origin: `infra-source-${sourceConfiguration.origin}`, - attributes: getAttributesFromSourceConfiguration(sourceConfiguration), - }; + return this.logViewFallbackHandler(sourceId, { soClient: this.savedObjectsClient }); } private async resolveLogViewId(logViewId: string): Promise { @@ -197,22 +189,3 @@ const getLogViewFromSavedObject = (savedObject: SavedObject): LogView = ), }; }; - -export const getAttributesFromSourceConfiguration = ({ - configuration: { name, description, logIndices, logColumns }, -}: InfraSource): LogViewAttributes => ({ - name, - description, - logIndices: getLogIndicesFromSourceConfigurationLogIndices(logIndices), - logColumns, -}); - -const getLogIndicesFromSourceConfigurationLogIndices = ( - logIndices: SourceConfigurationLogIndexReference -): LogIndexReference => - logIndices.type === 'index_pattern' - ? { - type: 'data_view', - dataViewId: logIndices.indexPatternId, - } - : logIndices; diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_service.mock.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.mock.ts similarity index 90% rename from x-pack/plugins/infra/server/services/log_views/log_views_service.mock.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_service.mock.ts index e472e30fae2b4..295b1fd77452f 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_service.mock.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.mock.ts @@ -10,6 +10,8 @@ import { LogViewsServiceSetup, LogViewsServiceStart } from './types'; export const createLogViewsServiceSetupMock = (): jest.Mocked => ({ defineInternalLogView: jest.fn(), + registerLogViewFallbackHandler: jest.fn(), + setLogViewsStaticConfig: jest.fn(), }); export const createLogViewsServiceStartMock = (): jest.Mocked => ({ diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_service.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.ts similarity index 65% rename from x-pack/plugins/infra/server/services/log_views/log_views_service.ts rename to x-pack/plugins/logs_shared/server/services/log_views/log_views_service.ts index cf1c7595ae5cb..5479c16dff411 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_service.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_service.ts @@ -11,12 +11,25 @@ import { Logger, SavedObjectsClientContract, } from '@kbn/core/server'; -import { defaultLogViewAttributes, LogView, LogViewAttributes } from '../../../common/log_views'; +import { + defaultLogViewAttributes, + defaultLogViewsStaticConfig, + LogView, + LogViewAttributes, + LogViewsStaticConfig, +} from '../../../common/log_views'; import { LogViewsClient } from './log_views_client'; -import { LogViewsServiceSetup, LogViewsServiceStart, LogViewsServiceStartDeps } from './types'; +import { + LogViewFallbackHandler, + LogViewsServiceSetup, + LogViewsServiceStart, + LogViewsServiceStartDeps, +} from './types'; export class LogViewsService { private internalLogViews: Map = new Map(); + private logViewFallbackHandler: LogViewFallbackHandler | null = null; + private logViewsStaticConfig: LogViewsStaticConfig = defaultLogViewsStaticConfig; constructor(private readonly logger: Logger) {} @@ -24,7 +37,7 @@ export class LogViewsService { const { internalLogViews } = this; return { - defineInternalLogView(logViewId: string, logViewAttributes: Partial) { + defineInternalLogView: (logViewId: string, logViewAttributes: Partial) => { internalLogViews.set(logViewId, { id: logViewId, origin: 'internal', @@ -32,17 +45,21 @@ export class LogViewsService { updatedAt: Date.now(), }); }, + registerLogViewFallbackHandler: (handler) => { + this.logViewFallbackHandler = handler; + }, + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => { + this.logViewsStaticConfig = config; + }, }; } public start({ - config, dataViews, elasticsearch, - infraSources, savedObjects, }: LogViewsServiceStartDeps): LogViewsServiceStart { - const { internalLogViews, logger } = this; + const { internalLogViews, logger, logViewFallbackHandler, logViewsStaticConfig } = this; return { getClient( @@ -54,9 +71,9 @@ export class LogViewsService { logger, dataViews.dataViewsServiceFactory(savedObjectsClient, elasticsearchClient, request), savedObjectsClient, - infraSources, + logViewFallbackHandler, internalLogViews, - config + logViewsStaticConfig ); }, getScopedClient(request: KibanaRequest) { diff --git a/x-pack/plugins/infra/server/services/log_views/types.ts b/x-pack/plugins/logs_shared/server/services/log_views/types.ts similarity index 81% rename from x-pack/plugins/infra/server/services/log_views/types.ts rename to x-pack/plugins/logs_shared/server/services/log_views/types.ts index b5f91cb3587b4..db1410207c11a 100644 --- a/x-pack/plugins/infra/server/services/log_views/types.ts +++ b/x-pack/plugins/logs_shared/server/services/log_views/types.ts @@ -20,18 +20,25 @@ import { LogViewsStaticConfig, ResolvedLogView, } from '../../../common/log_views'; -import { InfraSources } from '../../lib/sources'; export interface LogViewsServiceStartDeps { - config: LogViewsStaticConfig; dataViews: DataViewsServerPluginStart; elasticsearch: ElasticsearchServiceStart; - infraSources: InfraSources; savedObjects: SavedObjectsServiceStart; } +export interface LogViewFallbackHandlerOptions { + soClient: SavedObjectsClientContract; +} + +export type LogViewFallbackHandler = + | ((sourceId: string, options: LogViewFallbackHandlerOptions) => Promise) + | null; + export interface LogViewsServiceSetup { defineInternalLogView(logViewId: string, logViewAttributes: Partial): void; + registerLogViewFallbackHandler: (handler: LogViewFallbackHandler) => void; + setLogViewsStaticConfig: (config: LogViewsStaticConfig) => void; } export interface LogViewsServiceStart { diff --git a/x-pack/plugins/logs_shared/server/types.ts b/x-pack/plugins/logs_shared/server/types.ts new file mode 100644 index 0000000000000..2e922eceeb183 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/types.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 type { CoreSetup, RequestHandlerContext } from '@kbn/core/server'; +import { + PluginSetup as DataPluginSetup, + PluginStart as DataPluginStart, +} from '@kbn/data-plugin/server'; +import { PluginStart as DataViewsPluginStart } from '@kbn/data-views-plugin/server'; +import { LogsSharedDomainLibs } from './lib/logs_shared_types'; +import { LogViewsServiceSetup, LogViewsServiceStart } from './services/log_views/types'; + +export type LogsSharedPluginCoreSetup = CoreSetup< + LogsSharedServerPluginStartDeps, + LogsSharedPluginStart +>; +export type LogsSharedPluginStartServicesAccessor = LogsSharedPluginCoreSetup['getStartServices']; + +export interface LogsSharedPluginSetup extends LogsSharedDomainLibs { + logViews: LogViewsServiceSetup; + registerUsageCollectorActions: (usageCollector: UsageCollector) => void; +} + +export interface LogsSharedPluginStart { + logViews: LogViewsServiceStart; +} + +export interface LogsSharedServerPluginSetupDeps { + data: DataPluginSetup; +} + +export interface LogsSharedServerPluginStartDeps { + data: DataPluginStart; + dataViews: DataViewsPluginStart; +} + +export interface UsageCollector { + countLogs?: () => void; +} + +/** + * @internal + */ +export type LogsSharedPluginRequestHandlerContext = RequestHandlerContext; diff --git a/x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts b/x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts new file mode 100644 index 0000000000000..e2dbf02ae2d06 --- /dev/null +++ b/x-pack/plugins/logs_shared/server/utils/elasticsearch_runtime_types.ts @@ -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 * as rt from 'io-ts'; + +export const shardFailureRT = rt.partial({ + index: rt.union([rt.string, rt.null]), + node: rt.union([rt.string, rt.null]), + reason: rt.partial({ + reason: rt.union([rt.string, rt.null]), + type: rt.union([rt.string, rt.null]), + }), + shard: rt.number, +}); + +export type ShardFailure = rt.TypeOf; + +export const commonSearchSuccessResponseFieldsRT = rt.type({ + _shards: rt.intersection([ + rt.type({ + total: rt.number, + successful: rt.number, + skipped: rt.number, + failed: rt.number, + }), + rt.partial({ + failures: rt.array(shardFailureRT), + }), + ]), + timed_out: rt.boolean, + took: rt.number, +}); + +export const commonHitFieldsRT = rt.type({ + _index: rt.string, + _id: rt.string, +}); diff --git a/x-pack/plugins/logs_shared/server/utils/serialized_query.ts b/x-pack/plugins/logs_shared/server/utils/serialized_query.ts new file mode 100644 index 0000000000000..b3b2569528aea --- /dev/null +++ b/x-pack/plugins/logs_shared/server/utils/serialized_query.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { JsonObject } from '@kbn/utility-types'; + +export const parseFilterQuery = ( + filterQuery: string | null | undefined +): JsonObject | undefined => { + try { + if (filterQuery) { + const parsedFilterQuery = JSON.parse(filterQuery); + if ( + !parsedFilterQuery || + ['string', 'number', 'boolean'].includes(typeof parsedFilterQuery) || + Array.isArray(parsedFilterQuery) + ) { + throw new Error('expected value to be an object'); + } + return parsedFilterQuery; + } else { + return undefined; + } + } catch (err) { + throw new Error(`Failed to parse query: ${err}`); + } +}; diff --git a/x-pack/plugins/infra/server/utils/typed_search_strategy.ts b/x-pack/plugins/logs_shared/server/utils/typed_search_strategy.ts similarity index 100% rename from x-pack/plugins/infra/server/utils/typed_search_strategy.ts rename to x-pack/plugins/logs_shared/server/utils/typed_search_strategy.ts diff --git a/x-pack/plugins/logs_shared/tsconfig.json b/x-pack/plugins/logs_shared/tsconfig.json new file mode 100644 index 0000000000000..31c4466615974 --- /dev/null +++ b/x-pack/plugins/logs_shared/tsconfig.json @@ -0,0 +1,31 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types" + }, + "include": ["../../../typings/**/*", "common/**/*", "public/**/*", "server/**/*", "types/**/*"], + "exclude": ["target/**/*"], + "kbn_references": [ + "@kbn/core", + "@kbn/i18n", + "@kbn/i18n-react", + "@kbn/data-views-plugin", + "@kbn/io-ts-utils", + "@kbn/data-plugin", + "@kbn/kibana-utils-plugin", + "@kbn/es-query", + "@kbn/utility-types", + "@kbn/core-http-server", + "@kbn/logging", + "@kbn/config-schema", + "@kbn/std", + "@kbn/logging-mocks", + "@kbn/kibana-react-plugin", + "@kbn/test-subj-selector", + "@kbn/observability-shared-plugin", + "@kbn/observability-plugin", + "@kbn/datemath", + "@kbn/core-http-browser", + "@kbn/ui-actions-plugin", + ] +} diff --git a/x-pack/plugins/monitoring/kibana.jsonc b/x-pack/plugins/monitoring/kibana.jsonc index 236e6390d1bce..8da632c4b7d6f 100644 --- a/x-pack/plugins/monitoring/kibana.jsonc +++ b/x-pack/plugins/monitoring/kibana.jsonc @@ -19,6 +19,7 @@ ], "optionalPlugins": [ "infra", + "logsShared", "usageCollection", "home", "cloud", diff --git a/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts b/x-pack/plugins/monitoring/server/lib/logs/init_log_view.ts similarity index 74% rename from x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts rename to x-pack/plugins/monitoring/server/lib/logs/init_log_view.ts index 43fb8f7cc5dbd..52b0f43647386 100644 --- a/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts +++ b/x-pack/plugins/monitoring/server/lib/logs/init_log_view.ts @@ -5,20 +5,20 @@ * 2.0. */ -import { InfraPluginSetup } from '@kbn/infra-plugin/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import { CCS_REMOTE_PATTERN, INFRA_SOURCE_ID } from '../../../common/constants'; import { MonitoringConfig } from '../../config'; import { getIndexPatterns } from '../cluster/get_index_patterns'; -export const initInfraSource = (config: MonitoringConfig, infraPlugin: InfraPluginSetup) => { - if (infraPlugin) { +export const initLogView = (config: MonitoringConfig, logsShared: LogsSharedPluginSetup) => { + if (logsShared) { const logsIndexPattern = getIndexPatterns({ config, type: 'logs', ccs: CCS_REMOTE_PATTERN, }); - infraPlugin.logViews.defineInternalLogView(INFRA_SOURCE_ID, { + logsShared.logViews.defineInternalLogView(INFRA_SOURCE_ID, { name: 'Elastic Stack Logs', logIndices: { type: 'index_name', diff --git a/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts b/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts index b743e0300aef6..e7ffe701fbd1a 100644 --- a/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts +++ b/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts @@ -7,6 +7,7 @@ import { featuresPluginMock } from '@kbn/features-plugin/server/mocks'; import { infraPluginMock } from '@kbn/infra-plugin/server/mocks'; +import { logsSharedPluginMock } from '@kbn/logs-shared-plugin/server/mocks'; import { loggerMock } from '@kbn/logging-mocks'; import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/server/mocks'; import { configSchema, createConfig } from '../../../config'; @@ -38,6 +39,7 @@ const mockReq = ( usageCollection: usageCollectionSetup, features: featuresPluginMock.createSetup(), infra: infraPluginMock.createSetupContract(), + logsShared: logsSharedPluginMock.createSetupContract(), }, }, }, diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 5996eb125b6dc..1747855112964 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -35,7 +35,7 @@ import { configSchema, createConfig, MonitoringConfig } from './config'; import { instantiateClient } from './es_client/instantiate_client'; import { initBulkUploader } from './kibana_monitoring'; import { registerCollectors } from './kibana_monitoring/collectors'; -import { initInfraSource } from './lib/logs/init_infra_source'; +import { initLogView } from './lib/logs/init_log_view'; import { LicenseService } from './license_service'; import { requireUIRoutes } from './routes'; import { EndpointTypes, Globals } from './static_globals'; @@ -202,7 +202,7 @@ export class MonitoringPlugin alerting: plugins.alerting, logger: this.log, }); - initInfraSource(config, plugins.infra); + initLogView(config, plugins.logsShared); } } diff --git a/x-pack/plugins/monitoring/server/types.ts b/x-pack/plugins/monitoring/server/types.ts index 64931f5888514..7e056cbac5fb8 100644 --- a/x-pack/plugins/monitoring/server/types.ts +++ b/x-pack/plugins/monitoring/server/types.ts @@ -35,6 +35,7 @@ import { PluginSetupContract as FeaturesPluginSetupContract } from '@kbn/feature import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; import { RouteConfig, RouteMethod, Headers } from '@kbn/core/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import { ElasticsearchModifiedSource } from '../common/types/es'; import { RulesByType } from '../common/types/alerts'; import { configSchema, MonitoringConfig } from './config'; @@ -56,6 +57,7 @@ export interface PluginsSetup { alerting?: AlertingPluginSetupContract; infra: InfraPluginSetup; cloud?: CloudSetup; + logsShared: LogsSharedPluginSetup; } export type RequestHandlerContextMonitoringPlugin = CustomRequestHandlerContext<{ diff --git a/x-pack/plugins/monitoring/tsconfig.json b/x-pack/plugins/monitoring/tsconfig.json index 5ebd037e04648..00ca962568141 100644 --- a/x-pack/plugins/monitoring/tsconfig.json +++ b/x-pack/plugins/monitoring/tsconfig.json @@ -41,6 +41,7 @@ "@kbn/shared-ux-router", "@kbn/observability-shared-plugin", "@kbn/shared-ux-link-redirect-app", + "@kbn/logs-shared-plugin", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 1f9d308c783fb..29c1982ae0d3b 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -18117,7 +18117,6 @@ "xpack.infra.analysisSetup.indicesSelectionIndexNotFound": "Aucun index ne correspond au modèle {index}", "xpack.infra.analysisSetup.indicesSelectionNoTimestampField": "Il manque un champ {field} obligatoire dans au moins un index correspondant à {index}.", "xpack.infra.analysisSetup.indicesSelectionTimestampNotValid": "Au moins un index correspondant à {index} comprend un champ appelé {field} sans le type correct.", - "xpack.infra.dataSearch.shardFailureErrorMessage": "Index {indexName} : {errorMessage}", "xpack.infra.deprecations.containerAdjustIndexing": "Ajustez votre indexation pour identifier les conteneurs Docker utilisant \"{field}\"", "xpack.infra.deprecations.deprecatedFieldConfigDescription": "La configuration de \"xpack.infra.sources.default.fields.{fieldKey}\" a été déclassée et sera retirée dans la version 8.0.0.", "xpack.infra.deprecations.deprecatedFieldConfigTitle": "\"{fieldKey}\" est déclassé.", @@ -18138,8 +18137,6 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId} n'existe pas.", "xpack.infra.linkTo.hostWithIp.error": "Hôte avec l'adresse IP \"{hostIp}\" introuvable.", "xpack.infra.linkTo.hostWithIp.loading": "Chargement de l'hôte avec l'adresse IP \"{hostIp}\" en cours.", - "xpack.infra.logFlyout.flyoutSubTitle": "À partir de l'index {indexName}", - "xpack.infra.logFlyout.flyoutTitle": "Détails de l'entrée de log {logEntryId}", "xpack.infra.logs.alertDetails.chart.chartTitle": "Logs pour {criteria}", "xpack.infra.logs.alertFlyout.groupByOptimizationWarning": "Lors de la définition d'une valeur \"regrouper par\", nous recommandons fortement d'utiliser le comparateur \"{comparator}\" pour votre seuil. Cela peut permettre d'améliorer considérablement les performances.", "xpack.infra.logs.alerting.threshold.groupedCountAlertReasonDescription": "{actualCount, plural, one {la {actualCount} dernière entrée de log} many {les {actualCount} dernières entrées de log} other {les {actualCount} dernières entrées de log}} dans {duration} pour {groupName}. Alerte lorsque {comparator} {expectedCount}.", @@ -18157,22 +18154,11 @@ "xpack.infra.logs.analysis.mlUnavailableBody": "Pour en savoir plus, consultez {machineLearningAppLink}.", "xpack.infra.logs.common.invalidStateMessage": "Impossible de traiter l'état {stateValue}.", "xpack.infra.logs.customizeLogs.textSizeRadioGroup": "{textScale, select, small {Petite} medium {Moyenne} large {Large} other {{textScale}}}", - "xpack.infra.logs.extendTimeframeByDaysButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {jour} many {jours} other {jours}}", - "xpack.infra.logs.extendTimeframeByHoursButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {heure} many {heures} other {heures}}", - "xpack.infra.logs.extendTimeframeByMillisecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {milliseconde} many {millisecondes} other {millisecondes}}", - "xpack.infra.logs.extendTimeframeByMinutesButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {minute} many {minutes} other {minutes}}", - "xpack.infra.logs.extendTimeframeByMonthsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {mois} many {mois} other {mois}}", - "xpack.infra.logs.extendTimeframeBySecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {seconde} many {secondes} other {secondes}}", - "xpack.infra.logs.extendTimeframeByWeeksButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {semaine} many {semaines} other {semaines}}", - "xpack.infra.logs.extendTimeframeByYearsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {an} many {années} other {années}}", - "xpack.infra.logs.lastUpdate": "Dernière mise à jour {timestamp}", "xpack.infra.logs.logEntryCategories.manyCategoriesWarningReasonDescription": "Le rapport de catégories par document analysé est très élevé avec {categoriesDocumentRatio, number}.", "xpack.infra.logs.logEntryCategories.manyDeadCategoriesWarningReasonDescription": "Aucun nouveau message n'est attribué à {deadCategoriesRatio, number, percent} des catégories, car des catégories moins spécifiques les masquent.", "xpack.infra.logs.logEntryCategories.manyRareCategoriesWarningReasonDescription": "Les messages sont rarement attribués à {rareCategoriesRatio, number, percent} des catégories.", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, one {un autre segment} many {# autres segments} other {# autres segments}}", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, one {# entrée mise en surbrillance} many {# entrées mises en surbrillance} other {# entrées mises en surbrillance}}", - "xpack.infra.logs.showingEntriesFromTimestamp": "Affichage des entrées à partir de {timestamp}", - "xpack.infra.logs.showingEntriesUntilTimestamp": "Affichage des entrées jusqu'à {timestamp}", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "Les logs affichés proviennent du conteneur {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "Les logs affichés proviennent du fichier {file} et de l'hôte {host}", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "Le champ {messageField} doit être un champ textuel.", @@ -18283,9 +18269,6 @@ "xpack.infra.chartSection.notEnoughDataPointsToRenderTitle": "Données insuffisantes", "xpack.infra.common.tabBetaBadgeLabel": "Version bêta", "xpack.infra.configureSourceActionLabel": "Modifier la configuration de la source", - "xpack.infra.dataSearch.abortedRequestErrorMessage": "La demande a été annulée.", - "xpack.infra.dataSearch.cancelButtonLabel": "Annuler la demande", - "xpack.infra.dataSearch.loadingErrorRetryButtonLabel": "Réessayer", "xpack.infra.deprecations.containerIdFieldName": "ID de conteneur", "xpack.infra.deprecations.containerIdFieldTitle": "Le champ de configuration source \"ID de conteneur\" est déclassé.", "xpack.infra.deprecations.hostnameFieldName": "nom d'hôte", @@ -18439,18 +18422,7 @@ "xpack.infra.legendControls.stepsLabel": "Nombre de couleurs", "xpack.infra.legendControls.switchLabel": "Calculer automatiquement la plage", "xpack.infra.legnedControls.boundRangeError": "La valeur minimale doit être inférieure à la valeur maximale", - "xpack.infra.lobs.logEntryActionsViewInContextButton": "Afficher en contexte", "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "Afficher les actions de l'entrée du log", - "xpack.infra.logEntryActionsMenu.apmActionLabel": "Afficher dans APM", - "xpack.infra.logEntryActionsMenu.buttonLabel": "Examiner", - "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "Afficher le statut dans Uptime", - "xpack.infra.logEntryItemView.logEntryActionsMenuToolTip": "Afficher les actions de la ligne", - "xpack.infra.logFlyout.fieldColumnLabel": "Champ", - "xpack.infra.logFlyout.filterAriaLabel": "Filtre", - "xpack.infra.logFlyout.loadingErrorCalloutTitle": "Erreur lors de la recherche de l'entrée de log", - "xpack.infra.logFlyout.loadingMessage": "Recherche de l'entrée de log dans les partitions", - "xpack.infra.logFlyout.setFilterTooltip": "Afficher l'événement avec filtre", - "xpack.infra.logFlyout.valueColumnLabel": "Valeur", "xpack.infra.logs.alertDetails.chart.ratioTitle": "Ratio de Requête A à Requête B", "xpack.infra.logs.alertDetails.chartAnnotation.alertStarted": "Alerte démarrée", "xpack.infra.logs.alertDetails.chartHistory.alertsTriggered": "Alertes déclenchées", @@ -18569,9 +18541,6 @@ "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "Retour automatique à la ligne", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "Taille du texte", "xpack.infra.logs.customizeLogs.wrapLongLinesSwitchLabel": "Formater les longues lignes", - "xpack.infra.logs.emptyView.checkForNewDataButtonLabel": "Rechercher de nouvelles données", - "xpack.infra.logs.emptyView.noLogMessageDescription": "Essayez d'ajuster votre filtre.", - "xpack.infra.logs.emptyView.noLogMessageTitle": "Il n'y a aucun message de log à afficher.", "xpack.infra.logs.highlights.clearHighlightTermsButtonLabel": "Effacer les termes à mettre en surbrillance", "xpack.infra.logs.highlights.goToNextHighlightButtonLabel": "Passer au surlignage suivant", "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "Passer au surlignage précédent", @@ -18581,10 +18550,7 @@ "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "Catégories", "xpack.infra.logs.index.settingsTabTitle": "Paramètres", "xpack.infra.logs.index.streamTabTitle": "Flux", - "xpack.infra.logs.jumpToTailText": "Passer aux entrées les plus récentes", - "xpack.infra.logs.loadingNewEntriesText": "Chargement des nouvelles entrées", "xpack.infra.logs.logCategoriesTitle": "Catégories", - "xpack.infra.logs.logEntryActionsDetailsButton": "Afficher les détails", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "Analyse dans ML", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "Analysez cette catégorie dans l'application ML.", "xpack.infra.logs.logEntryCategories.categoryColumnTitle": "Catégorie", @@ -18615,7 +18581,6 @@ "xpack.infra.logs.noDataConfig.beatsCard.title": "Ajouter une intégration au logging", "xpack.infra.logs.noDataConfig.solutionName": "Observabilité", "xpack.infra.logs.pluginTitle": "Logs", - "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "Chargement des entrées", "xpack.infra.logs.search.nextButtonLabel": "Suivant", "xpack.infra.logs.search.previousButtonLabel": "Précédent", "xpack.infra.logs.search.searchInLogsAriaLabel": "rechercher", @@ -18625,10 +18590,6 @@ "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "Vue de log en ligne utilisée", "xpack.infra.logs.startStreamingButtonLabel": "Diffuser en direct", "xpack.infra.logs.stopStreamingButtonLabel": "Arrêter la diffusion", - "xpack.infra.logs.stream.messageColumnTitle": "Message", - "xpack.infra.logs.stream.timestampColumnTitle": "Horodatage", - "xpack.infra.logs.streamingNewEntriesText": "Diffusion de nouvelles entrées", - "xpack.infra.logs.streamLive": "Diffuser en direct", "xpack.infra.logs.streamPageTitle": "Flux", "xpack.infra.logsHeaderAddDataButtonLabel": "Ajouter des données", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "L'état d'au moins un champ du formulaire est non valide.", @@ -18655,8 +18616,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "Réessayer", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "Recherche d'entrées de log… (par ex. host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "Erreur de filtrage du log", - "xpack.infra.logStream.kqlErrorTitle": "Expression KQL non valide", - "xpack.infra.logStream.unknownErrorTitle": "Une erreur s'est produite", "xpack.infra.logStreamEmbeddable.description": "Ajoutez un tableau de logs de diffusion en direct.", "xpack.infra.logStreamEmbeddable.displayName": "Flux de log", "xpack.infra.logStreamEmbeddable.title": "Flux de log", @@ -19283,6 +19242,47 @@ "xpack.infra.waffle.unableToSelectMetricErrorTitle": "Impossible de sélectionner les options ou la valeur pour l'indicateur.", "xpack.infra.waffleTime.autoRefreshButtonLabel": "Actualisation automatique", "xpack.infra.waffleTime.stopRefreshingButtonLabel": "Arrêter l'actualisation", + "xpack.logsShared.dataSearch.shardFailureErrorMessage": "Index {indexName} : {errorMessage}", + "xpack.logsShared.logFlyout.flyoutSubTitle": "À partir de l'index {indexName}", + "xpack.logsShared.logFlyout.flyoutTitle": "Détails de l'entrée de log {logEntryId}", + "xpack.logsShared.logs.extendTimeframeByDaysButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {jour} many {jours} other {jours}}", + "xpack.logsShared.logs.extendTimeframeByHoursButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {heure} many {heures} other {heures}}", + "xpack.logsShared.logs.extendTimeframeByMillisecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {milliseconde} many {millisecondes} other {millisecondes}}", + "xpack.logsShared.logs.extendTimeframeByMinutesButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {minute} many {minutes} other {minutes}}", + "xpack.logsShared.logs.extendTimeframeByMonthsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {mois} many {mois} other {mois}}", + "xpack.logsShared.logs.extendTimeframeBySecondsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {seconde} many {secondes} other {secondes}}", + "xpack.logsShared.logs.extendTimeframeByWeeksButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {semaine} many {semaines} other {semaines}}", + "xpack.logsShared.logs.extendTimeframeByYearsButton": "Étendre le délai d'exécution de {amount, number} {amount, plural, one {an} many {années} other {années}}", + "xpack.logsShared.logs.lastUpdate": "Dernière mise à jour {timestamp}", + "xpack.logsShared.logs.showingEntriesFromTimestamp": "Affichage des entrées à partir de {timestamp}", + "xpack.logsShared.logs.showingEntriesUntilTimestamp": "Affichage des entrées jusqu'à {timestamp}", + "xpack.logsShared.dataSearch.abortedRequestErrorMessage": "La demande a été annulée.", + "xpack.logsShared.dataSearch.cancelButtonLabel": "Annuler la demande", + "xpack.logsShared.dataSearch.loadingErrorRetryButtonLabel": "Réessayer", + "xpack.logsShared.lobs.logEntryActionsViewInContextButton": "Afficher en contexte", + "xpack.logsShared.logEntryActionsMenu.apmActionLabel": "Afficher dans APM", + "xpack.logsShared.logEntryActionsMenu.buttonLabel": "Examiner", + "xpack.logsShared.logEntryActionsMenu.uptimeActionLabel": "Afficher le statut dans Uptime", + "xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip": "Afficher les actions de la ligne", + "xpack.logsShared.logFlyout.fieldColumnLabel": "Champ", + "xpack.logsShared.logFlyout.filterAriaLabel": "Filtre", + "xpack.logsShared.logFlyout.loadingErrorCalloutTitle": "Erreur lors de la recherche de l'entrée de log", + "xpack.logsShared.logFlyout.loadingMessage": "Recherche de l'entrée de log dans les partitions", + "xpack.logsShared.logFlyout.setFilterTooltip": "Afficher l'événement avec filtre", + "xpack.logsShared.logFlyout.valueColumnLabel": "Valeur", + "xpack.logsShared.logs.emptyView.checkForNewDataButtonLabel": "Rechercher de nouvelles données", + "xpack.logsShared.logs.emptyView.noLogMessageDescription": "Essayez d'ajuster votre filtre.", + "xpack.logsShared.logs.emptyView.noLogMessageTitle": "Il n'y a aucun message de log à afficher.", + "xpack.logsShared.logs.jumpToTailText": "Passer aux entrées les plus récentes", + "xpack.logsShared.logs.loadingNewEntriesText": "Chargement des nouvelles entrées", + "xpack.logsShared.logs.logEntryActionsDetailsButton": "Afficher les détails", + "xpack.logsShared.logs.scrollableLogTextStreamView.loadingEntriesLabel": "Chargement des entrées", + "xpack.logsShared.logs.stream.messageColumnTitle": "Message", + "xpack.logsShared.logs.stream.timestampColumnTitle": "Horodatage", + "xpack.logsShared.logs.streamingNewEntriesText": "Diffusion de nouvelles entrées", + "xpack.logsShared.logs.streamLive": "Diffuser en direct", + "xpack.logsShared.logStream.kqlErrorTitle": "Expression KQL non valide", + "xpack.logsShared.logStream.unknownErrorTitle": "Une erreur s'est produite", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "Pour utiliser l'option Ingérer des pipelines, vous devez avoir {privilegesCount, plural, one {ce privilège de cluster} many {ces privilèges de cluster} other {ces privilèges de cluster}} : {missingPrivileges}.", "xpack.ingestPipelines.clone.loadSourcePipelineErrorTitle": "Impossible de charger {name}.", "xpack.ingestPipelines.createFromCsv.errorMessage": "{message}", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 602616c9ffacc..2b610e8af95c6 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -18116,7 +18116,6 @@ "xpack.infra.analysisSetup.indicesSelectionIndexNotFound": "インデックスがパターン{index}と一致しません", "xpack.infra.analysisSetup.indicesSelectionNoTimestampField": "{index}と一致する1つ以上のインデックスに、必須フィールド{field}がありません。", "xpack.infra.analysisSetup.indicesSelectionTimestampNotValid": "{index}と一致する1つ以上のインデックスに、正しい型がない{field}フィールドがあります。", - "xpack.infra.dataSearch.shardFailureErrorMessage": "インデックス{indexName}:{errorMessage}", "xpack.infra.deprecations.containerAdjustIndexing": "インデックスを調整し、\"{field}\"を使用してDockerコンテナーを特定", "xpack.infra.deprecations.deprecatedFieldConfigDescription": "「xpack.infra.sources.default.fields.{fieldKey}」の構成は廃止予定であり、8.0.0で削除されます。", "xpack.infra.deprecations.deprecatedFieldConfigTitle": "\"{fieldKey}\"は廃止予定です。", @@ -18137,8 +18136,6 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId}は存在しません。", "xpack.infra.linkTo.hostWithIp.error": "IPアドレス「{hostIp}」でホストが見つかりません。", "xpack.infra.linkTo.hostWithIp.loading": "IPアドレス「{hostIp}」のホストを読み込み中です。", - "xpack.infra.logFlyout.flyoutSubTitle": "インデックス{indexName}から", - "xpack.infra.logFlyout.flyoutTitle": "ログエントリ{logEntryId}の詳細", "xpack.infra.logs.alertDetails.chart.chartTitle": "{criteria} のログ", "xpack.infra.logs.alertFlyout.groupByOptimizationWarning": "「group by」を設定するときには、しきい値で\"{comparator}\"比較演算子を使用することを強くお勧めします。これにより、パフォーマンスを大きく改善できます。", "xpack.infra.logs.alerting.threshold.groupedCountAlertReasonDescription": "{groupName}の過去{duration}の{actualCount, plural, other {{actualCount}件のログエントリ}}。{comparator} {expectedCount}のときにアラートを通知します。", @@ -18156,22 +18153,11 @@ "xpack.infra.logs.analysis.mlUnavailableBody": "詳細は {machineLearningAppLink} をご覧ください。", "xpack.infra.logs.common.invalidStateMessage": "状態{stateValue}を処理できません。", "xpack.infra.logs.customizeLogs.textSizeRadioGroup": "{textScale, select, small {小} medium {中} large {大} other {{textScale}}}", - "xpack.infra.logs.extendTimeframeByDaysButton": "タイムフレームを{amount, number}{amount, plural, other {日}}延長", - "xpack.infra.logs.extendTimeframeByHoursButton": "タイムフレームを{amount, number}{amount, plural, other {時間}}延長", - "xpack.infra.logs.extendTimeframeByMillisecondsButton": "タイムフレームを{amount, number}{amount, plural, other {ミリ秒}}延長", - "xpack.infra.logs.extendTimeframeByMinutesButton": "タイムフレームを{amount, number}{amount, plural, other {分}}延長", - "xpack.infra.logs.extendTimeframeByMonthsButton": "タイムフレームを{amount, number}{amount, plural, other {月}}延長", - "xpack.infra.logs.extendTimeframeBySecondsButton": "タイムフレームを{amount, number}{amount, plural, other {秒}}延長", - "xpack.infra.logs.extendTimeframeByWeeksButton": "タイムフレームを{amount, number}{amount, plural, other {週}}延長", - "xpack.infra.logs.extendTimeframeByYearsButton": "タイムフレームを{amount, number}{amount, plural, other {年}}延長", - "xpack.infra.logs.lastUpdate": "最終更新:{timestamp}", "xpack.infra.logs.logEntryCategories.manyCategoriesWarningReasonDescription": "分析されたドキュメントごとのカテゴリ比率が{categoriesDocumentRatio, number}で、非常に高い値です。", "xpack.infra.logs.logEntryCategories.manyDeadCategoriesWarningReasonDescription": "特定のカテゴリが少ないことで、目立たなくなるため、{deadCategoriesRatio, number, percent}のカテゴリには新しいメッセージが割り当てられません。", "xpack.infra.logs.logEntryCategories.manyRareCategoriesWarningReasonDescription": "{rareCategoriesRatio, number, percent}のカテゴリには、ほとんどメッセージが割り当てられません。", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, other {#個の追加のセグメント}}", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, other {#個のハイライトされたエントリ}}", - "xpack.infra.logs.showingEntriesFromTimestamp": "{timestamp}以降のエントリーを表示中", - "xpack.infra.logs.showingEntriesUntilTimestamp": "{timestamp}までのエントリーを表示中", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "表示されたログはコンテナー{container}から取得されました", "xpack.infra.logs.viewInContext.logsFromFileTitle": "表示されたログは、ファイル{file}およびホスト{host}から取得されました", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "{messageField}フィールドはテキストフィールドでなければなりません。", @@ -18282,9 +18268,6 @@ "xpack.infra.chartSection.notEnoughDataPointsToRenderTitle": "データが不十分です", "xpack.infra.common.tabBetaBadgeLabel": "ベータ", "xpack.infra.configureSourceActionLabel": "ソース構成を変更", - "xpack.infra.dataSearch.abortedRequestErrorMessage": "リクエストが中断されましたか。", - "xpack.infra.dataSearch.cancelButtonLabel": "リクエストのキャンセル", - "xpack.infra.dataSearch.loadingErrorRetryButtonLabel": "再試行", "xpack.infra.deprecations.containerIdFieldName": "コンテナーID", "xpack.infra.deprecations.containerIdFieldTitle": "ソース構成フィールド[コンテナーID]は廃止予定です。", "xpack.infra.deprecations.hostnameFieldName": "ホスト名", @@ -18438,18 +18421,7 @@ "xpack.infra.legendControls.stepsLabel": "色の数", "xpack.infra.legendControls.switchLabel": "自動計算範囲", "xpack.infra.legnedControls.boundRangeError": "最小値は最大値よりも小さくなければなりません", - "xpack.infra.lobs.logEntryActionsViewInContextButton": "コンテキストで表示", "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "ログエントリのアクションを表示", - "xpack.infra.logEntryActionsMenu.apmActionLabel": "APMで表示", - "xpack.infra.logEntryActionsMenu.buttonLabel": "調査", - "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "監視ステータスを表示", - "xpack.infra.logEntryItemView.logEntryActionsMenuToolTip": "行のアクションを表示", - "xpack.infra.logFlyout.fieldColumnLabel": "フィールド", - "xpack.infra.logFlyout.filterAriaLabel": "フィルター", - "xpack.infra.logFlyout.loadingErrorCalloutTitle": "ログエントリの検索中のエラー", - "xpack.infra.logFlyout.loadingMessage": "シャードのログエントリを検索しています", - "xpack.infra.logFlyout.setFilterTooltip": "フィルターでイベントを表示", - "xpack.infra.logFlyout.valueColumnLabel": "値", "xpack.infra.logs.alertDetails.chart.ratioTitle": "クエリAとクエリBの比率", "xpack.infra.logs.alertDetails.chartAnnotation.alertStarted": "アラートが開始しました", "xpack.infra.logs.alertDetails.chartHistory.alertsTriggered": "アラートがトリガーされました", @@ -18568,9 +18540,6 @@ "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "改行", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "テキストサイズ", "xpack.infra.logs.customizeLogs.wrapLongLinesSwitchLabel": "長い行を改行", - "xpack.infra.logs.emptyView.checkForNewDataButtonLabel": "新規データを確認", - "xpack.infra.logs.emptyView.noLogMessageDescription": "フィルターを調整してみてください。", - "xpack.infra.logs.emptyView.noLogMessageTitle": "表示するログメッセージがありません。", "xpack.infra.logs.highlights.clearHighlightTermsButtonLabel": "ハイライトする用語をクリア", "xpack.infra.logs.highlights.goToNextHighlightButtonLabel": "次のハイライトにスキップ", "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "前のハイライトにスキップ", @@ -18580,10 +18549,7 @@ "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "カテゴリー", "xpack.infra.logs.index.settingsTabTitle": "設定", "xpack.infra.logs.index.streamTabTitle": "ストリーム", - "xpack.infra.logs.jumpToTailText": "最も新しいエントリーに移動", - "xpack.infra.logs.loadingNewEntriesText": "新しいエントリーを読み込み中", "xpack.infra.logs.logCategoriesTitle": "カテゴリー", - "xpack.infra.logs.logEntryActionsDetailsButton": "詳細を表示", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "ML で分析", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "ML アプリでこのカテゴリーを分析します。", "xpack.infra.logs.logEntryCategories.categoryColumnTitle": "カテゴリー", @@ -18614,7 +18580,6 @@ "xpack.infra.logs.noDataConfig.beatsCard.title": "ロギング統合を追加", "xpack.infra.logs.noDataConfig.solutionName": "Observability", "xpack.infra.logs.pluginTitle": "ログ", - "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "エントリーを読み込み中", "xpack.infra.logs.search.nextButtonLabel": "次へ", "xpack.infra.logs.search.previousButtonLabel": "前へ", "xpack.infra.logs.search.searchInLogsAriaLabel": "検索", @@ -18624,10 +18589,6 @@ "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "使用中のインラインログビュー", "xpack.infra.logs.startStreamingButtonLabel": "ライブストリーム", "xpack.infra.logs.stopStreamingButtonLabel": "ストリーム停止", - "xpack.infra.logs.stream.messageColumnTitle": "メッセージ", - "xpack.infra.logs.stream.timestampColumnTitle": "タイムスタンプ", - "xpack.infra.logs.streamingNewEntriesText": "新しいエントリーをストリーム中", - "xpack.infra.logs.streamLive": "ライブストリーム", "xpack.infra.logs.streamPageTitle": "ストリーム", "xpack.infra.logsHeaderAddDataButtonLabel": "データの追加", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "1つ以上のフォームフィールドが無効な状態です。", @@ -18654,8 +18615,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "再試行", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "ログエントリーを検索中…(例:host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "ログフィルターエラー", - "xpack.infra.logStream.kqlErrorTitle": "無効なKQL式", - "xpack.infra.logStream.unknownErrorTitle": "エラーが発生しました", "xpack.infra.logStreamEmbeddable.description": "ライブストリーミングログのテーブルを追加します。", "xpack.infra.logStreamEmbeddable.displayName": "ログストリーム", "xpack.infra.logStreamEmbeddable.title": "ログストリーム", @@ -19282,6 +19241,47 @@ "xpack.infra.waffle.unableToSelectMetricErrorTitle": "メトリックのオプションまたは値を選択できません。", "xpack.infra.waffleTime.autoRefreshButtonLabel": "自動更新", "xpack.infra.waffleTime.stopRefreshingButtonLabel": "更新中止", + "xpack.logsShared.dataSearch.shardFailureErrorMessage": "インデックス{indexName}:{errorMessage}", + "xpack.logsShared.logFlyout.flyoutSubTitle": "インデックス{indexName}から", + "xpack.logsShared.logFlyout.flyoutTitle": "ログエントリ{logEntryId}の詳細", + "xpack.logsShared.logs.extendTimeframeByDaysButton": "タイムフレームを{amount, number}{amount, plural, other {日}}延長", + "xpack.logsShared.logs.extendTimeframeByHoursButton": "タイムフレームを{amount, number}{amount, plural, other {時間}}延長", + "xpack.logsShared.logs.extendTimeframeByMillisecondsButton": "タイムフレームを{amount, number}{amount, plural, other {ミリ秒}}延長", + "xpack.logsShared.logs.extendTimeframeByMinutesButton": "タイムフレームを{amount, number}{amount, plural, other {分}}延長", + "xpack.logsShared.logs.extendTimeframeByMonthsButton": "タイムフレームを{amount, number}{amount, plural, other {月}}延長", + "xpack.logsShared.logs.extendTimeframeBySecondsButton": "タイムフレームを{amount, number}{amount, plural, other {秒}}延長", + "xpack.logsShared.logs.extendTimeframeByWeeksButton": "タイムフレームを{amount, number}{amount, plural, other {週}}延長", + "xpack.logsShared.logs.extendTimeframeByYearsButton": "タイムフレームを{amount, number}{amount, plural, other {年}}延長", + "xpack.logsShared.logs.lastUpdate": "最終更新:{timestamp}", + "xpack.logsShared.logs.showingEntriesFromTimestamp": "{timestamp}以降のエントリーを表示中", + "xpack.logsShared.logs.showingEntriesUntilTimestamp": "{timestamp}までのエントリーを表示中", + "xpack.logsShared.dataSearch.abortedRequestErrorMessage": "リクエストが中断されましたか。", + "xpack.logsShared.dataSearch.cancelButtonLabel": "リクエストのキャンセル", + "xpack.logsShared.dataSearch.loadingErrorRetryButtonLabel": "再試行", + "xpack.logsShared.lobs.logEntryActionsViewInContextButton": "コンテキストで表示", + "xpack.logsShared.logEntryActionsMenu.apmActionLabel": "APMで表示", + "xpack.logsShared.logEntryActionsMenu.buttonLabel": "調査", + "xpack.logsShared.logEntryActionsMenu.uptimeActionLabel": "監視ステータスを表示", + "xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip": "行のアクションを表示", + "xpack.logsShared.logFlyout.fieldColumnLabel": "フィールド", + "xpack.logsShared.logFlyout.filterAriaLabel": "フィルター", + "xpack.logsShared.logFlyout.loadingErrorCalloutTitle": "ログエントリの検索中のエラー", + "xpack.logsShared.logFlyout.loadingMessage": "シャードのログエントリを検索しています", + "xpack.logsShared.logFlyout.setFilterTooltip": "フィルターでイベントを表示", + "xpack.logsShared.logFlyout.valueColumnLabel": "値", + "xpack.logsShared.logs.emptyView.checkForNewDataButtonLabel": "新規データを確認", + "xpack.logsShared.logs.emptyView.noLogMessageDescription": "フィルターを調整してみてください。", + "xpack.logsShared.logs.emptyView.noLogMessageTitle": "表示するログメッセージがありません。", + "xpack.logsShared.logs.jumpToTailText": "最も新しいエントリーに移動", + "xpack.logsShared.logs.loadingNewEntriesText": "新しいエントリーを読み込み中", + "xpack.logsShared.logs.logEntryActionsDetailsButton": "詳細を表示", + "xpack.logsShared.logs.scrollableLogTextStreamView.loadingEntriesLabel": "エントリーを読み込み中", + "xpack.logsShared.logs.stream.messageColumnTitle": "メッセージ", + "xpack.logsShared.logs.stream.timestampColumnTitle": "タイムスタンプ", + "xpack.logsShared.logs.streamingNewEntriesText": "新しいエントリーをストリーム中", + "xpack.logsShared.logs.streamLive": "ライブストリーム", + "xpack.logsShared.logStream.kqlErrorTitle": "無効なKQL式", + "xpack.logsShared.logStream.unknownErrorTitle": "エラーが発生しました", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "インジェストパイプラインを使用するには、{privilegesCount, plural, other {これらのクラスター権限}}が必要です:{missingPrivileges}。", "xpack.ingestPipelines.clone.loadSourcePipelineErrorTitle": "{name}を読み込めません。", "xpack.ingestPipelines.createFromCsv.errorMessage": "{message}", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 9c38c99996e8f..90059adb4de1f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -18116,7 +18116,6 @@ "xpack.infra.analysisSetup.indicesSelectionIndexNotFound": "没有索引匹配模式 {index}", "xpack.infra.analysisSetup.indicesSelectionNoTimestampField": "匹配 {index} 的索引至少有一个缺少必需字段 {field}。", "xpack.infra.analysisSetup.indicesSelectionTimestampNotValid": "匹配 {index} 的索引至少有一个具有称作 {field} 且类型不正确的字段。", - "xpack.infra.dataSearch.shardFailureErrorMessage": "索引 {indexName}:{errorMessage}", "xpack.infra.deprecations.containerAdjustIndexing": "调整索引以使用“{field}”标识 Docker 容器", "xpack.infra.deprecations.deprecatedFieldConfigDescription": "配置“xpack.infra.sources.default.fields.{fieldKey}”已过时,将在 8.0.0 中移除。", "xpack.infra.deprecations.deprecatedFieldConfigTitle": "“{fieldKey}”已过时。", @@ -18137,8 +18136,6 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId} 不存在。", "xpack.infra.linkTo.hostWithIp.error": "未找到 IP 地址为“{hostIp}”的主机。", "xpack.infra.linkTo.hostWithIp.loading": "正在加载 IP 地址为“{hostIp}”的主机。", - "xpack.infra.logFlyout.flyoutSubTitle": "从索引 {indexName}", - "xpack.infra.logFlyout.flyoutTitle": "日志条目 {logEntryId} 的详细信息", "xpack.infra.logs.alertDetails.chart.chartTitle": "{criteria} 的日志", "xpack.infra.logs.alertFlyout.groupByOptimizationWarning": "设置“分组依据”时,强烈建议将“{comparator}”比较符用于阈值。这会使性能有较大提升。", "xpack.infra.logs.alerting.threshold.groupedCountAlertReasonDescription": "对于 {groupName},过去 {duration}中有 {actualCount, plural, other {{actualCount} 个日志条目}}。{comparator} {expectedCount} 时告警。", @@ -18156,22 +18153,11 @@ "xpack.infra.logs.analysis.mlUnavailableBody": "查看 {machineLearningAppLink}以了解更多信息。", "xpack.infra.logs.common.invalidStateMessage": "无法处理状态 {stateValue}。", "xpack.infra.logs.customizeLogs.textSizeRadioGroup": "{textScale, select, small {小} medium {中} large {大} other {{textScale}}}", - "xpack.infra.logs.extendTimeframeByDaysButton": "将时间范围延伸 {amount, number} {amount, plural, other {天}}", - "xpack.infra.logs.extendTimeframeByHoursButton": "将时间范围延伸 {amount, number} {amount, plural, other {小时}}", - "xpack.infra.logs.extendTimeframeByMillisecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {毫秒}}", - "xpack.infra.logs.extendTimeframeByMinutesButton": "将时间范围延伸 {amount, number} {amount, plural, other {分钟}}", - "xpack.infra.logs.extendTimeframeByMonthsButton": "将时间范围延伸 {amount, number} 个{amount, plural, other {月}}", - "xpack.infra.logs.extendTimeframeBySecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {秒}}", - "xpack.infra.logs.extendTimeframeByWeeksButton": "将时间范围延伸 {amount, number} {amount, plural, other {周}}", - "xpack.infra.logs.extendTimeframeByYearsButton": "将时间范围延伸 {amount, number} {amount, plural, other {年}}", - "xpack.infra.logs.lastUpdate": "上次更新时间 {timestamp}", "xpack.infra.logs.logEntryCategories.manyCategoriesWarningReasonDescription": "每个分析文档的类别比率非常高,达到 {categoriesDocumentRatio, number}。", "xpack.infra.logs.logEntryCategories.manyDeadCategoriesWarningReasonDescription": "不会为 {deadCategoriesRatio, number, percent} 的类别分配新消息,因为较为笼统的类别遮蔽了它们。", "xpack.infra.logs.logEntryCategories.manyRareCategoriesWarningReasonDescription": "仅很少的时候为 {rareCategoriesRatio, number, percent} 的类别分配消息。", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, other {另 # 个分段}}", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, other {# 个高亮条目}}", - "xpack.infra.logs.showingEntriesFromTimestamp": "正在显示自 {timestamp} 起的条目", - "xpack.infra.logs.showingEntriesUntilTimestamp": "正在显示截止于 {timestamp} 的条目", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "显示的日志来自容器 {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "显示的日志来自文件 {file} 和主机 {host}", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "{messageField} 字段必须是文本字段。", @@ -18282,9 +18268,6 @@ "xpack.infra.chartSection.notEnoughDataPointsToRenderTitle": "没有足够的数据", "xpack.infra.common.tabBetaBadgeLabel": "公测版", "xpack.infra.configureSourceActionLabel": "更改源配置", - "xpack.infra.dataSearch.abortedRequestErrorMessage": "请求已中止。", - "xpack.infra.dataSearch.cancelButtonLabel": "取消请求", - "xpack.infra.dataSearch.loadingErrorRetryButtonLabel": "重试", "xpack.infra.deprecations.containerIdFieldName": "容器 ID", "xpack.infra.deprecations.containerIdFieldTitle": "源配置字段“容器 ID”已过时。", "xpack.infra.deprecations.hostnameFieldName": "主机名", @@ -18438,18 +18421,7 @@ "xpack.infra.legendControls.stepsLabel": "颜色个数", "xpack.infra.legendControls.switchLabel": "自动计算范围", "xpack.infra.legnedControls.boundRangeError": "最小值必须小于最大值", - "xpack.infra.lobs.logEntryActionsViewInContextButton": "在上下文中查看", "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "查看日志条目的操作", - "xpack.infra.logEntryActionsMenu.apmActionLabel": "在 APM 中查看", - "xpack.infra.logEntryActionsMenu.buttonLabel": "调查", - "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "在Uptime 中查看状态", - "xpack.infra.logEntryItemView.logEntryActionsMenuToolTip": "查看适用于以下行的操作:", - "xpack.infra.logFlyout.fieldColumnLabel": "字段", - "xpack.infra.logFlyout.filterAriaLabel": "筛选", - "xpack.infra.logFlyout.loadingErrorCalloutTitle": "搜索日志条目时出错", - "xpack.infra.logFlyout.loadingMessage": "正在分片中搜索日志条目", - "xpack.infra.logFlyout.setFilterTooltip": "使用筛选查看事件", - "xpack.infra.logFlyout.valueColumnLabel": "值", "xpack.infra.logs.alertDetails.chart.ratioTitle": "查询 A 到查询 B 的比率", "xpack.infra.logs.alertDetails.chartAnnotation.alertStarted": "已启动告警", "xpack.infra.logs.alertDetails.chartHistory.alertsTriggered": "已触发告警", @@ -18568,9 +18540,6 @@ "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "换行", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "文本大小", "xpack.infra.logs.customizeLogs.wrapLongLinesSwitchLabel": "长行换行", - "xpack.infra.logs.emptyView.checkForNewDataButtonLabel": "检查新数据", - "xpack.infra.logs.emptyView.noLogMessageDescription": "尝试调整您的筛选。", - "xpack.infra.logs.emptyView.noLogMessageTitle": "没有可显示的日志消息。", "xpack.infra.logs.highlights.clearHighlightTermsButtonLabel": "清除要突出显示的词", "xpack.infra.logs.highlights.goToNextHighlightButtonLabel": "跳转到下一高亮条目", "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "跳转到上一高亮条目", @@ -18580,10 +18549,7 @@ "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "类别", "xpack.infra.logs.index.settingsTabTitle": "设置", "xpack.infra.logs.index.streamTabTitle": "流式传输", - "xpack.infra.logs.jumpToTailText": "跳到最近的条目", - "xpack.infra.logs.loadingNewEntriesText": "正在加载新条目", "xpack.infra.logs.logCategoriesTitle": "类别", - "xpack.infra.logs.logEntryActionsDetailsButton": "查看详情", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "在 ML 中分析", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "在 ML 应用中分析此类别。", "xpack.infra.logs.logEntryCategories.categoryColumnTitle": "类别", @@ -18614,7 +18580,6 @@ "xpack.infra.logs.noDataConfig.beatsCard.title": "添加日志记录集成", "xpack.infra.logs.noDataConfig.solutionName": "Observability", "xpack.infra.logs.pluginTitle": "日志", - "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "正在加载条目", "xpack.infra.logs.search.nextButtonLabel": "下一页", "xpack.infra.logs.search.previousButtonLabel": "上一页", "xpack.infra.logs.search.searchInLogsAriaLabel": "搜索", @@ -18624,10 +18589,6 @@ "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "正使用内联日志视图", "xpack.infra.logs.startStreamingButtonLabel": "实时流式传输", "xpack.infra.logs.stopStreamingButtonLabel": "停止流式传输", - "xpack.infra.logs.stream.messageColumnTitle": "消息", - "xpack.infra.logs.stream.timestampColumnTitle": "时间戳", - "xpack.infra.logs.streamingNewEntriesText": "正在流式传输新条目", - "xpack.infra.logs.streamLive": "实时流式传输", "xpack.infra.logs.streamPageTitle": "流式传输", "xpack.infra.logsHeaderAddDataButtonLabel": "添加数据", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "至少一个表单字段处于无效状态。", @@ -18654,8 +18615,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "重试", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "搜索日志条目……(例如 host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "日志筛选错误", - "xpack.infra.logStream.kqlErrorTitle": "KQL 表达式无效", - "xpack.infra.logStream.unknownErrorTitle": "发生错误", "xpack.infra.logStreamEmbeddable.description": "添加实时流式传输日志的表。", "xpack.infra.logStreamEmbeddable.displayName": "日志流", "xpack.infra.logStreamEmbeddable.title": "日志流", @@ -19282,6 +19241,47 @@ "xpack.infra.waffle.unableToSelectMetricErrorTitle": "无法选择指标选项或指标值。", "xpack.infra.waffleTime.autoRefreshButtonLabel": "自动刷新", "xpack.infra.waffleTime.stopRefreshingButtonLabel": "停止刷新", + "xpack.logsShared.dataSearch.shardFailureErrorMessage": "索引 {indexName}:{errorMessage}", + "xpack.logsShared.logFlyout.flyoutSubTitle": "从索引 {indexName}", + "xpack.logsShared.logFlyout.flyoutTitle": "日志条目 {logEntryId} 的详细信息", + "xpack.logsShared.logs.extendTimeframeByDaysButton": "将时间范围延伸 {amount, number} {amount, plural, other {天}}", + "xpack.logsShared.logs.extendTimeframeByHoursButton": "将时间范围延伸 {amount, number} {amount, plural, other {小时}}", + "xpack.logsShared.logs.extendTimeframeByMillisecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {毫秒}}", + "xpack.logsShared.logs.extendTimeframeByMinutesButton": "将时间范围延伸 {amount, number} {amount, plural, other {分钟}}", + "xpack.logsShared.logs.extendTimeframeByMonthsButton": "将时间范围延伸 {amount, number} 个{amount, plural, other {月}}", + "xpack.logsShared.logs.extendTimeframeBySecondsButton": "将时间范围延伸 {amount, number} {amount, plural, other {秒}}", + "xpack.logsShared.logs.extendTimeframeByWeeksButton": "将时间范围延伸 {amount, number} {amount, plural, other {周}}", + "xpack.logsShared.logs.extendTimeframeByYearsButton": "将时间范围延伸 {amount, number} {amount, plural, other {年}}", + "xpack.logsShared.logs.lastUpdate": "上次更新时间 {timestamp}", + "xpack.logsShared.logs.showingEntriesFromTimestamp": "正在显示自 {timestamp} 起的条目", + "xpack.logsShared.logs.showingEntriesUntilTimestamp": "正在显示截止于 {timestamp} 的条目", + "xpack.logsShared.dataSearch.abortedRequestErrorMessage": "请求已中止。", + "xpack.logsShared.dataSearch.cancelButtonLabel": "取消请求", + "xpack.logsShared.dataSearch.loadingErrorRetryButtonLabel": "重试", + "xpack.logsShared.lobs.logEntryActionsViewInContextButton": "在上下文中查看", + "xpack.logsShared.logEntryActionsMenu.apmActionLabel": "在 APM 中查看", + "xpack.logsShared.logEntryActionsMenu.buttonLabel": "调查", + "xpack.logsShared.logEntryActionsMenu.uptimeActionLabel": "在Uptime 中查看状态", + "xpack.logsShared.logEntryItemView.logEntryActionsMenuToolTip": "查看适用于以下行的操作:", + "xpack.logsShared.logFlyout.fieldColumnLabel": "字段", + "xpack.logsShared.logFlyout.filterAriaLabel": "筛选", + "xpack.logsShared.logFlyout.loadingErrorCalloutTitle": "搜索日志条目时出错", + "xpack.logsShared.logFlyout.loadingMessage": "正在分片中搜索日志条目", + "xpack.logsShared.logFlyout.setFilterTooltip": "使用筛选查看事件", + "xpack.logsShared.logFlyout.valueColumnLabel": "值", + "xpack.logsShared.logs.emptyView.checkForNewDataButtonLabel": "检查新数据", + "xpack.logsShared.logs.emptyView.noLogMessageDescription": "尝试调整您的筛选。", + "xpack.logsShared.logs.emptyView.noLogMessageTitle": "没有可显示的日志消息。", + "xpack.logsShared.logs.jumpToTailText": "跳到最近的条目", + "xpack.logsShared.logs.loadingNewEntriesText": "正在加载新条目", + "xpack.logsShared.logs.logEntryActionsDetailsButton": "查看详情", + "xpack.logsShared.logs.scrollableLogTextStreamView.loadingEntriesLabel": "正在加载条目", + "xpack.logsShared.logs.stream.messageColumnTitle": "消息", + "xpack.logsShared.logs.stream.timestampColumnTitle": "时间戳", + "xpack.logsShared.logs.streamingNewEntriesText": "正在流式传输新条目", + "xpack.logsShared.logs.streamLive": "实时流式传输", + "xpack.logsShared.logStream.kqlErrorTitle": "KQL 表达式无效", + "xpack.logsShared.logStream.unknownErrorTitle": "发生错误", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "要使用采集管道,您必须具有{privilegesCount, plural, other {以下集群权限}}:{missingPrivileges}。", "xpack.ingestPipelines.clone.loadSourcePipelineErrorTitle": "无法加载 {name}。", "xpack.ingestPipelines.createFromCsv.errorMessage": "{message}", diff --git a/x-pack/plugins/upgrade_assistant/kibana.jsonc b/x-pack/plugins/upgrade_assistant/kibana.jsonc index 3f04775f4ca10..ff3584ef714bf 100644 --- a/x-pack/plugins/upgrade_assistant/kibana.jsonc +++ b/x-pack/plugins/upgrade_assistant/kibana.jsonc @@ -21,7 +21,8 @@ "usageCollection", "cloud", "security", - "infra" + "infra", + "logsShared" ], "requiredBundles": [ "esUiShared", diff --git a/x-pack/plugins/upgrade_assistant/server/plugin.ts b/x-pack/plugins/upgrade_assistant/server/plugin.ts index f77a5eabe1bda..6dfb65be85d7b 100644 --- a/x-pack/plugins/upgrade_assistant/server/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/server/plugin.ts @@ -16,7 +16,7 @@ import { SavedObjectsServiceStart, } from '@kbn/core/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; -import { InfraPluginSetup } from '@kbn/infra-plugin/server'; +import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; @@ -43,7 +43,7 @@ interface PluginsSetup { usageCollection: UsageCollectionSetup; licensing: LicensingPluginSetup; features: FeaturesPluginSetup; - infra: InfraPluginSetup; + logsShared: LogsSharedPluginSetup; security?: SecurityPluginSetup; } @@ -83,7 +83,7 @@ export class UpgradeAssistantServerPlugin implements Plugin { setup( { http, getStartServices, savedObjects }: CoreSetup, - { usageCollection, features, licensing, infra, security }: PluginsSetup + { usageCollection, features, licensing, logsShared, security }: PluginsSetup ) { this.licensing = licensing; @@ -105,7 +105,7 @@ export class UpgradeAssistantServerPlugin implements Plugin { // We need to initialize the deprecation logs plugin so that we can // navigate from this app to the observability app using a source_id. - infra?.logViews.defineInternalLogView(DEPRECATION_LOGS_SOURCE_ID, { + logsShared?.logViews.defineInternalLogView(DEPRECATION_LOGS_SOURCE_ID, { name: 'deprecationLogs', description: 'deprecation logs', logIndices: { diff --git a/x-pack/plugins/upgrade_assistant/tsconfig.json b/x-pack/plugins/upgrade_assistant/tsconfig.json index c9d8201c1607a..59d562c03c87d 100644 --- a/x-pack/plugins/upgrade_assistant/tsconfig.json +++ b/x-pack/plugins/upgrade_assistant/tsconfig.json @@ -20,7 +20,6 @@ "@kbn/features-plugin", "@kbn/licensing-plugin", "@kbn/es-ui-shared-plugin", - "@kbn/infra-plugin", "@kbn/cloud-plugin", "@kbn/test-jest-helpers", "@kbn/share-plugin", @@ -37,6 +36,7 @@ "@kbn/core-elasticsearch-client-server-mocks", "@kbn/utility-types", "@kbn/shared-ux-router", + "@kbn/logs-shared-plugin", ], "exclude": [ "target/**/*", diff --git a/x-pack/test/api_integration/apis/logs_ui/log_views.ts b/x-pack/test/api_integration/apis/logs_ui/log_views.ts index 646d9fd3bb5e3..07b2ffdbf6832 100644 --- a/x-pack/test/api_integration/apis/logs_ui/log_views.ts +++ b/x-pack/test/api_integration/apis/logs_ui/log_views.ts @@ -6,14 +6,14 @@ */ import expect from '@kbn/expect'; -import { defaultLogViewId, LogViewAttributes } from '@kbn/infra-plugin/common/log_views'; +import { defaultLogViewId, LogViewAttributes } from '@kbn/logs-shared-plugin/common/log_views'; import { defaultSourceConfiguration, infraSourceConfigurationSavedObjectName, mergeSourceConfiguration, } from '@kbn/infra-plugin/server/lib/sources'; import { extractSavedObjectReferences } from '@kbn/infra-plugin/server/lib/sources/saved_object_references'; -import { logViewSavedObjectName } from '@kbn/infra-plugin/server/saved_objects/log_view'; +import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts index 6efb17e1571cc..fd87af88ebc8b 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts @@ -17,7 +17,7 @@ import { LOG_ENTRIES_HIGHLIGHTS_PATH, logEntriesHighlightsRequestRT, logEntriesHighlightsResponseRT, -} from '@kbn/infra-plugin/common/http_api'; +} from '@kbn/logs-shared-plugin/common'; import { FtrProviderContext } from '../../ftr_provider_context'; diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts b/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts index 9c7c5548fcdbc..4ae51422ea688 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts @@ -19,7 +19,7 @@ import { LOG_ENTRIES_SUMMARY_PATH, logEntriesSummaryRequestRT, logEntriesSummaryResponseRT, -} from '@kbn/infra-plugin/common/http_api'; +} from '@kbn/logs-shared-plugin/common'; import { FtrProviderContext } from '../../ftr_provider_context'; diff --git a/x-pack/test/common/services/infra_log_views.ts b/x-pack/test/common/services/infra_log_views.ts index a6a87da67e1aa..3862295e997ad 100644 --- a/x-pack/test/common/services/infra_log_views.ts +++ b/x-pack/test/common/services/infra_log_views.ts @@ -10,8 +10,8 @@ import { PutLogViewRequestPayload, putLogViewRequestPayloadRT, putLogViewResponsePayloadRT, -} from '@kbn/infra-plugin/common/http_api'; -import { getLogViewUrl } from '@kbn/infra-plugin/common/http_api/log_views'; +} from '@kbn/logs-shared-plugin/common/http_api'; +import { getLogViewUrl } from '@kbn/logs-shared-plugin/common/http_api/log_views'; import { decodeOrThrow } from '@kbn/infra-plugin/common/runtime_types'; import { FtrProviderContext } from '../ftr_provider_context'; diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 03496116b2072..4a2aff8ae7739 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -130,6 +130,7 @@ "@kbn/slo-schema", "@kbn/lens-plugin", "@kbn/notifications-plugin", + "@kbn/logs-shared-plugin", "@kbn/telemetry-tools", "@kbn/profiling-plugin", "@kbn/observability-onboarding-plugin" diff --git a/yarn.lock b/yarn.lock index dec901f6e1b29..3037b73b85d8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4618,6 +4618,10 @@ version "0.0.0" uid "" +"@kbn/logs-shared-plugin@link:x-pack/plugins/logs_shared": + version "0.0.0" + uid "" + "@kbn/logstash-plugin@link:x-pack/plugins/logstash": version "0.0.0" uid "" From e654c8e936853e1952b2f46b862fd34911618d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Wed, 5 Jul 2023 10:38:55 +0200 Subject: [PATCH 27/64] [Enterprise Search]Add 404 error handling for mappings and documents endpoints (#161203) ## Summary Add 404 handler for the Document and mappings endpoints. They were default handlers before and returning 502. Error message is much more meaningful at the moment. ![Screenshot 2023-07-04 at 18 16 53](https://github.com/elastic/kibana/assets/1410658/f595391b-2889-4370-907f-7e5c0d331f2c) ![Screenshot 2023-07-04 at 18 17 01](https://github.com/elastic/kibana/assets/1410658/018d34d1-273a-4d85-9f5a-78bbf15cf526) ### Checklist Delete any items that are not applicable to this PR. - [ ] [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 --- .../enterprise_search/common/constants.ts | 2 + .../components/search_index/documents.tsx | 4 +- .../search_index/index_mappings.tsx | 4 +- .../plugins/enterprise_search/server/index.ts | 1 - .../server/lib/connectors/start_sync.test.ts | 8 ++-- .../server/lib/connectors/start_sync.ts | 11 +++-- .../indices/delete_access_control_index.ts | 2 +- .../routes/enterprise_search/mapping.ts | 26 ++++++++--- .../server/routes/enterprise_search/search.ts | 43 +++++++++++++------ 9 files changed, 67 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts index c2af49bb9e951..88290c2ed4831 100644 --- a/x-pack/plugins/enterprise_search/common/constants.ts +++ b/x-pack/plugins/enterprise_search/common/constants.ts @@ -210,3 +210,5 @@ export const DEFAULT_PRODUCT_FEATURES: ProductFeatures = { hasNativeConnectors: true, hasWebCrawler: true, }; + +export const CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX = '.search-acl-filter-'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx index 8cf25e16426a8..ea1b1aaecd23f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents.tsx @@ -20,6 +20,8 @@ import { import { i18n } from '@kbn/i18n'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../../../common/constants'; + import { KibanaLogic } from '../../../shared/kibana'; import { @@ -44,7 +46,7 @@ export const SearchIndexDocuments: React.FC = () => { const indexToShow = selectedIndexType === 'content-index' ? indexName - : indexName.replace('search-', '.search-acl-filter-'); + : indexName.replace('search-', CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX); const shouldShowAccessControlSwitcher = hasDocumentLevelSecurityFeature && productFeatures.hasDocumentLevelSecurityEnabled; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx index 4bc77672f5f7b..5ec31986b2fe4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_mappings.tsx @@ -25,6 +25,8 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../../../common/constants'; + import { docLinks } from '../../../shared/doc_links'; import { KibanaLogic } from '../../../shared/kibana'; @@ -51,7 +53,7 @@ export const SearchIndexIndexMappings: React.FC = () => { const indexToShow = selectedIndexType === 'content-index' ? indexName - : indexName.replace('search-', '.search-acl-filter-'); + : indexName.replace('search-', CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX); const shouldShowAccessControlSwitch = hasDocumentLevelSecurityFeature && productFeatures.hasDocumentLevelSecurityEnabled; diff --git a/x-pack/plugins/enterprise_search/server/index.ts b/x-pack/plugins/enterprise_search/server/index.ts index 704595b708c5e..2918641814341 100644 --- a/x-pack/plugins/enterprise_search/server/index.ts +++ b/x-pack/plugins/enterprise_search/server/index.ts @@ -53,4 +53,3 @@ export const CURRENT_CONNECTORS_INDEX = '.elastic-connectors-v1'; export const CONNECTORS_JOBS_INDEX = '.elastic-connectors-sync-jobs'; export const CONNECTORS_VERSION = 1; export const CRAWLERS_INDEX = '.ent-search-actastic-crawler2_configurations_v2'; -export const CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX = '.search-acl-filter-'; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts index ca7ae9fc76a66..4e35acd1434b4 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts @@ -7,11 +7,9 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { - CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX, - CONNECTORS_INDEX, - CONNECTORS_JOBS_INDEX, -} from '../..'; +import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../common/constants'; + import { SyncJobType, SyncStatus, TriggerMethod } from '../../../common/types/connectors'; import { ErrorCode } from '../../../common/types/error_codes'; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts index e4ef3288819f6..a3b2164c467a1 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts @@ -7,14 +7,13 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { - CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX, - CONNECTORS_INDEX, - CONNECTORS_JOBS_INDEX, -} from '../..'; +import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; import { isConfigEntry } from '../../../common/connectors/is_category_entry'; -import { ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE } from '../../../common/constants'; +import { + CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX, + ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE, +} from '../../../common/constants'; import { ConnectorConfiguration, diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts index 2df773b1af30e..3d185c9fde6f7 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/delete_access_control_index.ts @@ -8,7 +8,7 @@ import { isIndexNotFoundException } from '@kbn/core-saved-objects-migration-server-internal'; import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../..'; +import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../common/constants'; export const deleteAccessControlIndex = async (client: IScopedClusterClient, index: string) => { try { diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts index b963157694acf..0ce48c33a9d38 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts @@ -7,9 +7,13 @@ import { schema } from '@kbn/config-schema'; +import { ErrorCode } from '../../../common/types/error_codes'; + import { fetchMapping } from '../../lib/fetch_mapping'; import { RouteDependencies } from '../../plugin'; +import { createError } from '../../utils/create_error'; import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler'; +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; export function registerMappingRoute({ router, log }: RouteDependencies) { router.get( @@ -24,12 +28,24 @@ export function registerMappingRoute({ router, log }: RouteDependencies) { elasticsearchErrorHandler(log, async (context, request, response) => { const { client } = (await context.core).elasticsearch; - const mapping = await fetchMapping(client, request.params.index_name); + try { + const mapping = await fetchMapping(client, request.params.index_name); - return response.ok({ - body: mapping, - headers: { 'content-type': 'application/json' }, - }); + return response.ok({ + body: mapping, + headers: { 'content-type': 'application/json' }, + }); + } catch (error) { + if (isIndexNotFoundException(error)) { + return createError({ + errorCode: ErrorCode.INDEX_NOT_FOUND, + message: 'Could not found index', + response, + statusCode: 404, + }); + } + throw error; + } }) ); } diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts index 3ea14a2013a59..40158204e3ea3 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts @@ -10,10 +10,13 @@ import { SearchResponseBody } from '@elastic/elasticsearch/lib/api/types'; import { schema } from '@kbn/config-schema'; import { ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } from '../../../common/constants'; +import { ErrorCode } from '../../../common/types/error_codes'; import { fetchSearchResults } from '../../lib/fetch_search_results'; import { RouteDependencies } from '../../plugin'; +import { createError } from '../../utils/create_error'; import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler'; +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; const calculateMeta = (searchResults: SearchResponseBody, page: number, size: number) => { let totalResults = 0; @@ -64,21 +67,33 @@ export function registerSearchRoute({ router, log }: RouteDependencies) { const { client } = (await context.core).elasticsearch; const { page = 0, size = ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } = request.query; const from = page * size; - const searchResults: SearchResponseBody = await fetchSearchResults( - client, - indexName, - searchQuery, - from, - size - ); + try { + const searchResults: SearchResponseBody = await fetchSearchResults( + client, + indexName, + searchQuery, + from, + size + ); - return response.ok({ - body: { - meta: calculateMeta(searchResults, page, size), - results: searchResults, - }, - headers: { 'content-type': 'application/json' }, - }); + return response.ok({ + body: { + meta: calculateMeta(searchResults, page, size), + results: searchResults, + }, + headers: { 'content-type': 'application/json' }, + }); + } catch (error) { + if (isIndexNotFoundException(error)) { + return createError({ + errorCode: ErrorCode.INDEX_NOT_FOUND, + message: 'Could not found index', + response, + statusCode: 404, + }); + } + throw error; + } }) ); } From 77285193045db36453f367d61552638218fde013 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Wed, 5 Jul 2023 10:53:02 +0200 Subject: [PATCH 28/64] [ML] Fix Anomaly Explorer URL for alerting context with non-default space (#160899) ## Summary Fixes #160762 ### 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 --- .../ml/server/lib/alerts/alerting_service.ts | 16 +++++++++++++--- .../register_anomaly_detection_alert_type.ts | 4 ++-- .../ml_rule_types/anomaly_detection/alert.ts | 7 ++++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts index 68b3ed3491503..31794a901416f 100644 --- a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts +++ b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts @@ -23,6 +23,7 @@ import { type MlAnomalyResultType, ML_ANOMALY_RESULT_TYPE, } from '@kbn/ml-anomaly-utils'; +import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { MlClient } from '../ml_client'; import { MlAnomalyDetectionAlertParams, @@ -78,6 +79,7 @@ export function buildExplorerUrl( jobIds: string[], timeRange: { from: string; to: string; mode?: string }, type: MlAnomalyResultType, + spaceId: string, r?: AlertExecutionResult ): string { const isInfluencerResult = type === ML_ANOMALY_RESULT_TYPE.INFLUENCER; @@ -145,7 +147,11 @@ export function buildExplorerUrl( }, }, }; - return `/app/ml/explorer/?_g=${encodeURIComponent( + + const spacePathComponent: string = + !spaceId || spaceId === DEFAULT_SPACE_ID ? '' : `/s/${spaceId}`; + + return `${spacePathComponent}/app/ml/explorer/?_g=${encodeURIComponent( rison.encode(globalState) )}&_a=${encodeURIComponent(rison.encode(appState))}`; } @@ -765,9 +771,11 @@ export function alertingServiceProvider( * Return the result of an alert condition execution. * * @param params - Alert params + * @param spaceId */ execute: async ( - params: MlAnomalyDetectionAlertParams + params: MlAnomalyDetectionAlertParams, + spaceId: string ): Promise< { context: AnomalyDetectionAlertContext; name: string; isHealthy: boolean } | undefined > => { @@ -784,6 +792,7 @@ export function alertingServiceProvider( result.jobIds, { from: result.bucketRange.start, to: result.bucketRange.end }, params.resultType, + spaceId, result ); @@ -806,7 +815,8 @@ export function alertingServiceProvider( to: 'now', mode: 'relative', }, - queryParams.resultType + queryParams.resultType, + spaceId ), jobIds: queryParams.jobIds, message: i18n.translate( diff --git a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts index 7cee5917f6567..d68e40f44b4a6 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts @@ -137,13 +137,13 @@ export function registerAnomalyDetectionAlertType({ minimumLicenseRequired: MINIMUM_FULL_LICENSE, isExportable: true, doesSetRecoveryContext: true, - async executor({ services, params }) { + async executor({ services, params, spaceId }) { const fakeRequest = {} as KibanaRequest; const { execute } = mlSharedServices.alertingServiceProvider( services.savedObjectsClient, fakeRequest ); - const executionResult = await execute(params); + const executionResult = await execute(params, spaceId); if (executionResult && !executionResult.isHealthy) { const alertInstanceName = executionResult.name; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts index 1d69200a277d4..9bd615b99e53b 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/ml_rule_types/anomaly_detection/alert.ts @@ -133,12 +133,16 @@ export default function alertTests({ getService }: FtrProviderContext) { const docs = await waitForDocs(1); for (const doc of docs) { - const { name, message } = doc._source.params; + const { name, message, anomalyExplorerUrl } = doc._source.params; expect(name).to.be('Test AD job'); expect(message).to.be( 'Alerts are raised based on real-time scores. Remember that scores may be adjusted over time as data continues to be analyzed.' ); + // check only part of the URL as time bounds vary based on the anomaly + expect(anomalyExplorerUrl).to.contain( + '/s/space1/app/ml/explorer/?_g=(ml%3A(jobIds%3A!(rt-anomaly-mean-value))' + ); } }); @@ -166,6 +170,7 @@ export default function alertTests({ getService }: FtrProviderContext) { params: { name: '{{{alertName}}}', message: '{{{context.message}}}', + anomalyExplorerUrl: '{{{context.anomalyExplorerUrl}}}', }, }, ], From 0b13a843f86097ed38086791d846754edd17b25a Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 5 Jul 2023 11:23:46 +0200 Subject: [PATCH 29/64] Update publicBaseUrl warning id (#161204) Related to #161091 ## Summary I learned that when we update a default message, we should manually remove outdated translations. In this PR, I updated the ID and removed outdated translations. I will not backport this PR since the translation for the previous version is already started so I will keep the previous translation for v8.9. Please let me know if there is an issue with this approach. --- x-pack/plugins/translations/translations/fr-FR.json | 1 - x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - .../public/application/lib/validate_params_for_warnings.ts | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 29c1982ae0d3b..9ab100fe729a5 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -37760,7 +37760,6 @@ "xpack.triggersActionsUI.sections.actionTypeForm.addNewConnectorEmptyButton": "Ajouter un connecteur", "xpack.triggersActionsUI.sections.actionTypeForm.notifyWhenThrottleWarning": "Les intervalles d'action personnalisés ne peuvent pas être plus courts que l'intervalle de vérification de la règle", "xpack.triggersActionsUI.sections.actionTypeForm.summaryGroupTitle": "Résumé des alertes", - "xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl": "server.publicBaseUrl n'est pas défini. Les actions utiliseront des URL relatives.", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutHeaderCompatibility": "Compatibilité :", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "Sélectionner un connecteur", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "Création de \"{connectorName}\" effectuée", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2b610e8af95c6..c79922135bd8e 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -37734,7 +37734,6 @@ "xpack.triggersActionsUI.sections.actionTypeForm.addNewConnectorEmptyButton": "コネクターの追加", "xpack.triggersActionsUI.sections.actionTypeForm.notifyWhenThrottleWarning": "カスタムアクション間隔をルールのチェック間隔よりも短くすることはできません", "xpack.triggersActionsUI.sections.actionTypeForm.summaryGroupTitle": "アラートの概要", - "xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl": "server.publicBaseUrlが設定されていません。アクションは相対URLを使用します。", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutHeaderCompatibility": "互換性:", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "コネクターを選択", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "「{connectorName}」を作成しました", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 90059adb4de1f..163f3c66e1448 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -37728,7 +37728,6 @@ "xpack.triggersActionsUI.sections.actionTypeForm.addNewConnectorEmptyButton": "添加连接器", "xpack.triggersActionsUI.sections.actionTypeForm.notifyWhenThrottleWarning": "定制操作时间间隔不能短于规则的检查时间间隔", "xpack.triggersActionsUI.sections.actionTypeForm.summaryGroupTitle": "告警的摘要", - "xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl": "未设置 server.publicBaseUrl。操作将使用相对 URL。", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutHeaderCompatibility": "兼容性:", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "选择连接器", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "已创建“{connectorName}”", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts index 447a751f32a3c..e0f552f6bb0f7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/validate_params_for_warnings.ts @@ -11,7 +11,7 @@ import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common'; import Mustache from 'mustache'; const publicUrlWarning = i18n.translate( - 'xpack.triggersActionsUI.sections.actionTypeForm.warning.publicUrl', + 'xpack.triggersActionsUI.sections.actionTypeForm.warning.publicBaseUrl', { defaultMessage: 'server.publicBaseUrl is not set. Generated URLs will be either relative or empty.', From 38b487a879ba12a2a6b37930fd05d60aa3c7ae10 Mon Sep 17 00:00:00 2001 From: Cristina Amico Date: Wed, 5 Jul 2023 11:27:54 +0200 Subject: [PATCH 30/64] [Fleet] Fix permissions in integrations Assets page (#161233) Fixes https://github.com/elastic/kibana/issues/161058 ## Summary Fix permissions for Integrations assets tab. A user with role "Fleet All - Integration Read" wasn't able to visualize the assets tab. ### Test - Create a user with "Fleet All - Integration Read" as shown in this video: https://github.com/elastic/kibana/assets/16084106/a13c6ddd-a3d1-4e15-9c9d-9d56e1dbb0f0 - Log in with this new user - Navigate to any installed integration, then to the Assets tab - Verify that the assets are shown as usual (no warnings are shown) Screenshot 2023-07-05 at 10 22 36 --- .../integrations/sections/epm/screens/detail/assets/assets.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx index b9a023bef1ef7..2f6e20f097601 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx @@ -46,7 +46,7 @@ export const AssetsPage = ({ packageInfo }: AssetsPanelProps) => { const { spaces } = useStartServices(); const customAssetsExtension = useUIExtension(packageInfo.name, 'package-detail-assets'); - const canReadPackageSettings = useAuthz().integrations.readPackageSettings; + const canReadPackageSettings = useAuthz().integrations.readPackageInfo; const { getPath } = useLink(); const getPackageInstallStatus = useGetPackageInstallStatus(); From 3d146f3eff411ecd12dc7c1f561bd74e8b60a02d Mon Sep 17 00:00:00 2001 From: Andrew Gizas Date: Wed, 5 Jul 2023 12:41:24 +0300 Subject: [PATCH 31/64] fixing the path of manifets for hints autodiscover (#161075) ## Summary Bug: Fixing the path for downloading hint templates for elastic standalone agent. See that the path had changed to https://github.com/elastic/elastic-agent/tree/main/deploy/kubernetes/elastic-agent-standalone/templates.d --- x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts index 63691b878eaa7..f01f6d71df89d 100644 --- a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts +++ b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts @@ -42,7 +42,7 @@ spec: # - -c # - >- # mkdir -p /etc/elastic-agent/inputs.d && - # wget -O - https://github.com/elastic/elastic-agent/archive/main.tar.gz | tar xz -C /etc/elastic-agent/inputs.d --strip=5 "elastic-agent-main/deploy/kubernetes/elastic-agent/templates.d" + # wget -O - https://github.com/elastic/elastic-agent/archive/main.tar.gz | tar xz -C /etc/elastic-agent/inputs.d --strip=5 "elastic-agent-main/deploy/kubernetes/elastic-agent-standalone/templates.d" # volumeMounts: # - name: external-inputs # mountPath: /etc/elastic-agent/inputs.d From 6a84ea186b664b55c19a9465b2ea80ddd29c6ffd Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 5 Jul 2023 11:55:38 +0200 Subject: [PATCH 32/64] [Synthetics] Remove TLS alert option for ICMP monitor (#161173) --- .../monitor_add_edit/form/field_config.tsx | 21 ++++++++++--------- .../monitor_add_edit/form/form_config.tsx | 1 - .../tls_rule/tls_rule_executor.test.ts | 3 ++- .../alert_rules/tls_rule/tls_rule_executor.ts | 5 +++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx index 56987e86b9c83..133f509c4b0ec 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx @@ -507,9 +507,13 @@ export const FIELD = (readOnly?: boolean): FieldMap => ({ controlled: true, props: ({ setValue, field }): EuiSwitchProps => ({ id: 'syntheticsMonitorConfigIsAlertEnabled', - label: i18n.translate('xpack.synthetics.monitorConfig.enabledAlerting.label', { - defaultMessage: 'Enable status alerts', - }), + label: field?.value + ? i18n.translate('xpack.synthetics.monitorConfig.enabledAlerting.label', { + defaultMessage: 'Disable status alerts on this monitor', + }) + : i18n.translate('xpack.synthetics.monitorConfig.disabledAlerting.label', { + defaultMessage: 'Enable status alerts on this monitor', + }), checked: field?.value || false, onChange: (event) => { setValue(AlertConfigKey.STATUS_ENABLED, !!event.target.checked); @@ -522,18 +526,15 @@ export const FIELD = (readOnly?: boolean): FieldMap => ({ [AlertConfigKey.TLS_ENABLED]: { fieldKey: AlertConfigKey.TLS_ENABLED, component: Switch, - label: i18n.translate('xpack.synthetics.monitorConfig.enabledAlerting.tls.label', { - defaultMessage: 'Enable TLS alerts', - }), controlled: true, - props: ({ isEdit, setValue, field }): EuiSwitchProps => ({ + props: ({ setValue, field }): EuiSwitchProps => ({ id: 'syntheticsMonitorConfigIsTlsAlertEnabled', - label: isEdit + label: field?.value ? i18n.translate('xpack.synthetics.monitorConfig.edit.alertTlsEnabled.label', { - defaultMessage: 'Disabling will stop tls alerting on this monitor.', + defaultMessage: 'Disable TLS alerts on this monitor.', }) : i18n.translate('xpack.synthetics.monitorConfig.create.alertTlsEnabled.label', { - defaultMessage: 'Enable tls alerts on this monitor.', + defaultMessage: 'Enable TLS alerts on this monitor.', }), checked: field?.value || false, onChange: (event) => { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx index ffd8f1c3cfccd..8e44f9727a5c3 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx @@ -287,7 +287,6 @@ export const FORM_CONFIG = (readOnly: boolean): FieldConfig => ({ FIELD(readOnly)[ConfigKey.TIMEOUT], FIELD(readOnly)[ConfigKey.ENABLED], FIELD(readOnly)[AlertConfigKey.STATUS_ENABLED], - FIELD(readOnly)[AlertConfigKey.TLS_ENABLED], ], advanced: [DEFAULT_DATA_OPTIONS(readOnly), ICMP_ADVANCED(readOnly).requestConfig], }, diff --git a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts index ac89f6f6bbbba..eec9a8be02fd7 100644 --- a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts +++ b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.test.ts @@ -75,7 +75,8 @@ describe('tlsRuleExecutor', () => { expect(certs).toEqual([]); expect(spy).toHaveBeenCalledWith({ - filter: 'synthetics-monitor.attributes.alert.tls.enabled: true', + filter: + 'synthetics-monitor.attributes.alert.tls.enabled: true and (synthetics-monitor.attributes.type: http or synthetics-monitor.attributes.type: tcp)', soClient, }); }); diff --git a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts index ad5f6ad2b88d0..71cfd7453c12f 100644 --- a/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts +++ b/x-pack/plugins/synthetics/server/alert_rules/tls_rule/tls_rule_executor.ts @@ -21,7 +21,7 @@ import { getAllMonitors, processMonitors, } from '../../saved_objects/synthetics_monitor/get_all_monitors'; -import { CertResult, EncryptedSyntheticsMonitor } from '../../../common/runtime_types'; +import { CertResult, ConfigKey, EncryptedSyntheticsMonitor } from '../../../common/runtime_types'; import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; import { monitorAttributes } from '../../../common/types/saved_objects'; import { AlertConfigKey } from '../../../common/constants/monitor_management'; @@ -55,9 +55,10 @@ export class TLSRuleExecutor { } async getMonitors() { + const HTTP_OR_TCP = `${monitorAttributes}.${ConfigKey.MONITOR_TYPE}: http or ${monitorAttributes}.${ConfigKey.MONITOR_TYPE}: tcp`; this.monitors = await getAllMonitors({ soClient: this.soClient, - filter: `${monitorAttributes}.${AlertConfigKey.TLS_ENABLED}: true`, + filter: `${monitorAttributes}.${AlertConfigKey.TLS_ENABLED}: true and (${HTTP_OR_TCP})`, }); const { From 54dc40ff69f8ca0035cc722594b6cfc1512e499b Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 5 Jul 2023 12:10:32 +0200 Subject: [PATCH 33/64] [Synthetics] Overview page fix last refresh value display (#161086) Co-authored-by: Abdul Zahid --- .../plugins/synthetics/common/constants/ui.ts | 21 --------- .../common/components/last_refreshed.tsx | 11 ----- .../synthetics/utils/formatting/format.ts | 38 ---------------- .../utils/monitor_test_result/timestamp.ts | 45 ------------------- .../public/hooks/use_date_format.test.tsx | 25 +++++++++++ .../public/hooks/use_date_format.ts | 11 +++-- 6 files changed, 33 insertions(+), 118 deletions(-) delete mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts diff --git a/x-pack/plugins/synthetics/common/constants/ui.ts b/x-pack/plugins/synthetics/common/constants/ui.ts index d014b8b8ea6ff..189dd40660ae7 100644 --- a/x-pack/plugins/synthetics/common/constants/ui.ts +++ b/x-pack/plugins/synthetics/common/constants/ui.ts @@ -67,27 +67,6 @@ export const ML_MODULE_ID = 'uptime_heartbeat'; export const UNNAMED_LOCATION = 'Unnamed-location'; -export const SHORT_TS_LOCALE = 'en-short-locale'; - -export const SHORT_TIMESPAN_LOCALE = { - relativeTime: { - future: 'in %s', - past: '%s ago', - s: '%ds', - ss: '%ss', - m: '%dm', - mm: '%dm', - h: '%dh', - hh: '%dh', - d: '%dd', - dd: '%dd', - M: '%d Mon', - MM: '%d Mon', - y: '%d Yr', - yy: '%d Yr', - }, -}; - export enum CERT_STATUS { OK = 'OK', EXPIRING_SOON = 'EXPIRING_SOON', diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx index 28a4ef1c5b101..bc086f67c822b 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx @@ -10,7 +10,6 @@ import moment from 'moment'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useSelector } from 'react-redux'; -import { SHORT_TIMESPAN_LOCALE, SHORT_TS_LOCALE } from '../../../../../../common/constants'; import { useSyntheticsRefreshContext } from '../../../contexts'; import { selectRefreshPaused } from '../../../state'; @@ -41,18 +40,8 @@ export function LastRefreshed() { const isWarning = moment().diff(moment(lastRefreshed), 'minutes') > 1; const isDanger = moment().diff(moment(lastRefreshed), 'minutes') > 5; - const prevLocal: string = moment.locale() ?? 'en'; - - const shortLocale = moment.locale(SHORT_TS_LOCALE) === SHORT_TS_LOCALE; - if (!shortLocale) { - moment.defineLocale(SHORT_TS_LOCALE, SHORT_TIMESPAN_LOCALE); - } - const updatedDate = moment(lastRefreshed).from(refresh); - // Need to reset locale so it doesn't effect other parts of the app - moment.locale(prevLocal); - return ( { - if (relative) { - const prevLocale: string = moment.locale() ?? 'en'; - - const shortLocale = moment.locale(SHORT_TS_LOCALE) === SHORT_TS_LOCALE; - - if (!shortLocale) { - moment.defineLocale(SHORT_TS_LOCALE, SHORT_TIMESPAN_LOCALE); - } - - let shortTimestamp; - if (typeof timeStamp === 'string') { - shortTimestamp = parseTimestamp(timeStamp).fromNow(); - } else { - shortTimestamp = timeStamp.fromNow(); - } - - // Reset it so, it doesn't impact other part of the app - moment.locale(prevLocale); - return shortTimestamp; - } else { - if (moment().diff(timeStamp, 'd') >= 1) { - return timeStamp.format('ll LTS'); - } - return timeStamp.format('LTS'); - } -}; - -export const parseTimestamp = (tsValue: string): Moment => { - let parsed = Date.parse(tsValue); - if (isNaN(parsed)) { - parsed = parseInt(tsValue, 10); - } - return moment(parsed); -}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts b/x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts deleted file mode 100644 index c9c4d022b869d..0000000000000 --- a/x-pack/plugins/synthetics/public/apps/synthetics/utils/monitor_test_result/timestamp.ts +++ /dev/null @@ -1,45 +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 moment from 'moment'; -import { SHORT_TIMESPAN_LOCALE, SHORT_TS_LOCALE } from '../../../../../common/constants'; - -export const parseTimestamp = (tsValue: string): moment.Moment => { - let parsed = Date.parse(tsValue); - if (isNaN(parsed)) { - parsed = parseInt(tsValue, 10); - } - return moment(parsed); -}; - -export const getShortTimeStamp = (timeStamp: moment.Moment, relative = false) => { - if (relative) { - const prevLocale: string = moment.locale() ?? 'en'; - - const shortLocale = moment.locale(SHORT_TS_LOCALE) === SHORT_TS_LOCALE; - - if (!shortLocale) { - moment.defineLocale(SHORT_TS_LOCALE, SHORT_TIMESPAN_LOCALE); - } - - let shortTimestamp; - if (typeof (timeStamp as unknown) === 'string') { - shortTimestamp = parseTimestamp(timeStamp as unknown as string).fromNow(); - } else { - shortTimestamp = timeStamp.fromNow(); - } - - // Reset it so, it doesn't impact other part of the app - moment.locale(prevLocale); - return shortTimestamp; - } else { - if (moment().diff(timeStamp, 'd') >= 1) { - return timeStamp.format('ll LTS'); - } - return timeStamp.format('LTS'); - } -}; diff --git a/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx b/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx index 3ddfe441d3895..42cee2817e8f2 100644 --- a/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx +++ b/x-pack/plugins/synthetics/public/hooks/use_date_format.test.tsx @@ -6,10 +6,25 @@ */ import { renderHook } from '@testing-library/react-hooks'; +import { i18n } from '@kbn/i18n'; + +jest.mock('@kbn/i18n', () => ({ + i18n: { + getLocale: jest.fn().mockReturnValue(undefined), + }, +})); import { useDateFormat } from './use_date_format'; describe('useDateFormat', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + afterAll(() => { + jest.restoreAllMocks(); + }); + Object.defineProperty(global.navigator, 'language', { value: 'en-US', writable: true, @@ -26,4 +41,14 @@ describe('useDateFormat', () => { const response = renderHook(() => useDateFormat()); expect(response.result.current('2023-02-01 13:00:00')).toEqual('1 Feb 2023 @ 13:00'); }); + it('prefers Kibana locale if set', () => { + jest.spyOn(i18n, 'getLocale').mockReturnValue('fr-FR'); + + Object.defineProperty(global.navigator, 'language', { + value: 'en-GB', + writable: true, + }); + const response = renderHook(() => useDateFormat()); + expect(response.result.current('2023-02-01 13:00:00')).toEqual('1 févr. 2023 @ 13:00'); + }); }); diff --git a/x-pack/plugins/synthetics/public/hooks/use_date_format.ts b/x-pack/plugins/synthetics/public/hooks/use_date_format.ts index 2fc143af4a87f..4b402cc2367cd 100644 --- a/x-pack/plugins/synthetics/public/hooks/use_date_format.ts +++ b/x-pack/plugins/synthetics/public/hooks/use_date_format.ts @@ -7,13 +7,18 @@ import moment from 'moment'; import { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; export function useDateFormat(): (timestamp?: string) => string { - const locale = navigator.language; + const kibanaLocale = i18n.getLocale(); + const clientLocale = navigator.language; useEffect(() => { - moment.locale(locale); - }, [locale]); + const preferredLocale = kibanaLocale ?? clientLocale; + if (moment.locale() !== preferredLocale) { + moment.locale(preferredLocale); + } + }, [kibanaLocale, clientLocale]); return (timestamp?: string) => { if (!timestamp) return ''; From ee6ca657eeadd498f4783331539b102ec619097b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:38:55 +0200 Subject: [PATCH 34/64] [Console] Add logic for query params (#160515) ## Summary Fixes https://github.com/elastic/kibana/issues/160528 Follow up to https://github.com/elastic/kibana/pull/159241 This PR adds logic for query parameters to the new script generating Console autocomplete definitions from ES specification. The logic is explained in details in the [file](https://github.com/elastic/kibana/pull/160515/files#diff-b6853462c38db4e237dbb3cdec9d9f6659aa3fdc5f96a6193f2c4bac1439db43) but here is a short version: - Currently, the autocomplete engine only works with url params of 2 types: boolean (`__flag__`) and a list of options (for example `['all', 'open', 'hidden']`). The script will convert all of the url params from the specification into this format: a boolean or a list. If there are no set options for a parameter, but a default value is known, then it will be converted into a list with 1 option, for example `['random']` so that the autocomplete engine will display it as a single suggestion. We also need to convert any numbers to strings, because they won't be displayed otherwise. - Endpoints in the specification have a property `request` which in turn has 2 properties describing url params: `attachedBehaviours` and `query`. Both object contain an array of `property`'s each describing a url param. `property` is configured with either a built in type (`string`, `number`, `boolean`) or defined type, for example `ExpandWildcards`. By finding the type `ExpandWildcards` in the specification, we can convert this type to a list of options `['open', 'all', 'none', 'hidden']`. ### How to test Similar to https://github.com/elastic/kibana/pull/159241, you need to re-generenate the definitions and see if local changes to definitions files make sense. 1. Checkout the ES specification [repo](https://github.com/elastic/elasticsearch-specification) 2. Run the command `node scripts/generate_console_definitions.js --source --emptyDest` 3. Check the changes in the folder `KIBANA_REPO/src/plugins/console/server/lib/spec_definitions/json/generated` #### Intended changes to the definitions files - Most of endpoints have 4 default url params that previously were not in the definitions files but added to all endpoints in this [file](https://github.com/elastic/kibana/blob/main/src/plugins/console/public/lib/autocomplete/url_params.js). These params are configured in the interface `CommonQueryParameters` in the specification (see this [file](https://github.com/elastic/elasticsearch-specification/blob/main/specification/_spec_utils/behaviors.ts)).
The interface in the specification ```js export interface CommonQueryParameters { error_trace?: boolean filter_path?: string | string[] human?: boolean pretty?: boolean } ``` The converted url params ```json "error_trace": "__flag__", "filter_path": [], "human": "__flag__", "pretty": "__flag__", ```
- Previously existing `url_components` property in the definitions is deleted and this change will be addressed separately. (not sure it is currently working but added a task to the meta issue) - Previously numbers were configured as `0` or `0.0` but that is not currently displayed in suggestions. Instead, the new script converts numbers to strings and if any default value is present, it will be displayed as a suggestion. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../README.md | 11 +- .../src/generate_console_definitions.ts | 98 ++-- .../src/generate_query_params.test.ts | 375 +++++++++++++++ .../src/generate_query_params.ts | 219 +++++++++ .../types/autocomplete_definition_types.ts | 23 + .../src/types/index.ts | 15 + .../src/types/specification_types.ts | 442 ++++++++++++++++++ .../src/utils.ts | 17 + 8 files changed, 1131 insertions(+), 69 deletions(-) create mode 100644 packages/kbn-generate-console-definitions/src/generate_query_params.test.ts create mode 100644 packages/kbn-generate-console-definitions/src/generate_query_params.ts create mode 100644 packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.ts create mode 100644 packages/kbn-generate-console-definitions/src/types/index.ts create mode 100644 packages/kbn-generate-console-definitions/src/types/specification_types.ts create mode 100644 packages/kbn-generate-console-definitions/src/utils.ts diff --git a/packages/kbn-generate-console-definitions/README.md b/packages/kbn-generate-console-definitions/README.md index 71596b6fdf0bc..75d43fd7c493e 100644 --- a/packages/kbn-generate-console-definitions/README.md +++ b/packages/kbn-generate-console-definitions/README.md @@ -1,3 +1,10 @@ -# @kbn/generate-console-definitions +# Generate console definitions +This package is a script to generate definitions used in Console to display autocomplete suggestions. The script is +a new implementation of `kbn-spec-to-console` package: The old script uses [JSON specs](https://github.com/elastic/elasticsearch/tree/main/rest-api-spec) from the Elasticsearch repo as the source, whereas this script uses the Elasticsearch specification [repo](https://github.com/elastic/elasticsearch-specification) as the source. + +## Instructions +1. Checkout the Elasticsearch specification [repo](https://github.com/elastic/elasticsearch-specification). +2. Run the command `node scripts/generate_console_definitions.js --source --emptyDest` + This command will use the folder `` as the source and the constant [`AUTOCOMPLETE_DEFINITIONS_FOLDER`](https://github.com/elastic/kibana/blob/main/src/plugins/console/common/constants/autocomplete_definitions.ts) as the destination. Based on the value of the constant, the autocomplete definitions will be generated in the folder `/src/plugins/server/lib/spec_definitions/json/generated`. Using the flag `--emptyDest` will remove any existing files in the destination folder. +3. It's possible to generate the definitions into a different folder. For that pass an option to the command `--dest ` and also update the constant [`AUTOCOMPLETE_DEFINITIONS_FOLDER`](https://github.com/elastic/kibana/blob/main/src/plugins/console/common/constants/autocomplete_definitions.ts) so that the Console server will load the definitions from this folder. -Empty package generated by @kbn/generate diff --git a/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts b/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts index f5bb7cd687c7b..1d4918f44c6b1 100644 --- a/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts +++ b/packages/kbn-generate-console-definitions/src/generate_console_definitions.ts @@ -9,51 +9,16 @@ import fs from 'fs'; import Path, { join } from 'path'; import { ToolingLog } from '@kbn/tooling-log'; - -interface EndpointRequest { - name: string; - namespace: string; -} - -interface Endpoint { - name: string; - urls: Array<{ - methods: string[]; - path: string; - }>; - docUrl: string; - request: null | EndpointRequest; -} - -interface SchemaType { - name: { - name: string; - namespace: string; - }; -} - -interface Schema { - endpoints: Endpoint[]; - types: SchemaType[]; -} - -interface UrlParams { - [key: string]: number | string; -} - -interface BodyParams { - [key: string]: number | string; -} - -interface Definition { - documentation?: string; - methods: string[]; - patterns: string[]; - url_params?: UrlParams; - data_autocomplete_rules?: BodyParams; -} - -const generateMethods = (endpoint: Endpoint): string[] => { +import { generateQueryParams } from './generate_query_params'; +import type { + AutocompleteBodyParams, + AutocompleteDefinition, + AutocompleteUrlParams, + SpecificationTypes, +} from './types'; +import { findTypeDefinition } from './utils'; + +const generateMethods = (endpoint: SpecificationTypes.Endpoint): string[] => { // this array consists of arrays of strings const methodsArray = endpoint.urls.map((url) => url.methods); // flatten to return array of strings @@ -62,7 +27,7 @@ const generateMethods = (endpoint: Endpoint): string[] => { return [...new Set(flattenMethodsArray)]; }; -const generatePatterns = (endpoint: Endpoint): string[] => { +const generatePatterns = (endpoint: SpecificationTypes.Endpoint): string[] => { return endpoint.urls.map(({ path }) => { let pattern = path; // remove leading / if present @@ -73,42 +38,37 @@ const generatePatterns = (endpoint: Endpoint): string[] => { }); }; -const generateDocumentation = (endpoint: Endpoint): string => { +const generateDocumentation = (endpoint: SpecificationTypes.Endpoint): string => { return endpoint.docUrl; }; const generateParams = ( - endpoint: Endpoint, - schema: Schema -): { urlParams: UrlParams; bodyParams: BodyParams } | undefined => { + endpoint: SpecificationTypes.Endpoint, + schema: SpecificationTypes.Model +): { urlParams: AutocompleteUrlParams; bodyParams: AutocompleteBodyParams } | undefined => { const { request } = endpoint; if (!request) { return; } - const requestType = schema.types.find( - ({ name: { name, namespace } }) => name === request.name && namespace === request.namespace - ); + const requestType = findTypeDefinition(schema, request); if (!requestType) { return; } - - const urlParams = generateUrlParams(requestType); + const urlParams = generateQueryParams(requestType as SpecificationTypes.Request, schema); const bodyParams = generateBodyParams(requestType); return { urlParams, bodyParams }; }; -const generateUrlParams = (requestType: SchemaType): UrlParams => { - return {}; -}; - -const generateBodyParams = (requestType: SchemaType): BodyParams => { +const generateBodyParams = ( + requestType: SpecificationTypes.TypeDefinition +): AutocompleteBodyParams => { return {}; }; const addParams = ( - definition: Definition, - params: { urlParams: UrlParams; bodyParams: BodyParams } -): Definition => { + definition: AutocompleteDefinition, + params: { urlParams: AutocompleteUrlParams; bodyParams: AutocompleteBodyParams } +): AutocompleteDefinition => { const { urlParams, bodyParams } = params; if (urlParams && Object.keys(urlParams).length > 0) { definition.url_params = urlParams; @@ -119,15 +79,19 @@ const addParams = ( return definition; }; -const generateDefinition = (endpoint: Endpoint, schema: Schema): Definition => { +const generateDefinition = ( + endpoint: SpecificationTypes.Endpoint, + schema: SpecificationTypes.Model +): AutocompleteDefinition => { const methods = generateMethods(endpoint); const patterns = generatePatterns(endpoint); const documentation = generateDocumentation(endpoint); - let definition: Definition = { methods, patterns, documentation }; + let definition: AutocompleteDefinition = {}; const params = generateParams(endpoint, schema); if (params) { definition = addParams(definition, params); } + definition = { ...definition, methods, patterns, documentation }; return definition; }; @@ -143,7 +107,7 @@ export function generateConsoleDefinitions({ }) { const pathToSchemaFile = Path.resolve(specsRepo, 'output/schema/schema.json'); log.info('loading the ES specification schema file'); - const schema = JSON.parse(fs.readFileSync(pathToSchemaFile, 'utf8')) as Schema; + const schema = JSON.parse(fs.readFileSync(pathToSchemaFile, 'utf8')) as SpecificationTypes.Model; const { endpoints } = schema; log.info(`iterating over endpoints array: ${endpoints.length} endpoints`); @@ -151,7 +115,7 @@ export function generateConsoleDefinitions({ const { name } = endpoint; log.info(name); const definition = generateDefinition(endpoint, schema); - const fileContent: { [name: string]: Definition } = { + const fileContent: { [name: string]: AutocompleteDefinition } = { [name]: definition, }; fs.writeFileSync( diff --git a/packages/kbn-generate-console-definitions/src/generate_query_params.test.ts b/packages/kbn-generate-console-definitions/src/generate_query_params.test.ts new file mode 100644 index 0000000000000..3d658ba60f174 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/generate_query_params.test.ts @@ -0,0 +1,375 @@ +/* + * 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 { SpecificationTypes } from './types'; +import { generateQueryParams } from './generate_query_params'; +import { UrlParamValue } from './types/autocomplete_definition_types'; + +describe('generateQueryParams', () => { + const mockRequestType: SpecificationTypes.Request = { + body: { kind: 'no_body' }, + kind: 'request', + name: { + name: 'TestRequest', + namespace: 'test.namespace', + }, + path: [], + query: [], + specLocation: '', + }; + + const getMockProperty = ({ + propertyName, + typeName, + serverDefault, + type, + }: { + propertyName: string; + typeName?: SpecificationTypes.TypeName; + serverDefault?: SpecificationTypes.Property['serverDefault']; + type?: SpecificationTypes.ValueOf; + }): SpecificationTypes.Property => { + return { + description: 'Description', + name: propertyName, + required: false, + serverDefault: serverDefault ?? undefined, + type: type ?? { + kind: 'instance_of', + type: typeName ?? { + name: 'string', + namespace: '_builtins', + }, + }, + }; + }; + + const mockSchema: SpecificationTypes.Model = { + endpoints: [], + types: [], + }; + + it('iterates over attachedBehaviours', () => { + const behaviour1: SpecificationTypes.Interface = { + kind: 'interface', + name: { + name: 'behaviour1', + namespace: 'test.namespace', + }, + properties: [getMockProperty({ propertyName: 'property1' })], + specLocation: '', + }; + const behaviour2: SpecificationTypes.Interface = { + kind: 'interface', + name: { + name: 'behaviour2', + namespace: 'test.namespace', + }, + properties: [ + getMockProperty({ propertyName: 'property2' }), + getMockProperty({ propertyName: 'property3' }), + ], + specLocation: '', + }; + const schema: SpecificationTypes.Model = { + ...mockSchema, + types: [behaviour1, behaviour2], + }; + const requestType: SpecificationTypes.Request = { + ...mockRequestType, + attachedBehaviors: ['behaviour1', 'behaviour2'], + }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + property1: '', + property2: '', + property3: '', + }); + }); + + it('iterates over query properties', () => { + const requestType = { + ...mockRequestType, + query: [ + getMockProperty({ propertyName: 'property1' }), + getMockProperty({ propertyName: 'property2' }), + ], + }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + property1: '', + property2: '', + }); + }); + + it('converts builtin types', () => { + const stringProperty = getMockProperty({ + propertyName: 'stringProperty', + typeName: { name: 'string', namespace: '_builtins' }, + }); + const numberProperty = getMockProperty({ + propertyName: 'numberProperty', + typeName: { name: 'number', namespace: '_builtins' }, + }); + const booleanProperty = getMockProperty({ + propertyName: 'booleanProperty', + typeName: { name: 'boolean', namespace: '_builtins' }, + }); + const requestType = { + ...mockRequestType, + query: [stringProperty, numberProperty, booleanProperty], + }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + stringProperty: '', + numberProperty: '', + booleanProperty: '__flag__', + }); + }); + + it('adds serverDefault value if any', () => { + const propertyWithDefault = getMockProperty({ + propertyName: 'propertyWithDefault', + serverDefault: 'default', + }); + const requestType = { ...mockRequestType, query: [propertyWithDefault] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + propertyWithDefault: ['default'], + }); + }); + + it('converts an enum property', () => { + const enumProperty = getMockProperty({ + propertyName: 'enumProperty', + typeName: { name: 'EnumType', namespace: 'test.namespace' }, + }); + const enumType: SpecificationTypes.Enum = { + kind: 'enum', + members: [ + { + name: 'enum1', + }, + { + name: 'enum2', + }, + ], + name: { + name: 'EnumType', + namespace: 'test.namespace', + }, + specLocation: '', + }; + const requestType = { ...mockRequestType, query: [enumProperty] }; + const schema = { ...mockSchema, types: [enumType] }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + enumProperty: ['enum1', 'enum2'], + }); + }); + + it('converts a type alias', () => { + const typeAliasProperty = getMockProperty({ + propertyName: 'typeAliasProperty', + typeName: { + name: 'SomeTypeAlias', + namespace: 'test.namespace', + }, + }); + const typeAliasType: SpecificationTypes.TypeAlias = { + kind: 'type_alias', + name: { + name: 'SomeTypeAlias', + namespace: 'test.namespace', + }, + specLocation: '', + type: { + kind: 'instance_of', + type: { + name: 'integer', + namespace: '_types', + }, + }, + }; + const requestType = { ...mockRequestType, query: [typeAliasProperty] }; + const schema: SpecificationTypes.Model = { ...mockSchema, types: [typeAliasType] }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + typeAliasProperty: '', + }); + }); + + it('converts a literal_value to a string', () => { + const stringProperty = getMockProperty({ + propertyName: 'stringProperty', + type: { kind: 'literal_value', value: 'stringValue' }, + }); + const numberProperty = getMockProperty({ + propertyName: 'numberProperty', + type: { kind: 'literal_value', value: 14 }, + }); + const booleanProperty = getMockProperty({ + propertyName: 'booleanProperty', + type: { kind: 'literal_value', value: true }, + }); + const requestType = { + ...mockRequestType, + query: [stringProperty, numberProperty, booleanProperty], + }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + stringProperty: ['stringValue'], + numberProperty: ['14'], + booleanProperty: ['true'], + }); + }); + + describe('converts a union_of', () => { + it('flattens the array if one of the items is converted to an array', () => { + const enumType: SpecificationTypes.Enum = { + kind: 'enum', + members: [ + { + name: 'enum1', + }, + { name: 'enum2' }, + ], + name: { name: 'EnumType', namespace: 'test.namespace' }, + specLocation: '', + }; + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'instance_of', + type: { + name: 'EnumType', + namespace: 'test.namespace', + }, + }, + ], + }, + }); + const requestType = { ...mockRequestType, query: [unionProperty] }; + const schema: SpecificationTypes.Model = { ...mockSchema, types: [enumType] }; + const urlParams = generateQueryParams(requestType, schema); + expect(urlParams).toEqual({ + unionProperty: ['enum1', 'enum2'], + }); + }); + + it('removes empty string from the array', () => { + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'instance_of', + type: { + name: 'string', + namespace: '_builtins', + }, + }, + ], + }, + }); + const requestType = { ...mockRequestType, query: [unionProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + unionProperty: [], + }); + }); + + it('if one item is a boolean and others are empty, converts to a flag', () => { + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'instance_of', + type: { + name: 'string', + namespace: '_builtins', + }, + }, + { + kind: 'instance_of', + type: { + name: 'number', + namespace: '_builtins', + }, + }, + { + kind: 'instance_of', + type: { + name: 'boolean', + namespace: '_builtins', + }, + }, + ], + }, + }); + const requestType = { ...mockRequestType, query: [unionProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + unionProperty: '__flag__', + }); + }); + + it('if one item is an unknown type, converts it to an empty string', () => { + const unionProperty = getMockProperty({ + propertyName: 'unionProperty', + type: { + kind: 'union_of', + items: [ + { + kind: 'literal_value', + value: 'test', + }, + { + kind: 'instance_of', + type: { + name: 'UnknownType', + namespace: 'test.namespace', + }, + }, + ], + }, + }); + + const requestType = { ...mockRequestType, query: [unionProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + // check that no `undefined` values are added + const value = urlParams.unionProperty as UrlParamValue[]; + expect(value.length).toEqual(1); + }); + }); + + it('converts an unknown type to an empty string', () => { + const unknownTypeProperty = getMockProperty({ + propertyName: 'unknownTypeProperty', + type: { + kind: 'instance_of', + type: { + name: 'UnknownType', + namespace: 'test.namespace', + }, + }, + }); + + const requestType = { ...mockRequestType, query: [unknownTypeProperty] }; + const urlParams = generateQueryParams(requestType, mockSchema); + expect(urlParams).toEqual({ + unknownTypeProperty: '', + }); + }); +}); diff --git a/packages/kbn-generate-console-definitions/src/generate_query_params.ts b/packages/kbn-generate-console-definitions/src/generate_query_params.ts new file mode 100644 index 0000000000000..5310e85d68936 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/generate_query_params.ts @@ -0,0 +1,219 @@ +/* + * 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. + */ + +/** + * Types that are important for query params conversion: + * TypeDefinition = Interface | Request | Response | Enum | TypeAlias + * ValueOf = InstanceOf | ArrayOf | UnionOf | DictionaryOf | UserDefinedValue | LiteralValue; + * + * Conversion steps: + * 1. The schema has a property `endpoints` which is "Endpoint[]" + * 2. Each "Endpoint" has a property `request` which is "TypeName" + * 3. Using "TypeName" we find the "TypeDefinition" in the property `types` of the schema + * 4. the "TypeDefinition" is cast to "Request" + * - "Request" has a property `query` which is "Property[]" + * - "Request" has a property `attachedBehaviours` which is "string[]" + * With "string" we find a "TypeDefinition" that is "Interface" + * This "Interface" has a property `properties` which is "Property[]" + * 5. Each "Property" (from both `query` and `attachedBehaviours`) now can be converted + * 6. Each "Property" has a property `type` that is "ValueOf" + * 7. If "ValueOf" can be one of "InstanceOf", "ArrayOf", "UnionOf", "DictionaryOf", "UserDefinedValue", "LiteralValue" + * - "InstanceOf": it has a property `type` which is a "TypeName" + * - if "TypeName" has a `namespace` = "_builtins" then it's a primitive type like "string" -> convert according to set rules for primitives + * - if "TypeName" has a `namespace` = "_types" then it's a defined type that can be found in the schema + * - the found "TypeDefinition" can be either "Enum" or "TypeAlias" (not "Interface", "Request" or "Response") + * - if it's "TypeAlias", it has a property `type` which is "ValueOf" -> handle it as "ValueOf" (recursion) + * - if it's "Enum", it has a property `members` which is "EnumMember[]" -> convert each "EnumMember" (only need `name` property) + * - "ArrayOf": it has a property `value` which is "ValueOf" -> convert as "ValueOf" + * - "UnionOf": it has a property `items` which is "ValueOf[]" -> convert each as "ValueOf" + * - "DictionaryOf": not used for query params + * - "UserDefinedValue": not used for query params + * - "LiteralValue": it has `value` that is `string`, `number` or `boolean` + * + * Autocomplete definitions currently work with 2 url param types: + * - "__flag__" for a boolean (suggesting value 'true' and 'false') + * - list of options in an array, for example ['30s', '-1', '0'], suggesting all 3 values in a list + * If there is only a default value, we need to wrap it in an array, so that this value is displayed in a suggestion (similar to the list). + * Numbers need to be converted to strings, otherwise they are not displayed as suggestions. + * + */ + +import { UrlParamValue } from './types/autocomplete_definition_types'; +import type { AutocompleteUrlParams, SpecificationTypes } from './types'; +import { findTypeDefinition } from './utils'; + +const booleanFlagString = '__flag__'; +const trueValueString = String(true); +const falseValueString = String(false); + +export const generateQueryParams = ( + requestType: SpecificationTypes.Request, + schema: SpecificationTypes.Model +): AutocompleteUrlParams => { + let urlParams = {} as AutocompleteUrlParams; + const { types } = schema; + const { attachedBehaviors, query } = requestType; + // if there are any attached behaviors, iterate over each and find its type + if (attachedBehaviors) { + for (const attachedBehavior of attachedBehaviors) { + const foundBehavior = types.find((type) => type.name.name === attachedBehavior); + if (foundBehavior) { + // attached behaviours are interfaces + const behaviorType = foundBehavior as SpecificationTypes.Interface; + // if there are any properties in the behavior, iterate over each and add it to url params + const { properties } = behaviorType; + urlParams = convertProperties(properties, urlParams, schema); + } + } + } + + // iterate over properties in query and add it to url params + urlParams = convertProperties(query, urlParams, schema); + + return urlParams; +}; + +const convertProperties = ( + properties: SpecificationTypes.Property[], + urlParams: AutocompleteUrlParams, + schema: SpecificationTypes.Model +): AutocompleteUrlParams => { + for (const property of properties) { + const { name, serverDefault, type } = property; + // property has `type` which is `ValueOf` + const convertedValue = convertValueOf(type, serverDefault, schema); + urlParams[name] = convertedValue ?? ''; + } + return urlParams; +}; + +const convertValueOf = ( + valueOf: SpecificationTypes.ValueOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { kind } = valueOf; + if (kind === 'instance_of') { + return convertInstanceOf(valueOf, serverDefault, schema); + } else if (kind === 'array_of') { + return convertArrayOf(valueOf, serverDefault, schema); + } else if (kind === 'union_of') { + return convertUnionOf(valueOf, serverDefault, schema); + } else if (kind === 'literal_value') { + return convertLiteralValue(valueOf); + } + // for query params we can ignore 'dictionary_of' and 'user_defined_value' + return ''; +}; + +const convertInstanceOf = ( + type: SpecificationTypes.InstanceOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { type: typeName } = type; + const { name: propertyName, namespace } = typeName; + if (namespace === '_builtins') { + /** + * - `string` + * - `boolean` + * - `number` + * - `null` // ignore for query params + * - `void` // ignore for query params + * - `binary` // ignore for query params + */ + + if (propertyName === 'boolean') { + // boolean is converted to a flag param + return booleanFlagString; + } else { + // if default value, convert to string and put in an array + return serverDefault ? [serverDefault.toString()] : ''; + } + } else { + // if it's a defined type, try to convert it + const definedType = findTypeDefinition(schema, typeName); + if (definedType) { + // TypeDefinition can only be Enum or TypeAlias + if (definedType.kind === 'enum') { + return convertEnum(definedType as SpecificationTypes.Enum); + } else if (definedType.kind === 'type_alias') { + const aliasValueOf = definedType.type; + return convertValueOf(aliasValueOf, serverDefault, schema); + } + } + } + return ''; +}; + +const convertArrayOf = ( + type: SpecificationTypes.ArrayOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { value } = type; + // simply convert the value of an array item + return convertValueOf(value, serverDefault, schema); +}; + +const convertUnionOf = ( + type: SpecificationTypes.UnionOf, + serverDefault: SpecificationTypes.Property['serverDefault'], + schema: SpecificationTypes.Model +): UrlParamValue | undefined => { + const { items } = type; + const itemValues = new Set(); + for (const item of items) { + // each item is ValueOf + const convertedValue = convertValueOf(item, serverDefault, schema); + // flatten array if needed + if (convertedValue instanceof Array) { + convertedValue.forEach((v) => itemValues.add(v)); + } else itemValues.add(convertedValue); + } + + // if an empty string is in values, delete it + if (itemValues.has('')) { + itemValues.delete(''); + } + + // if there is a flag in the values, convert it to "true" + "false" + if (itemValues.size > 1 && itemValues.has(booleanFlagString)) { + itemValues.delete(booleanFlagString); + itemValues.add(trueValueString); + itemValues.add(falseValueString); + } + + // if only 2 values ("true","false"), convert back to a flag + // that can happen if the values before were ("true", "__flag__") or ("false", "__flag__") + if ( + itemValues.size === 2 && + itemValues.has(trueValueString) && + itemValues.has(falseValueString) + ) { + itemValues.clear(); + itemValues.add(booleanFlagString); + } + + // if only 1 element that is a flag, don't put it in an array + if (itemValues.size === 1 && itemValues.has(booleanFlagString)) { + return itemValues.values().next().value; + } + return [...itemValues] as UrlParamValue; +}; + +const convertLiteralValue = (type: SpecificationTypes.LiteralValue): UrlParamValue | undefined => { + // convert the value to a string + return [type.value.toString()]; +}; + +const convertEnum = (enumDefinition: SpecificationTypes.Enum): UrlParamValue => { + const { members } = enumDefinition; + // only need the `name` property + return members.map((member) => member.name); +}; diff --git a/packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.ts b/packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.ts new file mode 100644 index 0000000000000..edbb9bd74d9a8 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/types/autocomplete_definition_types.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. + */ +export type UrlParamValue = number | string | number[] | string[] | boolean; +export interface AutocompleteUrlParams { + [key: string]: UrlParamValue; +} + +export interface AutocompleteBodyParams { + [key: string]: number | string; +} + +export interface AutocompleteDefinition { + documentation?: string; + methods?: string[]; + patterns?: string[]; + url_params?: AutocompleteUrlParams; + data_autocomplete_rules?: AutocompleteBodyParams; +} diff --git a/packages/kbn-generate-console-definitions/src/types/index.ts b/packages/kbn-generate-console-definitions/src/types/index.ts new file mode 100644 index 0000000000000..a182592350681 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/types/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 type { + AutocompleteDefinition, + AutocompleteUrlParams, + AutocompleteBodyParams, +} from './autocomplete_definition_types'; + +export * as SpecificationTypes from './specification_types'; diff --git a/packages/kbn-generate-console-definitions/src/types/specification_types.ts b/packages/kbn-generate-console-definitions/src/types/specification_types.ts new file mode 100644 index 0000000000000..b9e61ded06448 --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/types/specification_types.ts @@ -0,0 +1,442 @@ +/* + * 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. + */ + +/** + * --------------- THIS FILE IS COPIED FROM ES SPECIFICATION REPO ------------------- + * + */ + +/** + * The name of a type, composed of a simple name and a namespace. Hierarchical namespace elements are separated by + * a dot, e.g 'cat.cat_aliases'. + * + * Builtin namespaces: + * - "generic" for type names that are generic parameter values from the enclosing type. + * - "internal" for primitive and builtin types (e.g. Id, IndexName, etc) + * Builtin types: + * - boolean, + * - string, + * - number: a 64bits floating point number. Additional types will be added for integers. + * - null: the null value. Since JS distinguishes undefined and null, some APIs make use of this value. + * - object: used to represent "any". We may forbid it at some point. UserDefinedValue should be used for user data. + */ +export interface TypeName { + namespace: string; + name: string; +} + +// ------------------------------------------------------------------------------------------------ +// Value types + +// Note: "required" is part of Property. This means we can have optional properties but we can't have null entries in +// containers (array and dictionary), which doesn't seem to be needed. +// +// The 'kind' property is used to tag and disambiguate union type members, and allow type-safe pattern matching in TS: +// see https://blog.logrocket.com/pattern-matching-and-type-safety-in-typescript-1da1231a2e34/ +// and https://medium.com/@fillopeter/pattern-matching-with-typescript-done-right-94049ddd671c + +/** + * Type of a value. Used both for property types and nested type definitions. + */ +export type ValueOf = + | InstanceOf + | ArrayOf + | UnionOf + | DictionaryOf + | UserDefinedValue + | LiteralValue; + +/** + * A single value + */ +export interface InstanceOf { + kind: 'instance_of'; + type: TypeName; + /** generic parameters: either concrete types or open parameters from the enclosing type */ + generics?: ValueOf[]; +} + +/** + * An array + */ +export interface ArrayOf { + kind: 'array_of'; + value: ValueOf; +} + +/** + * One of several possible types which don't necessarily have a common superinterface + */ +export interface UnionOf { + kind: 'union_of'; + items: ValueOf[]; +} + +/** + * A dictionary (or map). The key is a string or a number (or a union thereof), possibly through an alias. + * + * If `singleKey` is true, then this dictionary can only have a single key. This is a common pattern in ES APIs, + * used to associate a value to a field name or some other identifier. + */ +export interface DictionaryOf { + kind: 'dictionary_of'; + key: ValueOf; + value: ValueOf; + singleKey: boolean; +} + +/** + * A user defined value. To be used when bubbling a generic parameter up to the top-level interface is + * inconvenient or impossible (e.g. for lists of user-defined values of possibly different types). + * + * Clients will allow providing a serializer/deserializer when reading/writing properties of this type, + * and should also accept raw json. + * + * Think twice before using this as it defeats the purpose of a strongly typed API, and deserialization + * will also require to buffer raw JSON data which may have performance implications. + */ +export interface UserDefinedValue { + kind: 'user_defined_value'; +} + +/** + * A literal value. This is used for tagged unions, where each type member of a union has a 'type' + * attribute that defines its kind. This metamodel heavily uses this approach with its 'kind' attributes. + * + * It may later be used to set a property to a constant value, which is why it accepts not only strings but also + * other primitive types. + */ +export interface LiteralValue { + kind: 'literal_value'; + value: string | number | boolean; +} + +/** + * An interface or request interface property. + */ +export interface Property { + name: string; + type: ValueOf; + required: boolean; + description?: string; + docUrl?: string; + docId?: string; + since?: string; + serverDefault?: boolean | string | number | string[] | number[]; + deprecation?: Deprecation; + availability?: Availabilities; + stability?: Stability; + /** + * If specified takes precedence over `name` when generating code. `name` is always the value + * to be sent over the wire + */ + codegenName?: string; + /** An optional set of aliases for `name` */ + aliases?: string[]; + /** If the enclosing interface is a variants container, is this a property of the container and not a variant? */ + containerProperty?: boolean; + /** If this property has a quirk that needs special attention, give a short explanation about it */ + esQuirk?: string; +} + +// ------------------------------------------------------------------------------------------------ +// Type definitions + +export type TypeDefinition = Interface | Request | Response | Enum | TypeAlias; + +// ------------------------------------------------------------------------------------------------ + +/** + * Common attributes for all type definitions + */ +export interface BaseType { + name: TypeName; + description?: string; + /** Link to public documentation */ + docUrl?: string; + docId?: string; + deprecation?: Deprecation; + /** If this endpoint has a quirk that needs special attention, give a short explanation about it */ + esQuirk?: string; + kind: string; + /** Variant name for externally tagged variants */ + variantName?: string; + /** + * Additional identifiers for use by code generators. Usage depends on the actual type: + * - on unions (modeled as alias(union_of)), these are identifiers for the union members + * - for additional properties, this is the name of the dict that holds these properties + * - for additional property, this is the name of the key and value fields that hold the + * additional property + */ + codegenNames?: string[]; + /** + * Location of an item. The path is relative to the "specification" directory, e.g "_types/common.ts#L1-L2" + */ + specLocation: string; +} + +export type Variants = ExternalTag | InternalTag | Container; + +export interface VariantBase { + /** + * Is this variant type open to extensions? Default to false. Used for variants that can + * be extended with plugins. If true, target clients should allow for additional variants + * with a variant tag outside the ones defined in the spec and arbitrary data as the value. + */ + nonExhaustive?: boolean; +} + +export interface ExternalTag extends VariantBase { + kind: 'external_tag'; +} + +export interface InternalTag extends VariantBase { + kind: 'internal_tag'; + /* Name of the property that holds the variant tag */ + tag: string; + /* Default value for the variant tag if it's missing */ + defaultTag?: string; +} + +export interface Container extends VariantBase { + kind: 'container'; +} + +/** + * Inherits clause (aka extends or implements) for an interface or request + */ +export interface Inherits { + type: TypeName; + generics?: ValueOf[]; +} + +/** + * An interface type + */ +export interface Interface extends BaseType { + kind: 'interface'; + /** + * Open generic parameters. The name is that of the parameter, the namespace is an arbitrary value that allows + * this fully qualified type name to be used when this open generic parameter is used in property's type. + */ + generics?: TypeName[]; + inherits?: Inherits; + implements?: Inherits[]; + + /** + * Behaviors directly implemented by this interface + */ + behaviors?: Inherits[]; + + /** + * Behaviors attached to this interface, coming from the interface itself (see `behaviors`) + * or from inherits and implements ancestors + */ + attachedBehaviors?: string[]; + properties: Property[]; + /** + * The property that can be used as a shortcut for the entire data structure in the JSON. + */ + shortcutProperty?: string; + + /** Identify containers */ + variants?: Container; +} + +/** + * A request type + */ +export interface Request extends BaseType { + // Note: does not extend Interface as properties are split across path, query and body + kind: 'request'; + generics?: TypeName[]; + /** The parent defines additional body properties that are added to the body, that has to be a PropertyBody */ + inherits?: Inherits; + implements?: Inherits[]; + /** URL path properties */ + path: Property[]; + /** Query string properties */ + query: Property[]; + // FIXME: we need an annotation that lists query params replaced by a body property so that we can skip them. + // Examples on _search: sort -> sort, _source -> (_source, _source_include, _source_exclude) + // Or can we say that implicitly a body property replaces all path params starting with its name? + // Is there a priority rule between path and body parameters? + // + // We can also pull path parameter descriptions on body properties they replace + + /** + * Body type. Most often a list of properties (that can extend those of the inherited interface, see above), except for a + * few specific cases that use other types such as bulk (array) or create (generic parameter). Or NoBody for requests + * that don't have a body. + */ + body: Body; + behaviors?: Inherits[]; + attachedBehaviors?: string[]; +} + +/** + * A response type + */ +export interface Response extends BaseType { + kind: 'response'; + generics?: TypeName[]; + body: Body; + behaviors?: Inherits[]; + attachedBehaviors?: string[]; + exceptions?: ResponseException[]; +} + +export interface ResponseException { + description?: string; + body: Body; + statusCodes: number[]; +} + +export type Body = ValueBody | PropertiesBody | NoBody; + +export interface ValueBody { + kind: 'value'; + value: ValueOf; + codegenName?: string; +} + +export interface PropertiesBody { + kind: 'properties'; + properties: Property[]; +} + +export interface NoBody { + kind: 'no_body'; +} + +/** + * An enumeration member. + * + * When enumeration members can become ambiguous when translated to an identifier, the `name` property will be a good + * identifier name, and `stringValue` will be the string value to use on the wire. + * See DateMathTimeUnit for an example of this, which have members for "m" (minute) and "M" (month). + */ +export interface EnumMember { + /** The identifier to use for this enum */ + name: string; + /** An optional set of aliases for `name` */ + aliases?: string[]; + /** + * If specified takes precedence over `name` when generating code. `name` is always the value + * to be sent over the wire + */ + codegenName?: string; + description?: string; + deprecation?: Deprecation; + since?: string; +} + +/** + * An enumeration + */ +export interface Enum extends BaseType { + kind: 'enum'; + /** + * If the enum is open, it means that other than the specified values it can accept an arbitrary value. + * If this property is not present, it means that the enum is not open (in other words, is closed). + */ + isOpen?: boolean; + members: EnumMember[]; +} + +/** + * An alias for an existing type. + */ +export interface TypeAlias extends BaseType { + kind: 'type_alias'; + type: ValueOf; + /** generic parameters: either concrete types or open parameters from the enclosing type */ + generics?: TypeName[]; + /** Only applicable to `union_of` aliases: identify typed_key unions (external) and variant inventories (internal) */ + variants?: InternalTag | ExternalTag; +} + +// ------------------------------------------------------------------------------------------------ + +export enum Stability { + stable = 'stable', + beta = 'beta', + experimental = 'experimental', +} +export enum Visibility { + public = 'public', + feature_flag = 'feature_flag', + private = 'private', +} + +export interface Deprecation { + version: string; + description: string; +} + +export interface Availabilities { + stack?: Availability; + serverless?: Availability; +} + +export interface Availability { + since?: string; + featureFlag?: string; + stability?: Stability; + visibility?: Visibility; +} + +export interface Endpoint { + name: string; + description: string; + docUrl: string; + docId?: string; + deprecation?: Deprecation; + availability: Availabilities; + + /** + * If the request value is `null` it means that there is not yet a + * request type definition for this endpoint. + */ + request: TypeName | null; + requestBodyRequired: boolean; // Not sure this is useful + + /** + * If the response value is `null` it means that there is not yet a + * response type definition for this endpoint. + */ + response: TypeName | null; + + urls: UrlTemplate[]; + + /** + * The version when this endpoint reached its current stability level. + * Missing data means "forever", i.e. before any of the target client versions produced from this spec. + */ + since?: string; + stability?: Stability; + visibility?: Visibility; + featureFlag?: string; + requestMediaType?: string[]; + responseMediaType?: string[]; + privileges?: { + index?: string[]; + cluster?: string[]; + }; +} + +export interface UrlTemplate { + path: string; + methods: string[]; + deprecation?: Deprecation; +} + +export interface Model { + types: TypeDefinition[]; + endpoints: Endpoint[]; +} diff --git a/packages/kbn-generate-console-definitions/src/utils.ts b/packages/kbn-generate-console-definitions/src/utils.ts new file mode 100644 index 0000000000000..29c24e63fa58f --- /dev/null +++ b/packages/kbn-generate-console-definitions/src/utils.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 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 { SpecificationTypes } from './types'; +export const findTypeDefinition = ( + schema: SpecificationTypes.Model, + typeName: SpecificationTypes.TypeName +): SpecificationTypes.TypeDefinition | undefined => { + return schema.types.find( + (type) => type.name.name === typeName.name && type.name.namespace === typeName.namespace + ); +}; From f758ba47507fb3ec18ffbaeab32ff36ea828dd2c Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 5 Jul 2023 12:39:58 +0200 Subject: [PATCH 35/64] Use alert details page URL for the log threshold rule if the config is enabled (#161175) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #161117 ## Summary If `xpack.observability.unsafe.alertDetails.logs.enabled` is enabled, we will use the new alert details page URL in `context.alertDetailsUrl` otherwise, we send the user to the alerts page filtered for that alert. (Partially brings back [the logic for alert details URL](https://github.com/elastic/kibana/pull/157987/files#diff-a71ca536380c1fde8805744b23566ce795707f92b94a03af73347cac46ccac63L1027) and [getAlertDetailsConfig](https://github.com/elastic/kibana/pull/157987/files#diff-a71ca536380c1fde8805744b23566ce795707f92b94a03af73347cac46ccac63L1027)) ## 🧪 How to test 1. Set `xpack.observability.unsafe.alertDetails.logs.enabled` as false in Kibana yml config or remove the config 2. Create a log threshold rule with an action for both active state and recovered state 3. When the alert is triggered, check the default message, it should include the alertDetailsURL, by clicking on that, you should land on the alerts page filtered for that alert 4. Make the alert recovered and check and similar URL should be generated New alert details page: 1. Set `xpack.observability.unsafe.alertDetails.logs.enabled` as true in Kibana yml config 2. Repeat the steps 2,3,4 as mentioned before 3. This time, you should land on the new alert details page ![image](https://github.com/elastic/kibana/assets/12370520/a2f99bd7-cfaa-4146-bedf-72458973b463) --- .../infra/server/lib/alerting/common/utils.ts | 10 +++++ .../log_threshold/log_threshold_executor.ts | 43 ++++++++++++------- .../plugins/infra/server/lib/infra_types.ts | 2 + x-pack/plugins/infra/server/plugin.ts | 1 + 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts index 8377756654a9e..dc518e1e08cf7 100644 --- a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts +++ b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts @@ -9,6 +9,7 @@ import { isEmpty, isError } from 'lodash'; import { schema } from '@kbn/config-schema'; import { Logger, LogMeta } from '@kbn/logging'; import type { ElasticsearchClient, IBasePath } from '@kbn/core/server'; +import { ObservabilityConfig } from '@kbn/observability-plugin/server'; import { addSpaceIdToPath } from '@kbn/spaces-plugin/common'; import { ALERT_RULE_PARAMETERS, TIMESTAMP } from '@kbn/rule-data-utils'; import { @@ -109,6 +110,15 @@ export const createScopedLogger = ( }; }; +export const getAlertDetailsPageEnabledForApp = ( + config: ObservabilityConfig['unsafe']['alertDetails'] | null, + appName: keyof ObservabilityConfig['unsafe']['alertDetails'] +): boolean => { + if (!config) return false; + + return config[appName].enabled; +}; + export const getViewInInventoryAppUrl = ({ basePath, criteria, diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index 9b93e021ae8f1..e36ae54746b3d 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -7,7 +7,11 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { i18n } from '@kbn/i18n'; -import { getAlertUrl, AlertsLocatorParams } from '@kbn/observability-plugin/common'; +import { + AlertsLocatorParams, + getAlertDetailsUrl, + getAlertUrl, +} from '@kbn/observability-plugin/common'; import { ALERT_CONTEXT, ALERT_EVALUATION_THRESHOLD, @@ -59,6 +63,7 @@ import { InfraBackendLibs } from '../../infra_types'; import { AdditionalContext, flattenAdditionalContext, + getAlertDetailsPageEnabledForApp, getContextForRecoveredAlerts, getGroupByObject, unflattenObject, @@ -133,6 +138,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => getAlertByAlertUuid, } = services; const { basePath, alertsLocator } = libs; + const config = libs.getAlertDetailsConfig(); const alertFactory: LogThresholdAlertFactory = ( id, @@ -183,13 +189,15 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => alert.scheduleActions(actionGroup, { ...sharedContext, ...context, - alertDetailsUrl: await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - libs.alertsLocator, - libs.basePath.publicBaseUrl - ), + alertDetailsUrl: getAlertDetailsPageEnabledForApp(config, 'logs') + ? getAlertDetailsUrl(libs.basePath, spaceId, alertUuid) + : await getAlertUrl( + alertUuid, + spaceId, + indexedStartedAt, + libs.alertsLocator, + libs.basePath.publicBaseUrl + ), }); }); } @@ -246,6 +254,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => validatedParams, getAlertByAlertUuid, alertsLocator, + isAlertDetailsPageEnabled: getAlertDetailsPageEnabledForApp(config, 'logs'), }); } catch (e) { throw new Error(e); @@ -859,6 +868,7 @@ const processRecoveredAlerts = async ({ validatedParams, getAlertByAlertUuid, alertsLocator, + isAlertDetailsPageEnabled = false, }: { basePath: IBasePath; getAlertStartedDate: (alertId: string) => string | null; @@ -871,6 +881,7 @@ const processRecoveredAlerts = async ({ alertUuid: string ) => Promise | null> | null; alertsLocator?: LocatorPublic; + isAlertDetailsPageEnabled?: boolean; }) => { const groupByKeysObjectForRecovered = getGroupByObject( validatedParams.groupBy, @@ -887,13 +898,15 @@ const processRecoveredAlerts = async ({ const viewInAppUrl = addSpaceIdToPath(basePath.publicBaseUrl, spaceId, relativeViewInAppUrl); const baseContext = { - alertDetailsUrl: await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ), + alertDetailsUrl: isAlertDetailsPageEnabled + ? getAlertDetailsUrl(basePath, spaceId, alertUuid) + : await getAlertUrl( + alertUuid, + spaceId, + indexedStartedAt, + alertsLocator, + basePath.publicBaseUrl + ), group: hasGroupBy(validatedParams) ? recoveredAlertId : null, groupByKeys: groupByKeysObjectForRecovered[recoveredAlertId], timestamp: startedAt.toISOString(), diff --git a/x-pack/plugins/infra/server/lib/infra_types.ts b/x-pack/plugins/infra/server/lib/infra_types.ts index e31bad1b5ffeb..6bb24c722fe81 100644 --- a/x-pack/plugins/infra/server/lib/infra_types.ts +++ b/x-pack/plugins/infra/server/lib/infra_types.ts @@ -9,6 +9,7 @@ import type { Logger } from '@kbn/logging'; import type { IBasePath } from '@kbn/core/server'; import type { handleEsError } from '@kbn/es-ui-shared-plugin/server'; import type { AlertsLocatorParams } from '@kbn/observability-plugin/common'; +import { ObservabilityConfig } from '@kbn/observability-plugin/server'; import type { LocatorPublic } from '@kbn/share-plugin/common'; import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server'; import { RulesServiceSetup } from '../services/rules'; @@ -33,6 +34,7 @@ export interface InfraBackendLibs extends InfraDomainLibs { metricsRules: RulesServiceSetup; sources: InfraSources; sourceStatus: InfraSourceStatus; + getAlertDetailsConfig: () => ObservabilityConfig['unsafe']['alertDetails']; getStartServices: InfraPluginStartServicesAccessor; handleEsError: typeof handleEsError; logger: Logger; diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index 2449293dfa3aa..07bafb4781e70 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -193,6 +193,7 @@ export class InfraServerPlugin logsRules: this.logsRules.setup(core, plugins), metricsRules: this.metricsRules.setup(core, plugins), getStartServices: () => core.getStartServices(), + getAlertDetailsConfig: () => plugins.observability.getAlertDetailsConfig(), logger: this.logger, basePath: core.http.basePath, alertsLocator: plugins.share.url.locators.get(alertsLocatorID), From 16528cf28994b30642262a018c89c5217c28f884 Mon Sep 17 00:00:00 2001 From: Wafaa Nasr Date: Wed, 5 Jul 2023 11:44:03 +0100 Subject: [PATCH 36/64] [Security Solution] [Exceptions] Amend `Rule Exception's Comment` text (#161092) ## Summary - Addresses Docs team comment https://github.com/elastic/kibana/pull/159908#discussion_r1247964658 --- .../e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts | 4 ++-- .../components/add_exception_flyout/translations.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts index 59af4592d2ebe..0861bf1231e28 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions.cy.ts @@ -169,7 +169,7 @@ describe('Rule Exceptions workflows from Alert', () => { */ validateExceptionCommentCountAndText( 1, - 'Exception conditions are pre-filled with relevant data from alert with "id"' + 'Exception conditions are pre-filled with relevant data from an alert with the alert id (_id):' ); addExceptionFlyoutItemName(ITEM_NAME); @@ -207,7 +207,7 @@ describe('Rule Exceptions workflows from Alert', () => { */ validateExceptionCommentCountAndText( 1, - 'Exception conditions are pre-filled with relevant data from alert with "id"' + 'Exception conditions are pre-filled with relevant data from an alert with the alert id (_id):' ); addExceptionFlyoutItemName(ITEM_NAME); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts index 215bb3fc29923..d27d7994bb375 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/translations.ts @@ -90,6 +90,6 @@ export const ADD_RULE_EXCEPTION_FROM_ALERT_COMMENT = (alertId: string) => { values: { alertId }, defaultMessage: - 'Exception conditions are pre-filled with relevant data from alert with "id" {alertId}.', + 'Exception conditions are pre-filled with relevant data from an alert with the alert id (_id): {alertId}.', } ); From f43601d294a3d789c0aa40892c80e9e40859cab6 Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 5 Jul 2023 13:33:09 +0200 Subject: [PATCH 37/64] [Cases] Validate page and perPage parameters in find APIs (#161111) Connected to https://github.com/elastic/kibana/issues/146945 ## Summary | Description | Limit | Done? | Documented? | ------------- | ---- | :---: | ---- | | Total number of cases/user actions/comments per page | 100 | :white_check_mark: | No | N/A | | Maximum number of cases/user actions/comments returned from the API | 10.000 | :white_check_mark: | No | N/A | ### 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] [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 ### Release Notes Max value for perPage parameter in find Cases API is now 100. Max value for perPage parameter in find User Actions API is now 100. Max value for perPage parameter in find Comments API is now 100. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: lcawl --- .../cases/case-apis-passthru.asciidoc | 17 +- x-pack/plugins/cases/common/api/cases/case.ts | 218 +++++++++--------- .../cases/common/api/cases/comment/index.ts | 32 ++- .../api/cases/user_actions/operations/find.ts | 20 +- .../plugins/cases/common/constants/index.ts | 2 + .../plugins/cases/common/schema/index.test.ts | 164 +++++++++++-- x-pack/plugins/cases/common/schema/index.ts | 42 ++++ x-pack/plugins/cases/common/schema/types.ts | 20 ++ .../plugins/cases/docs/openapi/bundled.json | 45 ++-- .../plugins/cases/docs/openapi/bundled.yaml | 24 +- .../components/parameters/page_size.yaml | 3 +- ...id}@api@cases@{caseid}@comments@_find.yaml | 9 +- .../server/client/attachments/get.test.ts | 6 +- .../cases/server/client/attachments/get.ts | 3 - .../client/attachments/validators.test.ts | 52 ----- .../server/client/attachments/validators.ts | 24 +- .../cases/server/client/cases/find.test.ts | 23 +- .../server/client/user_actions/find.test.ts | 41 +++- .../tests/common/cases/find_cases.ts | 79 ++++--- .../tests/common/comments/find_comments.ts | 4 +- .../common/user_actions/find_user_actions.ts | 19 ++ 21 files changed, 505 insertions(+), 342 deletions(-) create mode 100644 x-pack/plugins/cases/common/schema/types.ts delete mode 100644 x-pack/plugins/cases/server/client/attachments/validators.test.ts diff --git a/docs/api-generated/cases/case-apis-passthru.asciidoc b/docs/api-generated/cases/case-apis-passthru.asciidoc index f35863d23eb88..8970186559032 100644 --- a/docs/api-generated/cases/case-apis-passthru.asciidoc +++ b/docs/api-generated/cases/case-apis-passthru.asciidoc @@ -859,7 +859,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
sortOrder (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
sortOrder (optional)
Query Parameter — Determines the sort order. default: desc
types (optional)
@@ -951,7 +951,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
sortOrder (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
sortOrder (optional)
Query Parameter — Determines the sort order. default: desc
types (optional)
@@ -1278,7 +1278,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
reporters (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
reporters (optional)
Query Parameter — Filters the returned cases by the user name of the reporter. default: null
search (optional)
@@ -1471,7 +1471,7 @@ Any modifications made to this file will be overwritten.
Query Parameter — The page number to return. default: 1
perPage (optional)
-
Query Parameter — The number of items to return. default: 20
reporters (optional)
+
Query Parameter — The number of items to return. Limited to 100 items. default: 20
reporters (optional)
Query Parameter — Filters the returned cases by the user name of the reporter. default: null
search (optional)
@@ -4156,7 +4156,6 @@ Any modifications made to this file will be overwritten.
  • findCaseConnectorsDefaultSpace_200_response_inner_config -
  • findCasesDefaultSpace_200_response -
  • findCasesDefaultSpace_assignees_parameter -
  • -
  • findCasesDefaultSpace_category_parameter -
  • findCasesDefaultSpace_owner_parameter -
  • findCasesDefaultSpace_searchFields_parameter -
  • getCaseCommentDefaultSpace_200_response -
  • @@ -4580,6 +4579,7 @@ Any modifications made to this file will be overwritten.
    settings
    severity (optional)
    tags
    array[String] The words and phrases that help categorize cases. It can be an empty array.
    +
    category (optional)
    String Category for the case. It could be a word or a phrase to categorize the case.
    title
    String A title for the case.

    @@ -4659,12 +4659,6 @@ Any modifications made to this file will be overwritten.
    -

    findCasesDefaultSpace_owner_parameter - Up

    @@ -5056,6 +5050,7 @@ Any modifications made to this file will be overwritten.
    severity (optional)
    status (optional)
    tags (optional)
    array[String] The words and phrases that help categorize cases.
    +
    category (optional)
    String Category for the case. It could be a word or a phrase to categorize the case.
    title (optional)
    String A title for the case.
    version
    String The current version of the case. To determine this value, use the get case or find cases APIs.
    diff --git a/x-pack/plugins/cases/common/api/cases/case.ts b/x-pack/plugins/cases/common/api/cases/case.ts index 9778195465432..ff6b8416f24dd 100644 --- a/x-pack/plugins/cases/common/api/cases/case.ts +++ b/x-pack/plugins/cases/common/api/cases/case.ts @@ -7,13 +7,17 @@ import * as rt from 'io-ts'; -import { NumberFromString } from '../saved_object'; import { UserRt } from '../user'; import { CommentRt } from './comment'; import { CasesStatusResponseRt, CaseStatusRt } from './status'; import { CaseConnectorRt } from '../connectors/connector'; import { CaseAssigneesRt } from './assignee'; -import { limitedArraySchema, limitedStringSchema, NonEmptyString } from '../../schema'; +import { + limitedArraySchema, + limitedStringSchema, + NonEmptyString, + paginationSchema, +} from '../../schema'; import { MAX_DELETE_IDS_LENGTH, MAX_DESCRIPTION_LENGTH, @@ -25,6 +29,7 @@ import { MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, MAX_BULK_GET_CASES, + MAX_CASES_PER_PAGE, } from '../../constants'; export const AttachmentTotalsRt = rt.strict({ @@ -227,110 +232,113 @@ const CasesFindRequestSearchFieldsRt = rt.keyof({ 'updated_by.profile_uid': null, }); -export const CasesFindRequestRt = rt.exact( - rt.partial({ - /** - * Tags to filter by - */ - tags: rt.union([ - limitedArraySchema({ - codec: rt.string, - fieldName: 'tags', - min: 0, - max: MAX_TAGS_FILTER_LENGTH, - }), - rt.string, - ]), - /** - * The status of the case (open, closed, in-progress) - */ - status: CaseStatusRt, - /** - * The severity of the case - */ - severity: CaseSeverityRt, - /** - * The uids of the user profiles to filter by - */ - assignees: rt.union([ - limitedArraySchema({ - codec: rt.string, - fieldName: 'assignees', - min: 0, - max: MAX_ASSIGNEES_FILTER_LENGTH, - }), - rt.string, - ]), - /** - * The reporters to filter by - */ - reporters: rt.union([ - limitedArraySchema({ - codec: rt.string, - fieldName: 'reporters', - min: 0, - max: MAX_REPORTERS_FILTER_LENGTH, - }), - rt.string, - ]), - /** - * Operator to use for the `search` field - */ - defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]), - /** - * A KQL date. If used all cases created after (gte) the from date will be returned - */ - from: rt.string, - /** - * The page of objects to return - */ - page: NumberFromString, - /** - * The number of objects to include in each page - */ - perPage: NumberFromString, - /** - * An Elasticsearch simple_query_string - */ - search: rt.string, - /** - * The fields to perform the simple_query_string parsed query against - */ - searchFields: rt.union([ - rt.array(CasesFindRequestSearchFieldsRt), - CasesFindRequestSearchFieldsRt, - ]), - /** - * The root fields to perform the simple_query_string parsed query against - */ - rootSearchFields: rt.array(rt.string), - /** - * The field to use for sorting the found objects. - * - */ - sortField: rt.string, - /** - * The order to sort by - */ - sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), +export const CasesFindRequestRt = rt.intersection([ + rt.exact( + rt.partial({ + /** + * Tags to filter by + */ + tags: rt.union([ + limitedArraySchema({ + codec: rt.string, + fieldName: 'tags', + min: 0, + max: MAX_TAGS_FILTER_LENGTH, + }), + rt.string, + ]), + /** + * The status of the case (open, closed, in-progress) + */ + status: CaseStatusRt, + /** + * The severity of the case + */ + severity: CaseSeverityRt, + /** + * The uids of the user profiles to filter by + */ + assignees: rt.union([ + limitedArraySchema({ + codec: rt.string, + fieldName: 'assignees', + min: 0, + max: MAX_ASSIGNEES_FILTER_LENGTH, + }), + rt.string, + ]), + /** + * The reporters to filter by + */ + reporters: rt.union([ + limitedArraySchema({ + codec: rt.string, + fieldName: 'reporters', + min: 0, + max: MAX_REPORTERS_FILTER_LENGTH, + }), + rt.string, + ]), + /** + * Operator to use for the `search` field + */ + defaultSearchOperator: rt.union([rt.literal('AND'), rt.literal('OR')]), + /** + * A KQL date. If used all cases created after (gte) the from date will be returned + */ + from: rt.string, + /** + * The page of objects to return + */ + // page: rt.union([rt.number, NumberFromString]), + /** + * The number of objects to include in each page + */ + // perPage: rt.union([rt.number, NumberFromString]), + /** + * An Elasticsearch simple_query_string + */ + search: rt.string, + /** + * The fields to perform the simple_query_string parsed query against + */ + searchFields: rt.union([ + rt.array(CasesFindRequestSearchFieldsRt), + CasesFindRequestSearchFieldsRt, + ]), + /** + * The root fields to perform the simple_query_string parsed query against + */ + rootSearchFields: rt.array(rt.string), + /** + * The field to use for sorting the found objects. + * + */ + sortField: rt.string, + /** + * The order to sort by + */ + sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), - /** - * A KQL date. If used all cases created before (lte) the to date will be returned. - */ - to: rt.string, - /** - * The owner(s) to filter by. The user making the request must have privileges to retrieve cases of that - * ownership or they will be ignored. If no owner is included, then all ownership types will be included in the response - * that the user has access to. - */ + /** + * A KQL date. If used all cases created before (lte) the to date will be returned. + */ + to: rt.string, + /** + * The owner(s) to filter by. The user making the request must have privileges to retrieve cases of that + * ownership or they will be ignored. If no owner is included, then all ownership types will be included in the response + * that the user has access to. + */ - owner: rt.union([rt.array(rt.string), rt.string]), - /** - * The category of the case. - */ - category: rt.union([rt.array(rt.string), rt.string]), - }) -); + owner: rt.union([rt.array(rt.string), rt.string]), + /** + * The category of the case. + */ + category: rt.union([rt.array(rt.string), rt.string]), + }) + ), + paginationSchema({ maxPerPage: MAX_CASES_PER_PAGE }), +]); export const CasesDeleteRequestRt = limitedArraySchema({ codec: NonEmptyString, @@ -532,8 +540,8 @@ export type Case = rt.TypeOf; export type CaseResolveResponse = rt.TypeOf; export type Cases = rt.TypeOf; export type CasesDeleteRequest = rt.TypeOf; -export type CasesFindRequest = rt.TypeOf; export type CasesByAlertIDRequest = rt.TypeOf; +export type CasesFindRequest = rt.TypeOf; export type CasesFindResponse = rt.TypeOf; export type CasePatchRequest = rt.TypeOf; export type CasesPatchRequest = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/api/cases/comment/index.ts b/x-pack/plugins/cases/common/api/cases/comment/index.ts index 1662631ae2b79..f53e7d8828930 100644 --- a/x-pack/plugins/cases/common/api/cases/comment/index.ts +++ b/x-pack/plugins/cases/common/api/cases/comment/index.ts @@ -6,10 +6,9 @@ */ import * as rt from 'io-ts'; -import { MAX_BULK_GET_ATTACHMENTS } from '../../../constants'; -import { limitedArraySchema } from '../../../schema'; +import { MAX_BULK_GET_ATTACHMENTS, MAX_COMMENTS_PER_PAGE } from '../../../constants'; +import { limitedArraySchema, paginationSchema } from '../../../schema'; import { jsonValueRt } from '../../runtime_types'; -import { NumberFromString } from '../../saved_object'; import { UserRt } from '../../user'; @@ -289,22 +288,17 @@ export const CommentsFindResponseRt = rt.strict({ export const CommentsRt = rt.array(CommentRt); -export const FindCommentsQueryParamsRt = rt.exact( - rt.partial({ - /** - * The page of objects to return - */ - page: rt.union([rt.number, NumberFromString]), - /** - * The number of objects to return for a page - */ - perPage: rt.union([rt.number, NumberFromString]), - /** - * Order to sort the response - */ - sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), - }) -); +export const FindCommentsQueryParamsRt = rt.intersection([ + rt.exact( + rt.partial({ + /** + * Order to sort the response + */ + sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), + }) + ), + paginationSchema({ maxPerPage: MAX_COMMENTS_PER_PAGE }), +]); export const BulkCreateCommentRequestRt = rt.array(CommentRequestRt); diff --git a/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts b/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts index 336c94a7a4fec..90dc408b5e886 100644 --- a/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts +++ b/x-pack/plugins/cases/common/api/cases/user_actions/operations/find.ts @@ -6,9 +6,10 @@ */ import * as rt from 'io-ts'; +import { MAX_USER_ACTIONS_PER_PAGE } from '../../../../constants'; import { UserActionsRt } from '../response'; import { ActionTypes } from '../common'; -import { NumberFromString } from '../../../saved_object'; +import { paginationSchema } from '../../../../schema'; const AdditionalFilterTypes = { action: 'action', @@ -26,14 +27,15 @@ const FindTypeFieldRt = rt.keyof(FindTypes); export type FindTypeField = rt.TypeOf; -export const UserActionFindRequestRt = rt.exact( - rt.partial({ - types: rt.array(FindTypeFieldRt), - sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), - page: NumberFromString, - perPage: NumberFromString, - }) -); +export const UserActionFindRequestRt = rt.intersection([ + rt.exact( + rt.partial({ + types: rt.array(FindTypeFieldRt), + sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), + }) + ), + paginationSchema({ maxPerPage: MAX_USER_ACTIONS_PER_PAGE }), +]); export type UserActionFindRequest = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index b7b4987042495..ffd627c8de865 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -105,6 +105,8 @@ export const MAX_BULK_GET_ATTACHMENTS = 100 as const; export const MAX_CONCURRENT_SEARCHES = 10 as const; export const MAX_BULK_GET_CASES = 1000 as const; export const MAX_COMMENTS_PER_PAGE = 100 as const; +export const MAX_CASES_PER_PAGE = 100 as const; +export const MAX_USER_ACTIONS_PER_PAGE = 100 as const; export const MAX_CATEGORY_FILTER_LENGTH = 100 as const; export const MAX_TAGS_FILTER_LENGTH = 100 as const; export const MAX_ASSIGNEES_FILTER_LENGTH = 100 as const; diff --git a/x-pack/plugins/cases/common/schema/index.test.ts b/x-pack/plugins/cases/common/schema/index.test.ts index 1a810c8003ff7..008cbc86cae80 100644 --- a/x-pack/plugins/cases/common/schema/index.test.ts +++ b/x-pack/plugins/cases/common/schema/index.test.ts @@ -7,7 +7,8 @@ import { PathReporter } from 'io-ts/lib/PathReporter'; -import { limitedArraySchema, limitedStringSchema, NonEmptyString } from '.'; +import { limitedArraySchema, limitedStringSchema, NonEmptyString, paginationSchema } from '.'; +import { MAX_DOCS_PER_PAGE } from '../constants'; describe('schema', () => { describe('limitedArraySchema', () => { @@ -19,10 +20,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode(['']) ) ).toMatchInlineSnapshot(` - Array [ - "string must have length >= 1", - ] - `); + Array [ + "string must have length >= 1", + ] + `); }); it('fails when given an empty array', () => { @@ -31,10 +32,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode([]) ) ).toMatchInlineSnapshot(` - Array [ - "The length of the field foobar is too short. Array must be of length >= 1.", - ] - `); + Array [ + "The length of the field foobar is too short. Array must be of length >= 1.", + ] + `); }); it('fails when given an array larger than the limit of one item', () => { @@ -46,10 +47,10 @@ describe('schema', () => { ]) ) ).toMatchInlineSnapshot(` - Array [ - "The length of the field foobar is too long. Array must be of length <= 1.", - ] - `); + Array [ + "The length of the field foobar is too long. Array must be of length <= 1.", + ] + `); }); it('succeeds when given an array of 1 item with a non-empty string', () => { @@ -58,10 +59,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 1, max: 1 }).decode(['a']) ) ).toMatchInlineSnapshot(` - Array [ - "No errors!", - ] - `); + Array [ + "No errors!", + ] + `); }); it('succeeds when given an array of 0 item with a non-empty string when the min is 0', () => { @@ -70,10 +71,10 @@ describe('schema', () => { limitedArraySchema({ codec: NonEmptyString, fieldName, min: 0, max: 2 }).decode([]) ) ).toMatchInlineSnapshot(` - Array [ - "No errors!", - ] - `); + Array [ + "No errors!", + ] + `); }); }); @@ -84,7 +85,7 @@ describe('schema', () => { expect(PathReporter.report(limitedStringSchema({ fieldName, min: 2, max: 1 }).decode('a'))) .toMatchInlineSnapshot(` Array [ - "The length of the ${fieldName} is too short. The minimum length is 2.", + "The length of the foo is too short. The minimum length is 2.", ] `); }); @@ -93,7 +94,7 @@ describe('schema', () => { expect(PathReporter.report(limitedStringSchema({ fieldName, min: 1, max: 1 }).decode(''))) .toMatchInlineSnapshot(` Array [ - "The ${fieldName} field cannot be an empty string.", + "The foo field cannot be an empty string.", ] `); }); @@ -102,7 +103,7 @@ describe('schema', () => { expect(PathReporter.report(limitedStringSchema({ fieldName, min: 1, max: 1 }).decode(' '))) .toMatchInlineSnapshot(` Array [ - "The ${fieldName} field cannot be an empty string.", + "The foo field cannot be an empty string.", ] `); }); @@ -114,7 +115,7 @@ describe('schema', () => { ) ).toMatchInlineSnapshot(` Array [ - "The length of the ${fieldName} is too long. The maximum length is 5.", + "The length of the foo is too long. The maximum length is 5.", ] `); }); @@ -167,4 +168,117 @@ describe('schema', () => { `); }); }); + + describe('paginationSchema', () => { + it('succeeds when no page or perPage passed', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 1 }).decode({}))) + .toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('succeeds when only valid page is passed', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 2 }).decode({ page: 0 }))) + .toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('succeeds when only valid perPage is passed', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ perPage: 1 }))) + .toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('succeeds when page and perPage are passed and valid', () => { + expect( + PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: 1, perPage: 2 })) + ).toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('fails when perPage > maxPerPage', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ perPage: 4 }))) + .toMatchInlineSnapshot(` + Array [ + "The provided perPage value is too high. The maximum allowed perPage value is 3.", + ] + `); + }); + + it(`fails when page > ${MAX_DOCS_PER_PAGE}`, () => { + expect( + PathReporter.report( + paginationSchema({ maxPerPage: 3 }).decode({ page: MAX_DOCS_PER_PAGE + 1 }) + ) + ).toMatchInlineSnapshot(` + Array [ + "The number of documents is too high. Paginating through more than 10000 documents is not possible.", + ] + `); + }); + + it(`fails when page * perPage > ${MAX_DOCS_PER_PAGE}`, () => { + expect( + PathReporter.report( + paginationSchema({ maxPerPage: 3 }).decode({ page: MAX_DOCS_PER_PAGE, perPage: 2 }) + ) + ).toMatchInlineSnapshot(` + Array [ + "The number of documents is too high. Paginating through more than 10000 documents is not possible.", + ] + `); + }); + + it('validate params as strings work correctly', () => { + expect( + PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: '1', perPage: '2' })) + ).toMatchInlineSnapshot(` + Array [ + "No errors!", + ] + `); + }); + + it('invalid NumberFromString work correctly', () => { + expect( + PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: 'a', perPage: 'b' })) + ).toMatchInlineSnapshot(` + Array [ + "Invalid value \\"a\\" supplied to : Pagination/page: (number | NumberFromString)/0: number", + "cannot parse to a number", + "Invalid value \\"b\\" supplied to : Pagination/perPage: (number | NumberFromString)/0: number", + "cannot parse to a number", + ] + `); + }); + + it.skip('fails when page number is negative', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ page: -1 }))) + .toMatchInlineSnapshot(` + Array [ + "The provided page value is too low. The minimum allowed page value is 0.", + ] + `); + }); + + it.skip('fails when perPage number is negative', () => { + expect(PathReporter.report(paginationSchema({ maxPerPage: 3 }).decode({ perPage: -1 }))) + .toMatchInlineSnapshot(` + Array [ + "The provided perPage value is too low. The minimum allowed perPage value is 0.", + ] + `); + }); + }); }); diff --git a/x-pack/plugins/cases/common/schema/index.ts b/x-pack/plugins/cases/common/schema/index.ts index 9003360ae11b8..764119b06159b 100644 --- a/x-pack/plugins/cases/common/schema/index.ts +++ b/x-pack/plugins/cases/common/schema/index.ts @@ -8,6 +8,10 @@ import * as rt from 'io-ts'; import { either } from 'fp-ts/lib/Either'; +import { MAX_DOCS_PER_PAGE } from '../constants'; +import type { PartialPaginationType } from './types'; +import { PaginationSchemaRt } from './types'; + export interface LimitedSchemaType { fieldName: string; min: number; @@ -92,3 +96,41 @@ export const limitedArraySchema = ({ }), rt.identity ); + +export const paginationSchema = ({ maxPerPage }: { maxPerPage: number }) => + new rt.PartialType( + 'Pagination', + PaginationSchemaRt.is, + (u, c) => + either.chain(PaginationSchemaRt.validate(u, c), (params) => { + if (params.page == null && params.perPage == null) { + return rt.success(params); + } + + const pageAsNumber = params.page ?? 0; + const perPageAsNumber = params.perPage ?? 0; + + if (perPageAsNumber > maxPerPage) { + return rt.failure( + u, + c, + `The provided perPage value is too high. The maximum allowed perPage value is ${maxPerPage}.` + ); + } + + if (Math.max(pageAsNumber, pageAsNumber * perPageAsNumber) > MAX_DOCS_PER_PAGE) { + return rt.failure( + u, + c, + `The number of documents is too high. Paginating through more than ${MAX_DOCS_PER_PAGE} documents is not possible.` + ); + } + + return rt.success({ + ...(params.page != null && { page: pageAsNumber }), + ...(params.perPage != null && { perPage: perPageAsNumber }), + }); + }), + rt.identity, + undefined + ); diff --git a/x-pack/plugins/cases/common/schema/types.ts b/x-pack/plugins/cases/common/schema/types.ts new file mode 100644 index 0000000000000..d2ece26504254 --- /dev/null +++ b/x-pack/plugins/cases/common/schema/types.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { NumberFromString } from '../api/saved_object'; + +const PageTypeRt = rt.union([rt.number, NumberFromString]); +type PageNumberType = rt.TypeOf; + +export interface Pagination { + page: PageNumberType; + perPage: PageNumberType; +} + +export const PaginationSchemaRt = rt.exact(rt.partial({ page: PageTypeRt, perPage: PageTypeRt })); +export type PartialPaginationType = Partial; diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index 4d6905006c08d..c504d966cb9d2 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -12,26 +12,18 @@ "url": "https://www.elastic.co/licensing/elastic-license" } }, - "servers": [ - { - "url": "http://localhost:5601", - "description": "local" - } - ], - "security": [ - { - "basicAuth": [] - }, - { - "apiKeyAuth": [] - } - ], "tags": [ { "name": "cases", "description": "Case APIs enable you to open and track issues." } ], + "servers": [ + { + "url": "http://localhost:5601", + "description": "local" + } + ], "paths": { "/api/cases": { "post": { @@ -3415,15 +3407,7 @@ "$ref": "#/components/parameters/page_index" }, { - "name": "perPage", - "in": "query", - "description": "The number of items to return. Limited to 100 items.", - "required": false, - "schema": { - "type": "integer", - "default": 20, - "maximum": 100 - } + "$ref": "#/components/parameters/page_size" }, { "$ref": "#/components/parameters/sort_order" @@ -3916,11 +3900,12 @@ "page_size": { "in": "query", "name": "perPage", - "description": "The number of items to return.", + "description": "The number of items to return. Limited to 100 items.", "required": false, "schema": { "type": "integer", - "default": 20 + "default": 20, + "maximum": 100 } }, "reporters": { @@ -7161,5 +7146,13 @@ ] } } - } + }, + "security": [ + { + "basicAuth": [] + }, + { + "apiKeyAuth": [] + } + ] } \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index 7608a44f3e45e..d393da4d334a0 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -8,15 +8,12 @@ info: license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license -servers: - - url: http://localhost:5601 - description: local -security: - - basicAuth: [] - - apiKeyAuth: [] tags: - name: cases description: Case APIs enable you to open and track issues. +servers: + - url: http://localhost:5601 + description: local paths: /api/cases: post: @@ -2085,14 +2082,7 @@ paths: parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/page_index' - - name: perPage - in: query - description: The number of items to return. Limited to 100 items. - required: false - schema: - type: integer - default: 20 - maximum: 100 + - $ref: '#/components/parameters/page_size' - $ref: '#/components/parameters/sort_order' - $ref: '#/components/parameters/space_id' responses: @@ -2382,11 +2372,12 @@ components: page_size: in: query name: perPage - description: The number of items to return. + description: The number of items to return. Limited to 100 items. required: false schema: type: integer default: 20 + maximum: 100 reporters: in: query name: reporters @@ -4772,3 +4763,6 @@ components: isPreconfigured: false isDeprecated: false referencedByCount: 0 +security: + - basicAuth: [] + - apiKeyAuth: [] diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml index f59ff5301f9c2..0c78946a39fcf 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/page_size.yaml @@ -1,7 +1,8 @@ in: query name: perPage -description: The number of items to return. +description: The number of items to return. Limited to 100 items. required: false schema: type: integer default: 20 + maximum: 100 diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml index bb43f4dcc0b26..b1dd32a659515 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@_find.yaml @@ -10,14 +10,7 @@ get: parameters: - $ref: '../components/parameters/case_id.yaml' - $ref: '../components/parameters/page_index.yaml' - - name: perPage - in: query - description: The number of items to return. Limited to 100 items. - required: false - schema: - type: integer - default: 20 - maximum: 100 + - $ref: '../components/parameters/page_size.yaml' - $ref: '../components/parameters/sort_order.yaml' - $ref: '../components/parameters/space_id.yaml' responses: diff --git a/x-pack/plugins/cases/server/client/attachments/get.test.ts b/x-pack/plugins/cases/server/client/attachments/get.test.ts index c2c3423b2388b..d093793417c7a 100644 --- a/x-pack/plugins/cases/server/client/attachments/get.test.ts +++ b/x-pack/plugins/cases/server/client/attachments/get.test.ts @@ -20,7 +20,7 @@ describe('get', () => { await expect(() => findComment({ caseID: 'mock-id', findQueryParams: { page: 209, perPage: 100 } }, clientArgs) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to find comments case id: mock-id: Error: The number of documents is too high. Paginating through more than 10,000 documents is not possible."` + `"Failed to find comments case id: mock-id: Error: The number of documents is too high. Paginating through more than 10000 documents is not possible."` ); }); @@ -28,7 +28,7 @@ describe('get', () => { await expect(() => findComment({ caseID: 'mock-id', findQueryParams: { page: 2, perPage: 9001 } }, clientArgs) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to find comments case id: mock-id: Error: The provided perPage value was too high. The maximum allowed perPage value is 100."` + `"Failed to find comments case id: mock-id: Error: The provided perPage value is too high. The maximum allowed perPage value is 100."` ); }); @@ -36,7 +36,7 @@ describe('get', () => { await expect( findComment( // @ts-expect-error: excess attribute - { caseID: 'mock-id', findQueryParams: { page: 2, perPage: 9001, foo: 'bar' } }, + { caseID: 'mock-id', findQueryParams: { page: 2, perPage: 9, foo: 'bar' } }, clientArgs ) ).rejects.toThrowErrorMatchingInlineSnapshot( diff --git a/x-pack/plugins/cases/server/client/attachments/get.ts b/x-pack/plugins/cases/server/client/attachments/get.ts index 62f647434e890..7e4bc311a6572 100644 --- a/x-pack/plugins/cases/server/client/attachments/get.ts +++ b/x-pack/plugins/cases/server/client/attachments/get.ts @@ -39,7 +39,6 @@ import { createCaseError } from '../../common/error'; import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../../routes/api'; import { buildFilter, combineFilters } from '../utils'; import { Operations } from '../../authorization'; -import { validateFindCommentsPagination } from './validators'; import { decodeOrThrow } from '../../../common/api/runtime_types'; const normalizeAlertResponse = (alerts: Array>): AlertResponse => @@ -124,8 +123,6 @@ export async function find( try { const queryParams = decodeWithExcessOrThrow(FindCommentsQueryParamsRt)(findQueryParams); - validateFindCommentsPagination(queryParams); - const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } = await authorization.getAuthorizationFilter(Operations.findComments); diff --git a/x-pack/plugins/cases/server/client/attachments/validators.test.ts b/x-pack/plugins/cases/server/client/attachments/validators.test.ts deleted file mode 100644 index ce6c43a665a10..0000000000000 --- a/x-pack/plugins/cases/server/client/attachments/validators.test.ts +++ /dev/null @@ -1,52 +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 { validateFindCommentsPagination } from './validators'; -import { MAX_COMMENTS_PER_PAGE } from '../../../common/constants'; - -const ERROR_MSG = - 'The number of documents is too high. Paginating through more than 10,000 documents is not possible.'; - -const ERROR_MSG_PER_PAGE = `The provided perPage value was too high. The maximum allowed perPage value is ${MAX_COMMENTS_PER_PAGE}.`; - -describe('validators', () => { - describe('validateFindCommentsPagination', () => { - it('does not throw if only page is undefined', () => { - expect(() => validateFindCommentsPagination({ perPage: 100 })).not.toThrowError(); - }); - - it('does not throw if only perPage is undefined', () => { - expect(() => validateFindCommentsPagination({ page: 100 })).not.toThrowError(); - }); - - it('does not throw if page and perPage are defined and valid', () => { - expect(() => validateFindCommentsPagination({ page: 2, perPage: 100 })).not.toThrowError(); - }); - - it('returns if page and perPage are undefined', () => { - expect(() => validateFindCommentsPagination({})).not.toThrowError(); - }); - - it('returns if perPage < 0', () => { - expect(() => validateFindCommentsPagination({ perPage: -1 })).not.toThrowError(); - }); - - it('throws if page > 10k', () => { - expect(() => validateFindCommentsPagination({ page: 10001 })).toThrow(ERROR_MSG); - }); - - it('throws if perPage > 100', () => { - expect(() => - validateFindCommentsPagination({ perPage: MAX_COMMENTS_PER_PAGE + 1 }) - ).toThrowError(ERROR_MSG_PER_PAGE); - }); - - it('throws if page * perPage > 10k', () => { - expect(() => validateFindCommentsPagination({ page: 101, perPage: 100 })).toThrow(ERROR_MSG); - }); - }); -}); diff --git a/x-pack/plugins/cases/server/client/attachments/validators.ts b/x-pack/plugins/cases/server/client/attachments/validators.ts index ea38fa71e702a..4a66d32c31c19 100644 --- a/x-pack/plugins/cases/server/client/attachments/validators.ts +++ b/x-pack/plugins/cases/server/client/attachments/validators.ts @@ -6,12 +6,11 @@ */ import Boom from '@hapi/boom'; -import { MAX_DOCS_PER_PAGE, MAX_COMMENTS_PER_PAGE } from '../../../common/constants'; import { isCommentRequestTypeExternalReference, isCommentRequestTypePersistableState, } from '../../../common/utils/attachments'; -import type { CommentRequest, FindCommentsQueryParams } from '../../../common/api'; +import type { CommentRequest } from '../../../common/api'; import type { ExternalReferenceAttachmentTypeRegistry } from '../../attachment_framework/external_reference_registry'; import type { PersistableStateAttachmentTypeRegistry } from '../../attachment_framework/persistable_state_registry'; @@ -42,24 +41,3 @@ export const validateRegisteredAttachments = ({ ); } }; - -export const validateFindCommentsPagination = (params?: FindCommentsQueryParams) => { - if (params?.page == null && params?.perPage == null) { - return; - } - - const pageAsNumber = params.page ?? 0; - const perPageAsNumber = params.perPage ?? 0; - - if (perPageAsNumber > MAX_COMMENTS_PER_PAGE) { - throw Boom.badRequest( - `The provided perPage value was too high. The maximum allowed perPage value is ${MAX_COMMENTS_PER_PAGE}.` - ); - } - - if (Math.max(pageAsNumber, pageAsNumber * perPageAsNumber) > MAX_DOCS_PER_PAGE) { - throw Boom.badRequest( - 'The number of documents is too high. Paginating through more than 10,000 documents is not possible.' - ); - } -}; diff --git a/x-pack/plugins/cases/server/client/cases/find.test.ts b/x-pack/plugins/cases/server/client/cases/find.test.ts index b7d9d9117ad7e..988aebd33e2af 100644 --- a/x-pack/plugins/cases/server/client/cases/find.test.ts +++ b/x-pack/plugins/cases/server/client/cases/find.test.ts @@ -10,7 +10,9 @@ import type { Case } from '../../../common/api'; import { MAX_ASSIGNEES_FILTER_LENGTH, + MAX_CASES_PER_PAGE, MAX_CATEGORY_FILTER_LENGTH, + MAX_DOCS_PER_PAGE, MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, } from '../../../common/constants'; @@ -81,7 +83,7 @@ describe('find', () => { }); }); - describe('searchFields errors', () => { + describe('errors', () => { const clientArgs = createCasesClientMockArgs(); beforeEach(() => { @@ -149,5 +151,24 @@ describe('find', () => { `Error: The length of the field reporters is too long. Array must be of length <= ${MAX_REPORTERS_FILTER_LENGTH}.` ); }); + + it('Invalid total items results in error', async () => { + const findRequest = createCasesClientMockFindRequest({ page: 209, perPage: 100 }); + + await expect(find(findRequest, clientArgs)).rejects.toThrowError( + `Error: The number of documents is too high. Paginating through more than ${MAX_DOCS_PER_PAGE} documents is not possible.` + ); + }); + + it('Invalid perPage items results in error', async () => { + const findRequest = createCasesClientMockFindRequest({ + page: 1, + perPage: MAX_CASES_PER_PAGE + 1, + }); + + await expect(find(findRequest, clientArgs)).rejects.toThrowError( + `Error: The provided perPage value is too high. The maximum allowed perPage value is ${MAX_CASES_PER_PAGE}.` + ); + }); }); }); diff --git a/x-pack/plugins/cases/server/client/user_actions/find.test.ts b/x-pack/plugins/cases/server/client/user_actions/find.test.ts index a8df2782117ce..e0655bc1d2d51 100644 --- a/x-pack/plugins/cases/server/client/user_actions/find.test.ts +++ b/x-pack/plugins/cases/server/client/user_actions/find.test.ts @@ -5,11 +5,12 @@ * 2.0. */ +import { MAX_DOCS_PER_PAGE, MAX_USER_ACTIONS_PER_PAGE } from '../../../common/constants'; import { createMockClient } from '../metrics/test_utils/client'; import { createCasesClientMockArgs } from '../mocks'; import { find } from './find'; -describe('addComment', () => { +describe('findUserActions', () => { const client = createMockClient(); const clientArgs = createCasesClientMockArgs(); @@ -17,10 +18,38 @@ describe('addComment', () => { jest.clearAllMocks(); }); - it('throws with excess fields', async () => { - await expect( - // @ts-expect-error: excess attribute - find({ caseId: 'test-case', params: { foo: 'bar' } }, client, clientArgs) - ).rejects.toThrow('invalid keys "foo"'); + describe('errors', () => { + it('throws with excess fields', async () => { + await expect( + // @ts-expect-error: excess attribute + find({ caseId: 'test-case', params: { foo: 'bar' } }, client, clientArgs) + ).rejects.toThrow('invalid keys "foo"'); + }); + + it(`throws when trying to fetch more than ${MAX_DOCS_PER_PAGE} items`, async () => { + await expect( + find({ caseId: 'test-case', params: { page: 209, perPage: 100 } }, client, clientArgs) + ).rejects.toThrow( + `Error: The number of documents is too high. Paginating through more than ${MAX_DOCS_PER_PAGE} documents is not possible.` + ); + }); + + it(`throws when perPage > ${MAX_USER_ACTIONS_PER_PAGE}`, async () => { + await expect( + find( + { + caseId: 'test-case', + params: { + page: 1, + perPage: MAX_USER_ACTIONS_PER_PAGE + 1, + }, + }, + client, + clientArgs + ) + ).rejects.toThrow( + `Error: The provided perPage value is too high. The maximum allowed perPage value is ${MAX_USER_ACTIONS_PER_PAGE}.` + ); + }); }); }); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts index 6875bc043a6c5..f4c044415190f 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts @@ -11,6 +11,7 @@ import expect from '@kbn/expect'; import { CASES_URL, MAX_ASSIGNEES_FILTER_LENGTH, + MAX_CASES_PER_PAGE, MAX_CATEGORY_FILTER_LENGTH, MAX_REPORTERS_FILTER_LENGTH, MAX_TAGS_FILTER_LENGTH, @@ -341,39 +342,6 @@ export default ({ getService }: FtrProviderContext): void => { }); }); - describe('errors', () => { - it('unhappy path - 400s when bad query supplied', async () => { - await findCases({ supertest, query: { perPage: true }, expectedHttpCode: 400 }); - }); - - for (const field of ['owner', 'tags', 'severity', 'status']) { - it(`should return a 400 when attempting to query a keyword field [${field}] when using a wildcard query`, async () => { - await findCases({ - supertest, - query: { searchFields: [field], search: 'some search string*' }, - expectedHttpCode: 400, - }); - }); - } - - for (const scenario of [ - { fieldName: 'category', sizeLimit: MAX_CATEGORY_FILTER_LENGTH }, - { fieldName: 'tags', sizeLimit: MAX_TAGS_FILTER_LENGTH }, - { fieldName: 'assignees', sizeLimit: MAX_ASSIGNEES_FILTER_LENGTH }, - { fieldName: 'reporters', sizeLimit: MAX_REPORTERS_FILTER_LENGTH }, - ]) { - it(`unhappy path - 400s when the field ${scenario.fieldName} exceeds the size limit`, async () => { - const value = Array(scenario.sizeLimit + 1).fill('foobar'); - - await findCases({ - supertest, - query: { [scenario.fieldName]: value }, - expectedHttpCode: 400, - }); - }); - } - }); - describe('search and searchField', () => { beforeEach(async () => { await createCase(supertest, postCaseReq); @@ -459,6 +427,51 @@ export default ({ getService }: FtrProviderContext): void => { }); }); + describe('errors', () => { + it('unhappy path - 400s when bad query supplied', async () => { + await findCases({ supertest, query: { perPage: true }, expectedHttpCode: 400 }); + }); + + for (const field of ['owner', 'tags', 'severity', 'status']) { + it(`should return a 400 when attempting to query a keyword field [${field}] when using a wildcard query`, async () => { + await findCases({ + supertest, + query: { searchFields: [field], search: 'some search string*' }, + expectedHttpCode: 400, + }); + }); + } + + for (const scenario of [ + { fieldName: 'category', sizeLimit: MAX_CATEGORY_FILTER_LENGTH }, + { fieldName: 'tags', sizeLimit: MAX_TAGS_FILTER_LENGTH }, + { fieldName: 'assignees', sizeLimit: MAX_ASSIGNEES_FILTER_LENGTH }, + { fieldName: 'reporters', sizeLimit: MAX_REPORTERS_FILTER_LENGTH }, + ]) { + it(`unhappy path - 400s when the field ${scenario.fieldName} exceeds the size limit`, async () => { + const value = Array(scenario.sizeLimit + 1).fill('foobar'); + + await findCases({ + supertest, + query: { [scenario.fieldName]: value }, + expectedHttpCode: 400, + }); + }); + } + + it(`400s when perPage > ${MAX_CASES_PER_PAGE} supplied`, async () => { + await findCases({ + supertest, + query: { perPage: MAX_CASES_PER_PAGE + 1 }, + expectedHttpCode: 400, + }); + }); + + it('400s when trying to fetch more than 10,000 documents', async () => { + await findCases({ supertest, query: { page: 209, perPage: 100 }, expectedHttpCode: 400 }); + }); + }); + describe('alerts', () => { const defaultSignalsIndex = '.siem-signals-default-000001'; const signalID = '4679431ee0ba3209b6fcd60a255a696886fe0a7d18f5375de510ff5b68fa6b78'; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts index 761959db29f66..0256a0ac1e562 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/find_comments.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; -import { CASES_URL } from '@kbn/cases-plugin/common/constants'; +import { CASES_URL, MAX_COMMENTS_PER_PAGE } from '@kbn/cases-plugin/common/constants'; import { CommentType } from '@kbn/cases-plugin/common/api'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { @@ -114,7 +114,7 @@ export default ({ getService }: FtrProviderContext): void => { { name: 'field is wrong type', queryParams: { perPage: true } }, { name: 'field is unknown', queryParams: { foo: 'bar' } }, { name: 'page > 10k', queryParams: { page: 10001 } }, - { name: 'perPage > 100', queryParams: { perPage: 101 } }, + { name: 'perPage > 100', queryParams: { perPage: MAX_COMMENTS_PER_PAGE + 1 } }, { name: 'page * perPage > 10k', queryParams: { page: 2, perPage: 9001 } }, ]) { it(`400s when ${errorScenario.name}`, async () => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts index 28bab81a70bee..d5340beea28d9 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/user_actions/find_user_actions.ts @@ -15,6 +15,7 @@ import { ConnectorTypes, FindTypes, } from '@kbn/cases-plugin/common/api'; +import { MAX_USER_ACTIONS_PER_PAGE } from '@kbn/cases-plugin/common/constants'; import { globalRead, noKibanaPrivileges, @@ -237,6 +238,24 @@ export default ({ getService }: FtrProviderContext): void => { expect(response.userActions[0].type).to.eql('create_case'); expect(response.userActions[0].action).to.eql('create'); }); + + it(`400s when perPage > ${MAX_USER_ACTIONS_PER_PAGE} supplied`, async () => { + await findCaseUserActions({ + caseID: theCase.id, + supertest, + options: { perPage: MAX_USER_ACTIONS_PER_PAGE + 1 }, + expectedHttpCode: 400, + }); + }); + + it('400s when trying to fetch more than 10,000 documents', async () => { + await findCaseUserActions({ + caseID: theCase.id, + supertest, + options: { page: 209, perPage: 100 }, + expectedHttpCode: 400, + }); + }); }); describe('filters using the type query parameter', () => { From f2e773d435a50215e952385dc2b86834364a0d1e Mon Sep 17 00:00:00 2001 From: Sergi Massaneda Date: Wed, 5 Jul 2023 13:51:49 +0200 Subject: [PATCH 38/64] [SecuritySolution] Rename security solution plugins (#161153) ## Summary closes: https://github.com/elastic/kibana/issues/159685 - Renaming _x-pack/plugins_: `serverless_security` -> `security_solution_serverless` `ess_security` -> `security_solution_ess` - All the related configurations and types have also been renamed. - i18n translation prefixes updated - relocation of internal `security_solution_serverless` directories to be consistent with `security_solution_ess` ### Eslint I also added the plugins in the `.eslintrc` configuration, defining the same rules as the `security_solution` plugin. All eslint errors have been addressed (mainly _type_ imports errors) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .eslintrc.js | 14 +++ .github/CODEOWNERS | 13 ++- config/serverless.security.yml | 6 +- config/serverless.yml | 2 +- docs/developer/plugin-list.asciidoc | 17 ++-- package.json | 4 +- packages/kbn-optimizer/limits.yml | 4 +- tsconfig.base.json | 8 +- x-pack/.i18nrc.json | 4 +- .../public/__mocks__/services.tsx | 23 ----- .../ess_security/public/get_started/index.tsx | 21 ----- .../ess_security/public/jest.config.js | 25 ----- x-pack/plugins/ess_security/public/plugin.ts | 49 ---------- .../plugins/security_solution/common/index.ts | 2 + .../.gitignore | 0 .../README.md | 4 +- .../common/index.ts | 4 +- .../jest.config.dev.js | 2 +- .../kibana.jsonc | 6 +- .../package.json | 4 +- .../public/breadcrumbs/breadcrumbs.test.ts | 0 .../public/breadcrumbs/breadcrumbs.ts | 12 +-- .../public/breadcrumbs/index.ts | 0 .../public/common/__mocks__/services.mock.ts | 15 +++ .../public/common/__mocks__/services.tsx | 10 ++ .../common/hooks/__mocks__/use_variation.ts | 0 .../public/common/hooks/use_variation.test.ts | 0 .../public/common/hooks/use_variation.ts | 0 .../public/common}/services.tsx | 19 ++-- .../public/get_started/images/cloud1.svg | 0 .../public/get_started/images/endpoint1.svg | 0 .../public/get_started/images/siem1.svg | 0 .../public/get_started/index.tsx | 19 ++++ .../public/get_started/landing_cards.test.tsx | 2 +- .../public/get_started/landing_cards.tsx | 4 +- .../public/get_started/lazy.tsx | 0 .../public/get_started/translations.tsx | 0 .../public/index.ts | 8 +- .../public/jest.config.js | 26 ++++++ .../security_solution_ess/public/plugin.ts | 49 ++++++++++ .../public/types.ts | 10 +- .../server/config.ts | 4 +- .../server/constants.ts | 0 .../server/index.ts | 8 +- .../server/plugin.ts | 26 +++--- .../server/types.ts | 10 +- .../tsconfig.json | 4 +- .../.gitignore | 0 .../security_solution_serverless/README.mdx | 4 + .../common/config.ts | 14 ++- .../common/index.ts | 4 +- .../common/jest.config.js | 28 ++++++ .../common/pli/pli_config.ts | 0 .../common/pli/pli_features.test.ts | 12 +-- .../common/pli/pli_features.ts | 0 .../common/product.ts | 17 ++++ .../jest.config.dev.js | 12 +++ .../kibana.jsonc | 9 +- .../package.json | 2 +- .../common/__mocks__}/services.mock.tsx | 18 ++-- .../public/common/__mocks__/services.tsx | 19 ++++ .../common}/hooks/__mocks__/use_link_props.ts | 0 .../common}/hooks/use_link_props.test.tsx | 27 +++--- .../public/common}/hooks/use_link_props.ts | 2 +- .../public/common}/hooks/use_nav_links.ts | 2 +- .../public/common}/lib/__mocks__/storage.ts | 0 .../public/common}/lib/storage.ts | 0 .../public/common/services.tsx | 10 +- .../get_started/__mocks__/card_step.tsx | 0 .../get_started/__mocks__/product_switch.tsx | 0 .../public}/get_started/__mocks__/storage.ts | 0 .../get_started/__mocks__/toggle_panel.tsx | 0 .../get_started/__mocks__/welcome_panel.tsx | 0 .../public}/get_started/card_item.test.tsx | 5 +- .../public}/get_started/card_item.tsx | 18 ++-- .../public}/get_started/card_step.test.tsx | 5 +- .../public}/get_started/card_step.tsx | 2 +- .../public}/get_started/get_started.test.tsx | 4 +- .../public}/get_started/get_started.tsx | 10 +- .../public}/get_started/helpers.test.ts | 8 +- .../public}/get_started/helpers.ts | 6 +- .../public}/get_started/images/invite.svg | 0 .../public}/get_started/images/progress.svg | 0 .../public}/get_started/images/protect.svg | 0 .../public}/get_started/images/respond.svg | 0 .../public}/get_started/images/step.svg | 0 .../public}/get_started/index.tsx | 20 ++-- .../public}/get_started/lazy.tsx | 4 +- .../get_started/product_switch.test.tsx | 4 +- .../public}/get_started/product_switch.tsx | 6 +- .../public}/get_started/reducer.test.ts | 12 +-- .../public}/get_started/reducer.tsx | 12 +-- .../public}/get_started/sections.tsx | 7 +- .../public}/get_started/storage.test.ts | 10 +- .../public}/get_started/storage.ts | 17 ++-- .../public}/get_started/toggle_panel.test.tsx | 7 +- .../public}/get_started/toggle_panel.tsx | 4 +- .../public}/get_started/translations.ts | 93 ++++++++++--------- .../public}/get_started/types.ts | 11 +-- .../get_started/use_setup_cards.test.tsx | 6 +- .../public}/get_started/use_setup_cards.tsx | 6 +- .../get_started/use_toggle_panel.test.tsx | 7 +- .../public}/get_started/use_toggle_panel.tsx | 8 +- .../get_started/welcome_panel.test.tsx | 2 +- .../public}/get_started/welcome_panel.tsx | 2 +- .../public/index.ts | 11 ++- .../public/jest.config.js | 29 ++++++ .../public}/navigation/breadcrumbs.ts | 2 +- .../public/navigation/index.ts | 29 ++++++ .../public}/navigation/links/index.ts | 0 .../public}/navigation/links/nav_links.ts | 0 .../public}/navigation/links/types.ts | 0 .../navigation/navigation_tree.test.ts | 47 +++++----- .../public}/navigation/navigation_tree.ts | 2 +- .../__mocks__/use_side_nav_items.ts | 0 .../navigation}/side_navigation/categories.ts | 0 .../navigation}/side_navigation/index.tsx | 15 +-- .../navigation}/side_navigation/lazy.tsx | 0 .../side_navigation/side_navigation.test.tsx | 17 ++-- .../side_navigation/side_navigation.tsx | 19 ++-- .../use_side_nav_items.test.tsx | 35 +++---- .../side_navigation}/use_side_nav_items.ts | 6 +- .../public/plugin.ts | 62 +++++++++++++ .../public/types.ts | 10 +- .../hooks/use_product_type_by_pli.ts | 2 +- .../public}/upselling/index.ts | 0 .../pages/generic_upselling_page.tsx | 6 +- .../pages/generic_upselling_section.tsx | 6 +- .../upselling/register_upsellings.test.tsx | 13 +-- .../public}/upselling/register_upsellings.tsx | 6 +- .../server/config.ts | 4 +- .../server/index.ts | 11 ++- .../server/plugin.ts | 24 ++--- .../server/types.ts | 12 +-- .../tsconfig.json | 2 +- x-pack/plugins/serverless_security/README.mdx | 3 - .../serverless_security/common/jest.config.js | 26 ------ .../public/common/jest.config.js | 28 ------ .../public/components/jest.config.js | 28 ------ .../public/hooks/jest.config.js | 28 ------ .../serverless_security/public/jest.config.js | 27 ------ .../public/lib/jest.config.js | 26 ------ .../serverless_security/public/plugin.ts | 71 -------------- .../test_suites/security/cypress/package.json | 2 +- yarn.lock | 16 ++-- 145 files changed, 759 insertions(+), 780 deletions(-) delete mode 100644 x-pack/plugins/ess_security/public/__mocks__/services.tsx delete mode 100644 x-pack/plugins/ess_security/public/get_started/index.tsx delete mode 100644 x-pack/plugins/ess_security/public/jest.config.js delete mode 100644 x-pack/plugins/ess_security/public/plugin.ts rename x-pack/plugins/{ess_security => security_solution_ess}/.gitignore (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/README.md (51%) rename x-pack/plugins/{ess_security => security_solution_ess}/common/index.ts (72%) rename x-pack/plugins/{serverless_security => security_solution_ess}/jest.config.dev.js (78%) rename x-pack/plugins/{ess_security => security_solution_ess}/kibana.jsonc (73%) rename x-pack/plugins/{serverless_security => security_solution_ess}/package.json (85%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/breadcrumbs/breadcrumbs.test.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/breadcrumbs/breadcrumbs.ts (67%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/breadcrumbs/index.ts (100%) create mode 100644 x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.ts create mode 100644 x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx rename x-pack/plugins/{ess_security => security_solution_ess}/public/common/hooks/__mocks__/use_variation.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/common/hooks/use_variation.test.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/common/hooks/use_variation.ts (100%) rename x-pack/plugins/{ess_security/public => security_solution_ess/public/common}/services.tsx (59%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/images/cloud1.svg (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/images/endpoint1.svg (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/images/siem1.svg (100%) create mode 100644 x-pack/plugins/security_solution_ess/public/get_started/index.tsx rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/landing_cards.test.tsx (98%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/landing_cards.tsx (98%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/lazy.tsx (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/get_started/translations.tsx (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/public/index.ts (62%) create mode 100644 x-pack/plugins/security_solution_ess/public/jest.config.js create mode 100644 x-pack/plugins/security_solution_ess/public/plugin.ts rename x-pack/plugins/{ess_security => security_solution_ess}/public/types.ts (69%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/config.ts (80%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/constants.ts (100%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/index.ts (64%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/plugin.ts (50%) rename x-pack/plugins/{ess_security => security_solution_ess}/server/types.ts (73%) rename x-pack/plugins/{ess_security => security_solution_ess}/tsconfig.json (92%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/.gitignore (100%) create mode 100755 x-pack/plugins/security_solution_serverless/README.mdx rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/config.ts (77%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/index.ts (69%) create mode 100644 x-pack/plugins/security_solution_serverless/common/jest.config.js rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/pli/pli_config.ts (100%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/pli/pli_features.test.ts (80%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/common/pli/pli_features.ts (100%) create mode 100644 x-pack/plugins/security_solution_serverless/common/product.ts create mode 100644 x-pack/plugins/security_solution_serverless/jest.config.dev.js rename x-pack/plugins/{serverless_security => security_solution_serverless}/kibana.jsonc (74%) rename x-pack/plugins/{ess_security => security_solution_serverless}/package.json (83%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public/common/__mocks__}/services.mock.tsx (75%) create mode 100644 x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/__mocks__/use_link_props.ts (100%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/use_link_props.test.tsx (82%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/use_link_props.ts (96%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/hooks/use_nav_links.ts (92%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/lib/__mocks__/storage.ts (100%) rename x-pack/plugins/{serverless_security/public => security_solution_serverless/public/common}/lib/storage.ts (100%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/public/common/services.tsx (74%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/card_step.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/product_switch.tsx (100%) rename x-pack/plugins/{serverless_security/public/lib => security_solution_serverless/public}/get_started/__mocks__/storage.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/toggle_panel.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/__mocks__/welcome_panel.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_item.test.tsx (92%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_item.tsx (90%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_step.test.tsx (94%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/card_step.tsx (97%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/get_started.test.tsx (94%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/get_started.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/helpers.test.ts (98%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/helpers.ts (92%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/invite.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/progress.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/protect.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/respond.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/images/step.svg (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/index.tsx (53%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/lazy.tsx (80%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/product_switch.test.tsx (95%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/product_switch.tsx (91%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/reducer.test.ts (96%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/reducer.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/sections.tsx (95%) rename x-pack/plugins/{serverless_security/public/lib => security_solution_serverless/public}/get_started/storage.test.ts (95%) rename x-pack/plugins/{serverless_security/public/lib => security_solution_serverless/public}/get_started/storage.ts (77%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/toggle_panel.test.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/toggle_panel.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/translations.ts (58%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/types.ts (88%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_setup_cards.test.tsx (94%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_setup_cards.tsx (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_toggle_panel.test.tsx (97%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/use_toggle_panel.tsx (90%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/welcome_panel.test.tsx (96%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/get_started/welcome_panel.tsx (98%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/public/index.ts (58%) create mode 100644 x-pack/plugins/security_solution_serverless/public/jest.config.js rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/breadcrumbs.ts (90%) create mode 100644 x-pack/plugins/security_solution_serverless/public/navigation/index.ts rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/links/index.ts (100%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/links/nav_links.ts (100%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/links/types.ts (100%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/navigation_tree.test.ts (86%) rename x-pack/plugins/{serverless_security/public/common => security_solution_serverless/public}/navigation/navigation_tree.ts (98%) rename x-pack/plugins/{serverless_security/public/hooks => security_solution_serverless/public/navigation/side_navigation}/__mocks__/use_side_nav_items.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/categories.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/index.tsx (73%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/lazy.tsx (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/side_navigation.test.tsx (85%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public/navigation}/side_navigation/side_navigation.tsx (79%) rename x-pack/plugins/{serverless_security/public/hooks => security_solution_serverless/public/navigation/side_navigation}/use_side_nav_items.test.tsx (82%) rename x-pack/plugins/{serverless_security/public/hooks => security_solution_serverless/public/navigation/side_navigation}/use_side_nav_items.ts (95%) create mode 100644 x-pack/plugins/security_solution_serverless/public/plugin.ts rename x-pack/plugins/{serverless_security => security_solution_serverless}/public/types.ts (78%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/hooks/use_product_type_by_pli.ts (93%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/index.ts (100%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/pages/generic_upselling_page.tsx (83%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/pages/generic_upselling_section.tsx (83%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/register_upsellings.test.tsx (81%) rename x-pack/plugins/{serverless_security/public/components => security_solution_serverless/public}/upselling/register_upsellings.tsx (91%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/config.ts (83%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/index.ts (60%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/plugin.ts (63%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/server/types.ts (73%) rename x-pack/plugins/{serverless_security => security_solution_serverless}/tsconfig.json (95%) delete mode 100755 x-pack/plugins/serverless_security/README.mdx delete mode 100644 x-pack/plugins/serverless_security/common/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/common/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/components/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/hooks/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/lib/jest.config.js delete mode 100644 x-pack/plugins/serverless_security/public/plugin.ts diff --git a/.eslintrc.js b/.eslintrc.js index be80d7550253a..dacfa2d470e05 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -986,7 +986,11 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{js,mjs,ts,tsx}', 'x-pack/packages/security-solution/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/security_solution/public/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/public/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/public/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/security_solution/common/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/common/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/common/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/timelines/public/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/timelines/common/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/cases/public/**/*.{js,mjs,ts,tsx}', @@ -1014,6 +1018,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{ts,tsx}', 'x-pack/packages/security-solution/**/*.{ts,tsx}', 'x-pack/plugins/security_solution/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{ts,tsx}', 'x-pack/plugins/timelines/**/*.{ts,tsx}', 'x-pack/plugins/cases/**/*.{ts,tsx}', ], @@ -1022,6 +1028,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/packages/security-solution/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/plugins/security_solution/**/*.{test,mock,test_helper}.{ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{test,mock,test_helper}.{ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/plugins/timelines/**/*.{test,mock,test_helper}.{ts,tsx}', 'x-pack/plugins/cases/**/*.{test,mock,test_helper}.{ts,tsx}', ], @@ -1036,6 +1044,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{ts,tsx}', 'x-pack/packages/security-solution/**/*.{ts,tsx}', 'x-pack/plugins/security_solution/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{ts,tsx}', 'x-pack/plugins/timelines/**/*.{ts,tsx}', 'x-pack/plugins/cases/**/*.{ts,tsx}', ], @@ -1069,6 +1079,8 @@ module.exports = { 'x-pack/packages/kbn-elastic-assistant/**/*.{js,mjs,ts,tsx}', 'x-pack/packages/security-solution/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/timelines/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/cases/**/*.{js,mjs,ts,tsx}', ], @@ -1163,6 +1175,8 @@ module.exports = { { files: [ 'x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_ess/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/security_solution_serverless/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/cases/**/*.{js,mjs,ts,tsx}', ], rules: { diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4248bd86c7d5b..00dd762c71601 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -359,7 +359,6 @@ packages/kbn-eslint-plugin-eslint @elastic/kibana-operations packages/kbn-eslint-plugin-imports @elastic/kibana-operations packages/kbn-eslint-plugin-telemetry @elastic/actionable-observability x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin @elastic/kibana-security -x-pack/plugins/ess_security @elastic/security-solution src/plugins/event_annotation @elastic/kibana-visualizations x-pack/test/plugin_api_integration/plugins/event_log @elastic/response-ops x-pack/plugins/event_log @elastic/response-ops @@ -580,8 +579,10 @@ examples/search_examples @elastic/kibana-data-discovery x-pack/plugins/searchprofiler @elastic/platform-deployment-management x-pack/test/security_api_integration/packages/helpers @elastic/kibana-core x-pack/plugins/security @elastic/kibana-security +x-pack/plugins/security_solution_ess @elastic/security-solution x-pack/test/cases_api_integration/common/plugins/security_solution @elastic/response-ops x-pack/plugins/security_solution @elastic/security-solution +x-pack/plugins/security_solution_serverless @elastic/security-solution x-pack/packages/security-solution/side_nav @elastic/security-threat-hunting-explore x-pack/packages/security-solution/storybook/config @elastic/security-threat-hunting-explore x-pack/test/security_functional/plugins/test_endpoints @elastic/kibana-security @@ -609,7 +610,6 @@ x-pack/plugins/serverless @elastic/appex-sharedux x-pack/plugins/serverless_observability @elastic/appex-sharedux @elastic/apm-ui packages/serverless/project_switcher @elastic/appex-sharedux x-pack/plugins/serverless_search @elastic/enterprise-search-frontend -x-pack/plugins/serverless_security @elastic/security-solution packages/serverless/storybook/config @elastic/appex-sharedux packages/serverless/types @elastic/appex-sharedux test/plugin_functional/plugins/session_notifications @elastic/kibana-core @@ -824,7 +824,7 @@ packages/kbn-yarn-lock-validator @elastic/kibana-operations #CC# /src/plugins/home/server/services/ @elastic/appex-sharedux #CC# /src/plugins/home/ @elastic/appex-sharedux #CC# /x-pack/plugins/reporting/ @elastic/appex-sharedux -#CC# /x-pack/plugins/serverless_security/ @elastic/appex-sharedux +#CC# /x-pack/plugins/security_solution_serverless/ @elastic/appex-sharedux ### Observability Plugins @@ -1034,6 +1034,11 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/test/api_integration/apis/security_solution @elastic/security-solution #CC# /x-pack/plugins/security_solution/ @elastic/security-solution +# Security Solution Offering plugins +# TODO: assign sub directories to sub teams +/x-pack/plugins/security_solution_ess/ @elastic/security-solution +/x-pack/plugins/security_solution_serverless/ @elastic/security-solution + # Security Solution sub teams ## Security Solution sub teams - Threat Hunting Investigations @@ -1259,6 +1264,8 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience # Security design /x-pack/plugins/endpoint/**/*.scss @elastic/security-design /x-pack/plugins/security_solution/**/*.scss @elastic/security-design +/x-pack/plugins/security_solution_ess/**/*.scss @elastic/security-design +/x-pack/plugins/security_solution_serverless/**/*.scss @elastic/security-design # Logstash #CC# /x-pack/plugins/logstash/ @elastic/logstash diff --git a/config/serverless.security.yml b/config/serverless.security.yml index 5e7cd22a3500b..bad71f38f24af 100644 --- a/config/serverless.security.yml +++ b/config/serverless.security.yml @@ -6,9 +6,9 @@ xpack.apm.enabled: false xpack.observability.enabled: false xpack.uptime.enabled: false -## Enable the Serverless Security plugin -xpack.serverless.security.enabled: true -xpack.serverless.security.productTypes: +## Enable the Security Solution Serverless plugin +xpack.securitySolutionServerless.enabled: true +xpack.securitySolutionServerless.productTypes: [ { product_line: 'security', product_tier: 'complete' }, { product_line: 'endpoint', product_tier: 'complete' }, diff --git a/config/serverless.yml b/config/serverless.yml index e3ecaaa44a8d3..897b168340cd5 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -16,7 +16,7 @@ migrations.zdt: runOnRoles: ["ui"] # Ess plugins -xpack.ess.security.enabled: false +xpack.securitySolutionEss.enabled: false # Management team plugins xpack.upgrade_assistant.enabled: false diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 8e001dcd6fdc6..e29f0fa2ac0ed 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -538,10 +538,6 @@ security and spaces filtering. |This plugin provides Kibana user interfaces for managing the Enterprise Search solution and its products, App Search and Workplace Search. -|{kib-repo}blob/{branch}/x-pack/plugins/ess_security/README.md[essSecurity] -|This plugin contains the ESS/on-prem deployments (non-serverless) customizations for Security Solution. - - |{kib-repo}blob/{branch}/x-pack/plugins/event_log/README.md[eventLog] |The event log plugin provides a persistent history of alerting and action activities. @@ -730,6 +726,15 @@ Kibana. |Welcome to the Kibana Security Solution plugin! This README will go over getting started with development and testing. +|{kib-repo}blob/{branch}/x-pack/plugins/security_solution_ess/README.md[securitySolutionEss] +|This plugin contains the ESS/on-prem deployments (non-serverless) specific logic for Security Solution. + + +|{kib-repo}blob/{branch}/x-pack/plugins/security_solution_serverless/README.mdx[securitySolutionServerless] +|This plugin contains configuration and code used to create a Serverless Security project. +It leverages universal configuration and other APIs in the serverless plugin to configure Kibana. + + |{kib-repo}blob/{branch}/x-pack/plugins/serverless/README.mdx[serverless] | @@ -742,10 +747,6 @@ Kibana. |This plugin contains configuration and code used to create a Serverless Search project. It leverages universal configuration and other APIs in the serverless plugin to configure Kibana. -|{kib-repo}blob/{branch}/x-pack/plugins/serverless_security/README.mdx[serverlessSecurity] -|This plugin contains configuration and code used to create a Serverless Security project. It leverages universal configuration and other APIs in the serverless plugin to configure Kibana. - - |{kib-repo}blob/{branch}/x-pack/plugins/session_view/README.md[sessionView] |Session View is meant to provide a visualization into what is going on in a particular Linux environment where the agent is running. It looks likes a terminal emulator; however, it is a tool for introspecting process activity and understanding user and service behaviour in your Linux servers and infrastructure. It is a time-ordered series of process executions displayed in a tree over time. diff --git a/package.json b/package.json index 7658626741ea1..bed23b10b7cfa 100644 --- a/package.json +++ b/package.json @@ -393,7 +393,6 @@ "@kbn/es-types": "link:packages/kbn-es-types", "@kbn/es-ui-shared-plugin": "link:src/plugins/es_ui_shared", "@kbn/eso-plugin": "link:x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin", - "@kbn/ess-security": "link:x-pack/plugins/ess_security", "@kbn/event-annotation-plugin": "link:src/plugins/event_annotation", "@kbn/event-log-fixture-plugin": "link:x-pack/test/plugin_api_integration/plugins/event_log", "@kbn/event-log-plugin": "link:x-pack/plugins/event_log", @@ -582,8 +581,10 @@ "@kbn/search-examples-plugin": "link:examples/search_examples", "@kbn/searchprofiler-plugin": "link:x-pack/plugins/searchprofiler", "@kbn/security-plugin": "link:x-pack/plugins/security", + "@kbn/security-solution-ess": "link:x-pack/plugins/security_solution_ess", "@kbn/security-solution-fixtures-plugin": "link:x-pack/test/cases_api_integration/common/plugins/security_solution", "@kbn/security-solution-plugin": "link:x-pack/plugins/security_solution", + "@kbn/security-solution-serverless": "link:x-pack/plugins/security_solution_serverless", "@kbn/security-solution-side-nav": "link:x-pack/packages/security-solution/side_nav", "@kbn/security-solution-storybook-config": "link:x-pack/packages/security-solution/storybook/config", "@kbn/security-test-endpoints-plugin": "link:x-pack/test/security_functional/plugins/test_endpoints", @@ -611,7 +612,6 @@ "@kbn/serverless-observability": "link:x-pack/plugins/serverless_observability", "@kbn/serverless-project-switcher": "link:packages/serverless/project_switcher", "@kbn/serverless-search": "link:x-pack/plugins/serverless_search", - "@kbn/serverless-security": "link:x-pack/plugins/serverless_security", "@kbn/serverless-types": "link:packages/serverless/types", "@kbn/session-notifications-plugin": "link:test/plugin_functional/plugins/session_notifications", "@kbn/session-view-plugin": "link:x-pack/plugins/session_view", diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index c0a9f99b09d4c..ae6543232fa8f 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -40,7 +40,6 @@ pageLoadAssetSize: embeddable: 87309 embeddableEnhanced: 22107 enterpriseSearch: 50858 - essSecurity: 16573 esUiShared: 326654 eventAnnotation: 48565 exploratoryView: 74673 @@ -119,10 +118,11 @@ pageLoadAssetSize: searchprofiler: 67080 security: 65433 securitySolution: 66738 + securitySolutionEss: 16573 + securitySolutionServerless: 40000 serverless: 16573 serverlessObservability: 68747 serverlessSearch: 71995 - serverlessSecurity: 40000 sessionView: 77750 share: 71239 snapshotRestore: 79032 diff --git a/tsconfig.base.json b/tsconfig.base.json index 1f70f84715646..8b4c52078c35a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -712,8 +712,6 @@ "@kbn/eslint-plugin-telemetry/*": ["packages/kbn-eslint-plugin-telemetry/*"], "@kbn/eso-plugin": ["x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin"], "@kbn/eso-plugin/*": ["x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin/*"], - "@kbn/ess-security": ["x-pack/plugins/ess_security"], - "@kbn/ess-security/*": ["x-pack/plugins/ess_security/*"], "@kbn/event-annotation-plugin": ["src/plugins/event_annotation"], "@kbn/event-annotation-plugin/*": ["src/plugins/event_annotation/*"], "@kbn/event-log-fixture-plugin": ["x-pack/test/plugin_api_integration/plugins/event_log"], @@ -1154,10 +1152,14 @@ "@kbn/security-api-integration-helpers/*": ["x-pack/test/security_api_integration/packages/helpers/*"], "@kbn/security-plugin": ["x-pack/plugins/security"], "@kbn/security-plugin/*": ["x-pack/plugins/security/*"], + "@kbn/security-solution-ess": ["x-pack/plugins/security_solution_ess"], + "@kbn/security-solution-ess/*": ["x-pack/plugins/security_solution_ess/*"], "@kbn/security-solution-fixtures-plugin": ["x-pack/test/cases_api_integration/common/plugins/security_solution"], "@kbn/security-solution-fixtures-plugin/*": ["x-pack/test/cases_api_integration/common/plugins/security_solution/*"], "@kbn/security-solution-plugin": ["x-pack/plugins/security_solution"], "@kbn/security-solution-plugin/*": ["x-pack/plugins/security_solution/*"], + "@kbn/security-solution-serverless": ["x-pack/plugins/security_solution_serverless"], + "@kbn/security-solution-serverless/*": ["x-pack/plugins/security_solution_serverless/*"], "@kbn/security-solution-side-nav": ["x-pack/packages/security-solution/side_nav"], "@kbn/security-solution-side-nav/*": ["x-pack/packages/security-solution/side_nav/*"], "@kbn/security-solution-storybook-config": ["x-pack/packages/security-solution/storybook/config"], @@ -1212,8 +1214,6 @@ "@kbn/serverless-project-switcher/*": ["packages/serverless/project_switcher/*"], "@kbn/serverless-search": ["x-pack/plugins/serverless_search"], "@kbn/serverless-search/*": ["x-pack/plugins/serverless_search/*"], - "@kbn/serverless-security": ["x-pack/plugins/serverless_security"], - "@kbn/serverless-security/*": ["x-pack/plugins/serverless_security/*"], "@kbn/serverless-storybook-config": ["packages/serverless/storybook/config"], "@kbn/serverless-storybook-config/*": ["packages/serverless/storybook/config/*"], "@kbn/serverless-types": ["packages/serverless/types"], diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 2fa461531b499..6fbc0f935b940 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -74,9 +74,9 @@ "xpack.serverless": "plugins/serverless", "xpack.serverlessSearch": "plugins/serverless_search", "xpack.serverlessObservability": "plugins/serverless_observability", - "xpack.serverlessSecurity": "plugins/serverless_security", "xpack.securitySolution": "plugins/security_solution", - "xpack.securitySolutionEss": "plugins/ess_security", + "xpack.securitySolutionEss": "plugins/security_solution_ess", + "xpack.securitySolutionServerless": "plugins/security_solution_serverless", "xpack.sessionView": "plugins/session_view", "xpack.snapshotRestore": "plugins/snapshot_restore", "xpack.spaces": "plugins/spaces", diff --git a/x-pack/plugins/ess_security/public/__mocks__/services.tsx b/x-pack/plugins/ess_security/public/__mocks__/services.tsx deleted file mode 100644 index e24367947f89e..0000000000000 --- a/x-pack/plugins/ess_security/public/__mocks__/services.tsx +++ /dev/null @@ -1,23 +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 React from 'react'; - -export const KibanaServicesProvider = jest - .fn() - .mockImplementation(({ children }) =>
    {children}
    ); - -export const useKibana = jest.fn().mockReturnValue({ - services: { - http: { - basePath: { - prepend: jest.fn().mockImplementation((path: string) => path), - }, - }, - cloudExperiments: {}, - }, -}); diff --git a/x-pack/plugins/ess_security/public/get_started/index.tsx b/x-pack/plugins/ess_security/public/get_started/index.tsx deleted file mode 100644 index b06d1c0b2c844..0000000000000 --- a/x-pack/plugins/ess_security/public/get_started/index.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; - -import { CoreStart } from '@kbn/core/public'; -import { KibanaServicesProvider } from '../services'; -import { EssSecurityPluginStartDependencies } from '../types'; -import { GetStarted } from './lazy'; - -export const getSecurityGetStartedComponent = - (core: CoreStart, pluginsStart: EssSecurityPluginStartDependencies): React.ComponentType => - () => - ( - - - - ); diff --git a/x-pack/plugins/ess_security/public/jest.config.js b/x-pack/plugins/ess_security/public/jest.config.js deleted file mode 100644 index ffee6062ec59b..0000000000000 --- a/x-pack/plugins/ess_security/public/jest.config.js +++ /dev/null @@ -1,25 +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. - */ -module.exports = { - preset: '@kbn/test', - rootDir: '../../../..', - /** all nested directories have their own Jest config file */ - testMatch: ['/x-pack/plugins/ess_security/public/**/*.test.{js,mjs,ts,tsx}'], - roots: ['/x-pack/plugins/ess_security/public'], - coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/ess_security/public', - coverageReporters: ['text', 'html'], - collectCoverageFrom: [ - '/x-pack/plugins/ess_security/public/**/*.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/*.test.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', - '!/x-pack/plugins/ess_security/public/*mock*.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/*.test.{ts,tsx}', - '!/x-pack/plugins/ess_security/public/*.d.ts', - '!/x-pack/plugins/ess_security/public/*.config.ts', - '!/x-pack/plugins/ess_security/public/index.{js,ts,tsx}', - ], -}; diff --git a/x-pack/plugins/ess_security/public/plugin.ts b/x-pack/plugins/ess_security/public/plugin.ts deleted file mode 100644 index 52d75c01f8119..0000000000000 --- a/x-pack/plugins/ess_security/public/plugin.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; -import { subscribeBreadcrumbs } from './breadcrumbs'; -import { getSecurityGetStartedComponent } from './get_started'; -import { - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies, -} from './types'; - -export class EssSecurityPlugin - implements - Plugin< - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies - > -{ - constructor() {} - - public setup( - _core: CoreSetup, - _setupDeps: EssSecurityPluginSetupDependencies - ): EssSecurityPluginSetup { - return {}; - } - - public start( - core: CoreStart, - startDeps: EssSecurityPluginStartDependencies - ): EssSecurityPluginStart { - const { securitySolution } = startDeps; - - subscribeBreadcrumbs(securitySolution, core); - securitySolution.setGetStartedPage(getSecurityGetStartedComponent(core, startDeps)); - - return {}; - } - - public stop() {} -} diff --git a/x-pack/plugins/security_solution/common/index.ts b/x-pack/plugins/security_solution/common/index.ts index ebe102e29ce2b..24beb602305dd 100644 --- a/x-pack/plugins/security_solution/common/index.ts +++ b/x-pack/plugins/security_solution/common/index.ts @@ -13,6 +13,8 @@ export { APP_ID, CASES_FEATURE_ID, SERVER_APP_ID, + APP_PATH, + MANAGE_PATH, ADD_DATA_PATH, SecurityPageName, } from './constants'; diff --git a/x-pack/plugins/ess_security/.gitignore b/x-pack/plugins/security_solution_ess/.gitignore similarity index 100% rename from x-pack/plugins/ess_security/.gitignore rename to x-pack/plugins/security_solution_ess/.gitignore diff --git a/x-pack/plugins/ess_security/README.md b/x-pack/plugins/security_solution_ess/README.md similarity index 51% rename from x-pack/plugins/ess_security/README.md rename to x-pack/plugins/security_solution_ess/README.md index c207b6d2671d4..de7339892f750 100755 --- a/x-pack/plugins/ess_security/README.md +++ b/x-pack/plugins/security_solution_ess/README.md @@ -1,3 +1,3 @@ -# essSecurity +# securitySolutionEss -This plugin contains the ESS/on-prem deployments (non-serverless) customizations for Security Solution. \ No newline at end of file +This plugin contains the ESS/on-prem deployments (non-serverless) specific logic for Security Solution. \ No newline at end of file diff --git a/x-pack/plugins/ess_security/common/index.ts b/x-pack/plugins/security_solution_ess/common/index.ts similarity index 72% rename from x-pack/plugins/ess_security/common/index.ts rename to x-pack/plugins/security_solution_ess/common/index.ts index 0b3ef135ddc16..b3541827fd117 100644 --- a/x-pack/plugins/ess_security/common/index.ts +++ b/x-pack/plugins/security_solution_ess/common/index.ts @@ -5,5 +5,5 @@ * 2.0. */ -export const PLUGIN_ID = 'essSecurity'; -export const PLUGIN_NAME = 'essSecurity'; +export const PLUGIN_ID = 'securitySolutionEss'; +export const PLUGIN_NAME = 'securitySolutionEss'; diff --git a/x-pack/plugins/serverless_security/jest.config.dev.js b/x-pack/plugins/security_solution_ess/jest.config.dev.js similarity index 78% rename from x-pack/plugins/serverless_security/jest.config.dev.js rename to x-pack/plugins/security_solution_ess/jest.config.dev.js index f759355f0e0e5..6ac2f96f95f04 100644 --- a/x-pack/plugins/serverless_security/jest.config.dev.js +++ b/x-pack/plugins/security_solution_ess/jest.config.dev.js @@ -8,5 +8,5 @@ module.exports = { preset: '@kbn/test', rootDir: '../../../', - projects: ['/x-pack/plugins/serverless_security/public/*/jest.config.js'], + projects: ['/x-pack/plugins/security_solution_ess/public/jest.config.js'], }; diff --git a/x-pack/plugins/ess_security/kibana.jsonc b/x-pack/plugins/security_solution_ess/kibana.jsonc similarity index 73% rename from x-pack/plugins/ess_security/kibana.jsonc rename to x-pack/plugins/security_solution_ess/kibana.jsonc index eee71237a2a7d..cf1edb3f571c5 100644 --- a/x-pack/plugins/ess_security/kibana.jsonc +++ b/x-pack/plugins/security_solution_ess/kibana.jsonc @@ -1,13 +1,13 @@ { "type": "plugin", - "id": "@kbn/ess-security", + "id": "@kbn/security-solution-ess", "owner": "@elastic/security-solution", "description": "ESS customizations for Security Solution.", "plugin": { - "id": "essSecurity", + "id": "securitySolutionEss", "server": true, "browser": true, - "configPath": ["xpack", "ess", "security"], + "configPath": ["xpack", "securitySolutionEss"], "requiredPlugins": [ "securitySolution" ], diff --git a/x-pack/plugins/serverless_security/package.json b/x-pack/plugins/security_solution_ess/package.json similarity index 85% rename from x-pack/plugins/serverless_security/package.json rename to x-pack/plugins/security_solution_ess/package.json index 0154207c22d6f..e7ab99edd6a2a 100644 --- a/x-pack/plugins/serverless_security/package.json +++ b/x-pack/plugins/security_solution_ess/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/serverless-security", + "name": "@kbn/security-solution-ess", "version": "1.0.0", "license": "Elastic License 2.0", "private": true, @@ -8,4 +8,4 @@ "plugin-helpers": "node ../../../scripts/plugin_helpers", "kbn": "node ../../../scripts/kbn" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts b/x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.test.ts similarity index 100% rename from x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.test.ts rename to x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.test.ts diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts b/x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.ts similarity index 67% rename from x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts rename to x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.ts index 8fa8107226f4c..ca76dc304ab99 100644 --- a/x-pack/plugins/ess_security/public/breadcrumbs/breadcrumbs.ts +++ b/x-pack/plugins/security_solution_ess/public/breadcrumbs/breadcrumbs.ts @@ -5,17 +5,15 @@ * 2.0. */ -import type { PluginStart as SecuritySolutionPluginStart } from '@kbn/security-solution-plugin/public'; -import { ChromeBreadcrumb, CoreStart } from '@kbn/core/public'; +import type { ChromeBreadcrumb } from '@kbn/core/public'; +import type { Services } from '../common/services'; -export const subscribeBreadcrumbs = ( - securitySolution: SecuritySolutionPluginStart, - core: CoreStart -) => { +export const subscribeBreadcrumbs = (services: Services) => { + const { chrome, securitySolution } = services; securitySolution.getBreadcrumbsNav$().subscribe((breadcrumbsNav) => { const breadcrumbs = [...breadcrumbsNav.leading, ...breadcrumbsNav.trailing]; if (breadcrumbs.length > 0) { - core.chrome.setBreadcrumbs(emptyLastBreadcrumbUrl(breadcrumbs)); + chrome.setBreadcrumbs(emptyLastBreadcrumbUrl(breadcrumbs)); } }); }; diff --git a/x-pack/plugins/ess_security/public/breadcrumbs/index.ts b/x-pack/plugins/security_solution_ess/public/breadcrumbs/index.ts similarity index 100% rename from x-pack/plugins/ess_security/public/breadcrumbs/index.ts rename to x-pack/plugins/security_solution_ess/public/breadcrumbs/index.ts diff --git a/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.ts b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.ts new file mode 100644 index 0000000000000..9e9909b45894b --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.mock.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { coreMock } from '@kbn/core/public/mocks'; +import { securitySolutionMock } from '@kbn/security-solution-plugin/public/mocks'; +import type { Services } from '../services'; + +export const mockServices: Services = { + ...coreMock.createStart(), + securitySolution: securitySolutionMock.createStart(), +}; diff --git a/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx new file mode 100644 index 0000000000000..710a9b378adad --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/common/__mocks__/services.tsx @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mockServices } from './services.mock'; + +export const useKibana = jest.fn(() => ({ services: mockServices })); diff --git a/x-pack/plugins/ess_security/public/common/hooks/__mocks__/use_variation.ts b/x-pack/plugins/security_solution_ess/public/common/hooks/__mocks__/use_variation.ts similarity index 100% rename from x-pack/plugins/ess_security/public/common/hooks/__mocks__/use_variation.ts rename to x-pack/plugins/security_solution_ess/public/common/hooks/__mocks__/use_variation.ts diff --git a/x-pack/plugins/ess_security/public/common/hooks/use_variation.test.ts b/x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.test.ts similarity index 100% rename from x-pack/plugins/ess_security/public/common/hooks/use_variation.test.ts rename to x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.test.ts diff --git a/x-pack/plugins/ess_security/public/common/hooks/use_variation.ts b/x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.ts similarity index 100% rename from x-pack/plugins/ess_security/public/common/hooks/use_variation.ts rename to x-pack/plugins/security_solution_ess/public/common/hooks/use_variation.ts diff --git a/x-pack/plugins/ess_security/public/services.tsx b/x-pack/plugins/security_solution_ess/public/common/services.tsx similarity index 59% rename from x-pack/plugins/ess_security/public/services.tsx rename to x-pack/plugins/security_solution_ess/public/common/services.tsx index ef8c0db8e792f..d00fd10350a7d 100644 --- a/x-pack/plugins/ess_security/public/services.tsx +++ b/x-pack/plugins/security_solution_ess/public/common/services.tsx @@ -5,22 +5,27 @@ * 2.0. */ -import { CoreStart } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; import React from 'react'; import { KibanaContextProvider, useKibana as useKibanaReact, } from '@kbn/kibana-react-plugin/public'; -import type { EssSecurityPluginStartDependencies } from './types'; +import type { SecuritySolutionEssPluginStartDeps } from '../types'; -export type Services = CoreStart & EssSecurityPluginStartDependencies; +export type Services = CoreStart & SecuritySolutionEssPluginStartDeps; export const KibanaServicesProvider: React.FC<{ - core: CoreStart; - pluginsStart: EssSecurityPluginStartDependencies; -}> = ({ core, pluginsStart, children }) => { - const services: Services = { ...core, ...pluginsStart }; + services: Services; +}> = ({ services, children }) => { return {children}; }; export const useKibana = () => useKibanaReact(); + +export const createServices = ( + core: CoreStart, + pluginsStart: SecuritySolutionEssPluginStartDeps +): Services => { + return { ...core, ...pluginsStart }; +}; diff --git a/x-pack/plugins/ess_security/public/get_started/images/cloud1.svg b/x-pack/plugins/security_solution_ess/public/get_started/images/cloud1.svg similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/images/cloud1.svg rename to x-pack/plugins/security_solution_ess/public/get_started/images/cloud1.svg diff --git a/x-pack/plugins/ess_security/public/get_started/images/endpoint1.svg b/x-pack/plugins/security_solution_ess/public/get_started/images/endpoint1.svg similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/images/endpoint1.svg rename to x-pack/plugins/security_solution_ess/public/get_started/images/endpoint1.svg diff --git a/x-pack/plugins/ess_security/public/get_started/images/siem1.svg b/x-pack/plugins/security_solution_ess/public/get_started/images/siem1.svg similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/images/siem1.svg rename to x-pack/plugins/security_solution_ess/public/get_started/images/siem1.svg diff --git a/x-pack/plugins/security_solution_ess/public/get_started/index.tsx b/x-pack/plugins/security_solution_ess/public/get_started/index.tsx new file mode 100644 index 0000000000000..f85d20afe0c07 --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/get_started/index.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; + +import { KibanaServicesProvider, type Services } from '../common/services'; +import { GetStarted } from './lazy'; + +export const getSecurityGetStartedComponent = (services: Services): React.ComponentType => + function GetStartedComponent() { + return ( + + + + ); + }; diff --git a/x-pack/plugins/ess_security/public/get_started/landing_cards.test.tsx b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.test.tsx similarity index 98% rename from x-pack/plugins/ess_security/public/get_started/landing_cards.test.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/landing_cards.test.tsx index 05ef9d5cf23f4..153d279a6a06e 100644 --- a/x-pack/plugins/ess_security/public/get_started/landing_cards.test.tsx +++ b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.test.tsx @@ -12,7 +12,7 @@ import { ADD_DATA_PATH } from '@kbn/security-solution-plugin/common'; import { useVariation } from '../common/hooks/use_variation'; jest.mock('../common/hooks/use_variation'); -jest.mock('../services'); +jest.mock('../common/services'); describe('LandingCards component', () => { beforeEach(() => { diff --git a/x-pack/plugins/ess_security/public/get_started/landing_cards.tsx b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.tsx similarity index 98% rename from x-pack/plugins/ess_security/public/get_started/landing_cards.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/landing_cards.tsx index eacf3c380a293..91e3c2c5f1fc8 100644 --- a/x-pack/plugins/ess_security/public/get_started/landing_cards.tsx +++ b/x-pack/plugins/security_solution_ess/public/get_started/landing_cards.tsx @@ -12,8 +12,8 @@ import { EuiFlexGroup, EuiFlexItem, EuiPageHeader, - EuiThemeComputed, useEuiTheme, + type EuiThemeComputed, } from '@elastic/eui'; import { css } from '@emotion/react'; import { ADD_DATA_PATH } from '@kbn/security-solution-plugin/common'; @@ -22,7 +22,7 @@ import * as i18n from './translations'; import endpointSvg from './images/endpoint1.svg'; import cloudSvg from './images/cloud1.svg'; import siemSvg from './images/siem1.svg'; -import { useKibana } from '../services'; +import { useKibana } from '../common/services'; const imgUrls = { cloud: cloudSvg, diff --git a/x-pack/plugins/ess_security/public/get_started/lazy.tsx b/x-pack/plugins/security_solution_ess/public/get_started/lazy.tsx similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/lazy.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/lazy.tsx diff --git a/x-pack/plugins/ess_security/public/get_started/translations.tsx b/x-pack/plugins/security_solution_ess/public/get_started/translations.tsx similarity index 100% rename from x-pack/plugins/ess_security/public/get_started/translations.tsx rename to x-pack/plugins/security_solution_ess/public/get_started/translations.tsx diff --git a/x-pack/plugins/ess_security/public/index.ts b/x-pack/plugins/security_solution_ess/public/index.ts similarity index 62% rename from x-pack/plugins/ess_security/public/index.ts rename to x-pack/plugins/security_solution_ess/public/index.ts index 730b776d97b25..3a26496d3692d 100644 --- a/x-pack/plugins/ess_security/public/index.ts +++ b/x-pack/plugins/security_solution_ess/public/index.ts @@ -5,13 +5,13 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/public'; -import { EssSecurityPlugin } from './plugin'; +import type { PluginInitializerContext } from '@kbn/core/public'; +import { SecuritySolutionEssPlugin } from './plugin'; // This exports static code and TypeScript types, // as well as, Kibana Platform `plugin()` initializer. export function plugin(_initializerContext: PluginInitializerContext) { - return new EssSecurityPlugin(); + return new SecuritySolutionEssPlugin(); } -export type { EssSecurityPluginSetup, EssSecurityPluginStart } from './types'; +export type { SecuritySolutionEssPluginSetup, SecuritySolutionEssPluginStart } from './types'; diff --git a/x-pack/plugins/security_solution_ess/public/jest.config.js b/x-pack/plugins/security_solution_ess/public/jest.config.js new file mode 100644 index 0000000000000..fac3d4ceba420 --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/jest.config.js @@ -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. + */ +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + /** all nested directories have their own Jest config file */ + testMatch: ['/x-pack/plugins/security_solution_ess/public/**/*.test.{js,mjs,ts,tsx}'], + roots: ['/x-pack/plugins/security_solution_ess/public'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution_ess/public', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution_ess/public/**/*.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', + '!/x-pack/plugins/security_solution_ess/public/*mock*.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_ess/public/*.d.ts', + '!/x-pack/plugins/security_solution_ess/public/*.config.ts', + '!/x-pack/plugins/security_solution_ess/public/index.{js,ts,tsx}', + ], +}; diff --git a/x-pack/plugins/security_solution_ess/public/plugin.ts b/x-pack/plugins/security_solution_ess/public/plugin.ts new file mode 100644 index 0000000000000..7224a46f682e4 --- /dev/null +++ b/x-pack/plugins/security_solution_ess/public/plugin.ts @@ -0,0 +1,49 @@ +/* + * 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 { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { subscribeBreadcrumbs } from './breadcrumbs'; +import { createServices } from './common/services'; +import { getSecurityGetStartedComponent } from './get_started'; +import type { + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps, +} from './types'; + +export class SecuritySolutionEssPlugin + implements + Plugin< + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps + > +{ + public setup( + _core: CoreSetup, + _setupDeps: SecuritySolutionEssPluginSetupDeps + ): SecuritySolutionEssPluginSetup { + return {}; + } + + public start( + core: CoreStart, + startDeps: SecuritySolutionEssPluginStartDeps + ): SecuritySolutionEssPluginStart { + const { securitySolution } = startDeps; + const services = createServices(core, startDeps); + + securitySolution.setGetStartedPage(getSecurityGetStartedComponent(services)); + subscribeBreadcrumbs(services); + + return {}; + } + + public stop() {} +} diff --git a/x-pack/plugins/ess_security/public/types.ts b/x-pack/plugins/security_solution_ess/public/types.ts similarity index 69% rename from x-pack/plugins/ess_security/public/types.ts rename to x-pack/plugins/security_solution_ess/public/types.ts index 3ba22c5f0ff31..2bdeeffebf723 100644 --- a/x-pack/plugins/ess_security/public/types.ts +++ b/x-pack/plugins/security_solution_ess/public/types.ts @@ -9,19 +9,19 @@ import type { PluginSetup as SecuritySolutionPluginSetup, PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/public'; -import { CloudExperimentsPluginStart } from '@kbn/cloud-experiments-plugin/common'; +import type { CloudExperimentsPluginStart } from '@kbn/cloud-experiments-plugin/common'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginSetup {} +export interface SecuritySolutionEssPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginStart {} +export interface SecuritySolutionEssPluginStart {} -export interface EssSecurityPluginSetupDependencies { +export interface SecuritySolutionEssPluginSetupDeps { securitySolution: SecuritySolutionPluginSetup; } -export interface EssSecurityPluginStartDependencies { +export interface SecuritySolutionEssPluginStartDeps { securitySolution: SecuritySolutionPluginStart; cloudExperiments?: CloudExperimentsPluginStart; } diff --git a/x-pack/plugins/ess_security/server/config.ts b/x-pack/plugins/security_solution_ess/server/config.ts similarity index 80% rename from x-pack/plugins/ess_security/server/config.ts rename to x-pack/plugins/security_solution_ess/server/config.ts index 1d03beec8e263..48e96989859f5 100644 --- a/x-pack/plugins/ess_security/server/config.ts +++ b/x-pack/plugins/security_solution_ess/server/config.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { schema, TypeOf } from '@kbn/config-schema'; -import { PluginConfigDescriptor } from '@kbn/core/server'; +import { schema, type TypeOf } from '@kbn/config-schema'; +import type { PluginConfigDescriptor } from '@kbn/core/server'; export const configSchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), diff --git a/x-pack/plugins/ess_security/server/constants.ts b/x-pack/plugins/security_solution_ess/server/constants.ts similarity index 100% rename from x-pack/plugins/ess_security/server/constants.ts rename to x-pack/plugins/security_solution_ess/server/constants.ts diff --git a/x-pack/plugins/ess_security/server/index.ts b/x-pack/plugins/security_solution_ess/server/index.ts similarity index 64% rename from x-pack/plugins/ess_security/server/index.ts rename to x-pack/plugins/security_solution_ess/server/index.ts index a6dbcaa2893b7..ebb28fda2cf0a 100644 --- a/x-pack/plugins/ess_security/server/index.ts +++ b/x-pack/plugins/security_solution_ess/server/index.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/server'; +import type { PluginInitializerContext } from '@kbn/core/server'; -import { EssSecurityPlugin } from './plugin'; +import { SecuritySolutionEssPlugin } from './plugin'; export { config } from './config'; // This exports static code and TypeScript types, // as well as, Kibana Platform `plugin()` initializer. export function plugin(_initializerContext: PluginInitializerContext) { - return new EssSecurityPlugin(); + return new SecuritySolutionEssPlugin(); } -export type { EssSecurityPluginSetup, EssSecurityPluginStart } from './types'; +export type { SecuritySolutionEssPluginSetup, SecuritySolutionEssPluginStart } from './types'; diff --git a/x-pack/plugins/ess_security/server/plugin.ts b/x-pack/plugins/security_solution_ess/server/plugin.ts similarity index 50% rename from x-pack/plugins/ess_security/server/plugin.ts rename to x-pack/plugins/security_solution_ess/server/plugin.ts index d845216ad722b..0083fe1314cfd 100644 --- a/x-pack/plugins/ess_security/server/plugin.ts +++ b/x-pack/plugins/security_solution_ess/server/plugin.ts @@ -5,28 +5,26 @@ * 2.0. */ -import { Plugin, CoreSetup } from '@kbn/core/server'; +import type { Plugin, CoreSetup } from '@kbn/core/server'; import { DEFAULT_APP_FEATURES } from './constants'; -import { - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies, +import type { + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps, } from './types'; -export class EssSecurityPlugin +export class SecuritySolutionEssPlugin implements Plugin< - EssSecurityPluginSetup, - EssSecurityPluginStart, - EssSecurityPluginSetupDependencies, - EssSecurityPluginStartDependencies + SecuritySolutionEssPluginSetup, + SecuritySolutionEssPluginStart, + SecuritySolutionEssPluginSetupDeps, + SecuritySolutionEssPluginStartDeps > { - constructor() {} - - public setup(_coreSetup: CoreSetup, pluginsSetup: EssSecurityPluginSetupDependencies) { + public setup(_coreSetup: CoreSetup, pluginsSetup: SecuritySolutionEssPluginSetupDeps) { pluginsSetup.securitySolution.setAppFeatures(DEFAULT_APP_FEATURES); return {}; } diff --git a/x-pack/plugins/ess_security/server/types.ts b/x-pack/plugins/security_solution_ess/server/types.ts similarity index 73% rename from x-pack/plugins/ess_security/server/types.ts rename to x-pack/plugins/security_solution_ess/server/types.ts index d90729e77be4b..37dd38d76ed77 100644 --- a/x-pack/plugins/ess_security/server/types.ts +++ b/x-pack/plugins/security_solution_ess/server/types.ts @@ -5,20 +5,20 @@ * 2.0. */ -import { +import type { PluginSetup as SecuritySolutionPluginSetup, PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/server'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginSetup {} +export interface SecuritySolutionEssPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface EssSecurityPluginStart {} +export interface SecuritySolutionEssPluginStart {} -export interface EssSecurityPluginSetupDependencies { +export interface SecuritySolutionEssPluginSetupDeps { securitySolution: SecuritySolutionPluginSetup; } -export interface EssSecurityPluginStartDependencies { +export interface SecuritySolutionEssPluginStartDeps { securitySolution: SecuritySolutionPluginStart; } diff --git a/x-pack/plugins/ess_security/tsconfig.json b/x-pack/plugins/security_solution_ess/tsconfig.json similarity index 92% rename from x-pack/plugins/ess_security/tsconfig.json rename to x-pack/plugins/security_solution_ess/tsconfig.json index f28c81c6c59ec..c37fc77790254 100644 --- a/x-pack/plugins/ess_security/tsconfig.json +++ b/x-pack/plugins/security_solution_ess/tsconfig.json @@ -11,9 +11,7 @@ "server/**/*.ts", "../../../typings/**/*" ], - "exclude": [ - "target/**/*" - ], + "exclude": ["target/**/*"], "kbn_references": [ "@kbn/core", "@kbn/config-schema", diff --git a/x-pack/plugins/serverless_security/.gitignore b/x-pack/plugins/security_solution_serverless/.gitignore similarity index 100% rename from x-pack/plugins/serverless_security/.gitignore rename to x-pack/plugins/security_solution_serverless/.gitignore diff --git a/x-pack/plugins/security_solution_serverless/README.mdx b/x-pack/plugins/security_solution_serverless/README.mdx new file mode 100755 index 0000000000000..a9e20bf8147a4 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/README.mdx @@ -0,0 +1,4 @@ +# Serverless Security project plugin + +This plugin contains configuration and code used to create a Serverless Security project. +It leverages universal configuration and other APIs in the [`serverless`](../serverless/README.mdx) plugin to configure Kibana. \ No newline at end of file diff --git a/x-pack/plugins/serverless_security/common/config.ts b/x-pack/plugins/security_solution_serverless/common/config.ts similarity index 77% rename from x-pack/plugins/serverless_security/common/config.ts rename to x-pack/plugins/security_solution_serverless/common/config.ts index 63b173ff3930e..cc661da4af1a9 100644 --- a/x-pack/plugins/serverless_security/common/config.ts +++ b/x-pack/plugins/security_solution_serverless/common/config.ts @@ -5,13 +5,8 @@ * 2.0. */ -import { schema, TypeOf } from '@kbn/config-schema'; - -export enum ProductLine { - security = 'security', - cloud = 'cloud', - endpoint = 'endpoint', -} +import { schema, type TypeOf } from '@kbn/config-schema'; +import { ProductLine, ProductTier } from './product'; export const productLine = schema.oneOf([ schema.literal(ProductLine.security), @@ -21,7 +16,10 @@ export const productLine = schema.oneOf([ export type SecurityProductLine = TypeOf; -export const productTier = schema.oneOf([schema.literal('essentials'), schema.literal('complete')]); +export const productTier = schema.oneOf([ + schema.literal(ProductTier.essentials), + schema.literal(ProductTier.complete), +]); export type SecurityProductTier = TypeOf; export const productType = schema.object({ diff --git a/x-pack/plugins/serverless_security/common/index.ts b/x-pack/plugins/security_solution_serverless/common/index.ts similarity index 69% rename from x-pack/plugins/serverless_security/common/index.ts rename to x-pack/plugins/security_solution_serverless/common/index.ts index 0dc5be6ddf9bb..e6a263165b00e 100644 --- a/x-pack/plugins/serverless_security/common/index.ts +++ b/x-pack/plugins/security_solution_serverless/common/index.ts @@ -5,5 +5,5 @@ * 2.0. */ -export const PLUGIN_ID = 'serverlessSecurity'; -export const PLUGIN_NAME = 'serverlessSecurity'; +export const PLUGIN_ID = 'securitySolutionServerless'; +export const PLUGIN_NAME = 'securitySolutionServerless'; diff --git a/x-pack/plugins/security_solution_serverless/common/jest.config.js b/x-pack/plugins/security_solution_serverless/common/jest.config.js new file mode 100644 index 0000000000000..01ea1139d6e44 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/common/jest.config.js @@ -0,0 +1,28 @@ +/* + * 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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/x-pack/plugins/security_solution_serverless/common'], + testMatch: [ + '/x-pack/plugins/security_solution_serverless/common/**/*.test.{js,mjs,ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution_serverless/common', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution_serverless/common/**/*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', + '!/x-pack/plugins/security_solution_serverless/common/*mock*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/common/*.d.ts', + '!/x-pack/plugins/security_solution_serverless/common/*.config.ts', + '!/x-pack/plugins/security_solution_serverless/common/index.{js,ts,tsx}', + ], +}; diff --git a/x-pack/plugins/serverless_security/common/pli/pli_config.ts b/x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts similarity index 100% rename from x-pack/plugins/serverless_security/common/pli/pli_config.ts rename to x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts diff --git a/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts b/x-pack/plugins/security_solution_serverless/common/pli/pli_features.test.ts similarity index 80% rename from x-pack/plugins/serverless_security/common/pli/pli_features.test.ts rename to x-pack/plugins/security_solution_serverless/common/pli/pli_features.test.ts index c00f8d7fdd9ec..3358ee69a4250 100644 --- a/x-pack/plugins/serverless_security/common/pli/pli_features.test.ts +++ b/x-pack/plugins/security_solution_serverless/common/pli/pli_features.test.ts @@ -6,7 +6,7 @@ */ import { getProductAppFeatures } from './pli_features'; import * as pliConfig from './pli_config'; -import { ProductLine } from '../config'; +import { ProductLine, ProductTier } from '../product'; describe('getProductAppFeatures', () => { it('should return the essentials PLIs features', () => { @@ -19,7 +19,7 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: ProductLine.security, product_tier: 'essentials' }, + { product_line: ProductLine.security, product_tier: ProductTier.essentials }, ]); expect(appFeatureKeys).toEqual(['foo']); @@ -35,7 +35,7 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: ProductLine.security, product_tier: 'complete' }, + { product_line: ProductLine.security, product_tier: ProductTier.complete }, ]); expect(appFeatureKeys).toEqual(['foo', 'baz']); @@ -59,9 +59,9 @@ describe('getProductAppFeatures', () => { }; const appFeatureKeys = getProductAppFeatures([ - { product_line: ProductLine.security, product_tier: 'essentials' }, - { product_line: ProductLine.endpoint, product_tier: 'complete' }, - { product_line: ProductLine.cloud, product_tier: 'essentials' }, + { product_line: ProductLine.security, product_tier: ProductTier.essentials }, + { product_line: ProductLine.endpoint, product_tier: ProductTier.complete }, + { product_line: ProductLine.cloud, product_tier: ProductTier.essentials }, ]); expect(appFeatureKeys).toEqual(['foo', 'bar', 'repeated', 'qux', 'quux', 'corge', 'garply']); diff --git a/x-pack/plugins/serverless_security/common/pli/pli_features.ts b/x-pack/plugins/security_solution_serverless/common/pli/pli_features.ts similarity index 100% rename from x-pack/plugins/serverless_security/common/pli/pli_features.ts rename to x-pack/plugins/security_solution_serverless/common/pli/pli_features.ts diff --git a/x-pack/plugins/security_solution_serverless/common/product.ts b/x-pack/plugins/security_solution_serverless/common/product.ts new file mode 100644 index 0000000000000..d5095eea31637 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/common/product.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. + */ + +export enum ProductLine { + security = 'security', + endpoint = 'endpoint', + cloud = 'cloud', +} + +export enum ProductTier { + essentials = 'essentials', + complete = 'complete', +} diff --git a/x-pack/plugins/security_solution_serverless/jest.config.dev.js b/x-pack/plugins/security_solution_serverless/jest.config.dev.js new file mode 100644 index 0000000000000..2591fcc775ab0 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/jest.config.dev.js @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../', + projects: ['/x-pack/plugins/security_solution_serverless/public/jest.config.js'], +}; diff --git a/x-pack/plugins/serverless_security/kibana.jsonc b/x-pack/plugins/security_solution_serverless/kibana.jsonc similarity index 74% rename from x-pack/plugins/serverless_security/kibana.jsonc rename to x-pack/plugins/security_solution_serverless/kibana.jsonc index 306918ed70697..c9895ac040f34 100644 --- a/x-pack/plugins/serverless_security/kibana.jsonc +++ b/x-pack/plugins/security_solution_serverless/kibana.jsonc @@ -1,16 +1,15 @@ { "type": "plugin", - "id": "@kbn/serverless-security", + "id": "@kbn/security-solution-serverless", "owner": "@elastic/security-solution", "description": "Serverless customizations for security.", "plugin": { - "id": "serverlessSecurity", + "id": "securitySolutionServerless", "server": true, "browser": true, "configPath": [ "xpack", - "serverless", - "security" + "securitySolutionServerless", ], "requiredPlugins": [ "kibanaReact", @@ -21,7 +20,7 @@ "serverless" ], "optionalPlugins": [ - "essSecurity" + "securitySolutionEss" ], "requiredBundles": ["kibanaUtils"] } diff --git a/x-pack/plugins/ess_security/package.json b/x-pack/plugins/security_solution_serverless/package.json similarity index 83% rename from x-pack/plugins/ess_security/package.json rename to x-pack/plugins/security_solution_serverless/package.json index 1ea768291aff0..745afbe7d97c6 100644 --- a/x-pack/plugins/ess_security/package.json +++ b/x-pack/plugins/security_solution_serverless/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/ess-security", + "name": "@kbn/security-solution-serverless", "version": "1.0.0", "license": "Elastic License 2.0", "private": true, diff --git a/x-pack/plugins/serverless_security/public/common/services.mock.tsx b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.mock.tsx similarity index 75% rename from x-pack/plugins/serverless_security/public/common/services.mock.tsx rename to x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.mock.tsx index a3aba806af18c..e4b1c777191ef 100644 --- a/x-pack/plugins/serverless_security/public/common/services.mock.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.mock.tsx @@ -13,12 +13,12 @@ import { securityMock } from '@kbn/security-plugin/public/mocks'; import { securitySolutionMock } from '@kbn/security-solution-plugin/public/mocks'; import { BehaviorSubject } from 'rxjs'; import { managementPluginMock } from '@kbn/management-plugin/public/mocks'; -import type { ProjectNavigationLink } from './navigation/links'; -import type { Services } from './services'; +import type { ProjectNavigationLink } from '../../navigation/links'; +import type { Services } from '../services'; export const mockProjectNavLinks = jest.fn((): ProjectNavigationLink[] => []); -export const servicesMocks: Services = { +export const mockServices: Services = { ...coreMock.createStart(), serverless: serverlessMock.createStart(), security: securityMock.createStart(), @@ -27,8 +27,10 @@ export const servicesMocks: Services = { management: managementPluginMock.createStartContract(), }; -export const KibanaServicesProvider = React.memo(({ children }) => ( - - {children} - -)); +export const ServicesWrapper = React.memo(function ServicesWrapper({ children }) { + return ( + + {children} + + ); +}); diff --git a/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx new file mode 100644 index 0000000000000..5c6d2f1117c64 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/common/__mocks__/services.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { I18nProvider } from '@kbn/i18n-react'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { mockServices } from './services.mock'; + +export const KibanaServicesProvider: React.FC = ({ children }) => ( + + {children} + +); + +export const useKibana = jest.fn(() => ({ services: mockServices })); diff --git a/x-pack/plugins/serverless_security/public/hooks/__mocks__/use_link_props.ts b/x-pack/plugins/security_solution_serverless/public/common/hooks/__mocks__/use_link_props.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/hooks/__mocks__/use_link_props.ts rename to x-pack/plugins/security_solution_serverless/public/common/hooks/__mocks__/use_link_props.ts diff --git a/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.test.tsx similarity index 82% rename from x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx rename to x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.test.tsx index 2a20ca97ef855..5b4d215e331ea 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_link_props.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.test.tsx @@ -5,15 +5,18 @@ * 2.0. */ -import { MouseEvent } from 'react'; +import type { MouseEvent } from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { KibanaServicesProvider, servicesMocks } from '../common/services.mock'; +import { mockServices } from '../__mocks__/services.mock'; import { useGetLinkProps, useLinkProps } from './use_link_props'; -const { getUrlForApp, navigateToUrl: mockNavigateToUrl } = servicesMocks.application; +jest.mock('../services'); const href = '/app/security/test'; + +const { getUrlForApp, navigateToUrl } = mockServices.application; +const mockNavigateToUrl = navigateToUrl as jest.MockedFunction; const mockGetUrlForApp = getUrlForApp as jest.MockedFunction; mockGetUrlForApp.mockReturnValue(href); @@ -23,7 +26,7 @@ describe('useLinkProps', () => { }); it('should return link props', async () => { - const { result } = renderHook(useLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useLinkProps); const linkProps = result.current; @@ -37,7 +40,7 @@ describe('useLinkProps', () => { it('should call navigate when clicked normally', async () => { const ev = { preventDefault: jest.fn() } as unknown as MouseEvent; - const { result } = renderHook(useLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useLinkProps); const { onClick } = result.current; onClick(ev); @@ -48,7 +51,7 @@ describe('useLinkProps', () => { it('should not call navigate when clicked with modifiers', async () => { const ev = { preventDefault: jest.fn(), ctrlKey: true } as unknown as MouseEvent; - const { result } = renderHook(useLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useLinkProps); const { onClick } = result.current; onClick(ev); @@ -58,7 +61,6 @@ describe('useLinkProps', () => { it('should return link props passing deepLink', async () => { const { result } = renderHook(useLinkProps, { - wrapper: KibanaServicesProvider, initialProps: { deepLinkId: SecurityPageName.alerts }, }); @@ -74,7 +76,6 @@ describe('useLinkProps', () => { it('should return link props passing deepLink and path', async () => { const { result } = renderHook(useLinkProps, { - wrapper: KibanaServicesProvider, initialProps: { deepLinkId: SecurityPageName.alerts, path: '/test' }, }); @@ -95,7 +96,7 @@ describe('useGetLinkProps', () => { }); it('should return link props', async () => { - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const linkProps = result.current({}); @@ -109,7 +110,7 @@ describe('useGetLinkProps', () => { it('should call navigate when clicked normally', async () => { const ev = { preventDefault: jest.fn() } as unknown as MouseEvent; - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const { onClick } = result.current({}); onClick(ev); @@ -120,7 +121,7 @@ describe('useGetLinkProps', () => { it('should not call navigate when clicked with modifiers', async () => { const ev = { preventDefault: jest.fn(), ctrlKey: true } as unknown as MouseEvent; - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const { onClick } = result.current({}); onClick(ev); @@ -129,7 +130,7 @@ describe('useGetLinkProps', () => { }); it('should return link props passing deepLink', async () => { - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const linkProps = result.current({ deepLinkId: SecurityPageName.alerts }); @@ -142,7 +143,7 @@ describe('useGetLinkProps', () => { }); it('should return link props passing deepLink and path', async () => { - const { result } = renderHook(useGetLinkProps, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useGetLinkProps); const linkProps = result.current({ deepLinkId: SecurityPageName.alerts, path: '/test' }); diff --git a/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.ts similarity index 96% rename from x-pack/plugins/serverless_security/public/hooks/use_link_props.ts rename to x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.ts index 6644afb7fdf01..3a1989dbdc79a 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_link_props.ts +++ b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_link_props.ts @@ -7,7 +7,7 @@ import { APP_UI_ID, type SecurityPageName } from '@kbn/security-solution-plugin/common'; import { useMemo, useCallback, type MouseEventHandler, type MouseEvent } from 'react'; -import { useKibana, type Services } from '../common/services'; +import { useKibana, type Services } from '../services'; interface LinkProps { onClick: MouseEventHandler; diff --git a/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_nav_links.ts similarity index 92% rename from x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts rename to x-pack/plugins/security_solution_serverless/public/common/hooks/use_nav_links.ts index eaa643603f86d..625e836223822 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_nav_links.ts +++ b/x-pack/plugins/security_solution_serverless/public/common/hooks/use_nav_links.ts @@ -7,7 +7,7 @@ import { useMemo } from 'react'; import useObservable from 'react-use/lib/useObservable'; -import { useKibana } from '../common/services'; +import { useKibana } from '../services'; export const useNavLinks = () => { const { getProjectNavLinks$ } = useKibana().services; diff --git a/x-pack/plugins/serverless_security/public/lib/__mocks__/storage.ts b/x-pack/plugins/security_solution_serverless/public/common/lib/__mocks__/storage.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/lib/__mocks__/storage.ts rename to x-pack/plugins/security_solution_serverless/public/common/lib/__mocks__/storage.ts diff --git a/x-pack/plugins/serverless_security/public/lib/storage.ts b/x-pack/plugins/security_solution_serverless/public/common/lib/storage.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/lib/storage.ts rename to x-pack/plugins/security_solution_serverless/public/common/lib/storage.ts diff --git a/x-pack/plugins/serverless_security/public/common/services.tsx b/x-pack/plugins/security_solution_serverless/public/common/services.tsx similarity index 74% rename from x-pack/plugins/serverless_security/public/common/services.tsx rename to x-pack/plugins/security_solution_serverless/public/common/services.tsx index f3bfe1dbbfa1b..799b2e5913c0a 100644 --- a/x-pack/plugins/serverless_security/public/common/services.tsx +++ b/x-pack/plugins/security_solution_serverless/public/common/services.tsx @@ -5,20 +5,20 @@ * 2.0. */ -import { CoreStart } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; import React from 'react'; import { KibanaContextProvider, useKibana as useKibanaReact, } from '@kbn/kibana-react-plugin/public'; -import type { ServerlessSecurityPluginStartDependencies } from '../types'; -import { getProjectNavLinks$, type ProjectNavLinks } from './navigation/links'; +import type { SecuritySolutionServerlessPluginStartDeps } from '../types'; +import { getProjectNavLinks$, type ProjectNavLinks } from '../navigation/links'; interface InternalServices { getProjectNavLinks$: () => ProjectNavLinks; } -export type Services = CoreStart & ServerlessSecurityPluginStartDependencies & InternalServices; +export type Services = CoreStart & SecuritySolutionServerlessPluginStartDeps & InternalServices; export const KibanaServicesProvider: React.FC<{ services: Services; @@ -30,7 +30,7 @@ export const useKibana = () => useKibanaReact(); export const createServices = ( core: CoreStart, - pluginsStart: ServerlessSecurityPluginStartDependencies + pluginsStart: SecuritySolutionServerlessPluginStartDeps ): Services => { const { securitySolution } = pluginsStart; const projectNavLinks$ = getProjectNavLinks$(securitySolution.getNavLinks$()); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/card_step.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/card_step.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/card_step.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/card_step.tsx diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/product_switch.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/product_switch.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/product_switch.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/product_switch.tsx diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/__mocks__/storage.ts b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/storage.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/lib/get_started/__mocks__/storage.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/storage.ts diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/toggle_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/toggle_panel.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/toggle_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/toggle_panel.tsx diff --git a/x-pack/plugins/serverless_security/public/components/get_started/__mocks__/welcome_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/welcome_panel.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/__mocks__/welcome_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/__mocks__/welcome_panel.tsx diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_item.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.test.tsx similarity index 92% rename from x-pack/plugins/serverless_security/public/components/get_started/card_item.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_item.test.tsx index aacd3f520d9cf..c132eb72bb359 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_item.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.test.tsx @@ -7,8 +7,9 @@ import React from 'react'; import { render } from '@testing-library/react'; import { CardItem } from './card_item'; -import { CardId, GetSetUpCardId, IntroductionSteps, SectionId, StepId } from './types'; -import { EuiThemeComputed } from '@elastic/eui'; +import type { CardId, StepId } from './types'; +import { GetSetUpCardId, IntroductionSteps, SectionId } from './types'; +import type { EuiThemeComputed } from '@elastic/eui'; jest.mock('./card_step'); describe('CardItemComponent', () => { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_item.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.tsx similarity index 90% rename from x-pack/plugins/serverless_security/public/components/get_started/card_item.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_item.tsx index 4abb71354b641..2dbd6da34d992 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_item.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_item.tsx @@ -5,18 +5,11 @@ * 2.0. */ -import { - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiPanel, - EuiText, - EuiThemeComputed, - EuiTitle, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiPanel, EuiText, EuiTitle } from '@elastic/eui'; +import type { EuiThemeComputed } from '@elastic/eui'; import React, { useCallback, useState } from 'react'; import { css } from '@emotion/react'; -import { CardId, SectionId, StepId } from './types'; +import type { CardId, SectionId, StepId } from './types'; import * as i18n from './translations'; import { CardStep } from './card_step'; import { getSections } from './sections'; @@ -102,7 +95,10 @@ const CardItemComponent: React.FC<{ {i18n.STEPS_LEFT(stepsLeft)} )} {timeInMins != null && timeInMins > 0 && ( - • {i18n.STEP_TIME_MIN(timeInMins)} + + {' • '} + {i18n.STEP_TIME_MIN(timeInMins)} + )} diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_step.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.test.tsx similarity index 94% rename from x-pack/plugins/serverless_security/public/components/get_started/card_step.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_step.test.tsx index d5fe2433a9fab..9e72370f179e8 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_step.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.test.tsx @@ -7,7 +7,8 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { CardStep } from './card_step'; -import { GetSetUpCardId, IntroductionSteps, SectionId, StepId } from './types'; +import type { StepId } from './types'; +import { GetSetUpCardId, IntroductionSteps, SectionId } from './types'; describe('CardStepComponent', () => { const step = { @@ -18,7 +19,7 @@ describe('CardStepComponent', () => { { id: 'badge2', name: 'Badge 2' }, ], description: ['Description line 1', 'Description line 2'], - splitPanel:
    Split Panel
    , + splitPanel:
    {'Split Panel'}
    , }; const onStepClicked = jest.fn(); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/card_step.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.tsx similarity index 97% rename from x-pack/plugins/serverless_security/public/components/get_started/card_step.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/card_step.tsx index 67d683edaac5e..137895b9bb078 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/card_step.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/card_step.tsx @@ -18,7 +18,7 @@ import { import { css } from '@emotion/react'; import React, { useCallback, useState } from 'react'; -import { CardId, SectionId, Step, StepId } from './types'; +import type { CardId, SectionId, Step, StepId } from './types'; import step from './images/step.svg'; const CardStepComponent: React.FC<{ diff --git a/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.test.tsx similarity index 94% rename from x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/get_started.test.tsx index ddf0b17985223..51896789c6b31 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/get_started.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { GetStartedComponent } from './get_started'; -import { SecurityProductTypes } from '../../../common/config'; +import type { SecurityProductTypes } from '../../common/config'; jest.mock('./toggle_panel'); jest.mock('./welcome_panel'); @@ -32,7 +32,7 @@ describe('GetStartedComponent', () => { const { getByText } = render(); const pageTitle = getByText('Welcome'); - const subtitle = getByText('Let’s get started'); + const subtitle = getByText(`Let's get started`); const description = getByText( `Set up your Elastic Security workspace. Use the toggles below to curate a list of tasks that best fits your environment` ); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/get_started.tsx index b29ba3b30d6a4..55550495e6e13 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/get_started.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/get_started.tsx @@ -17,15 +17,17 @@ import { GET_STARTED_PAGE_SUBTITLE, GET_STARTED_PAGE_TITLE, } from './translations'; -import { SecurityProductTypes } from '../../../common/config'; +import type { SecurityProductTypes } from '../../common/config'; import { ProductSwitch } from './product_switch'; import { useTogglePanel } from './use_toggle_panel'; const CONTENT_WIDTH = 1150; -export const GetStartedComponent: React.FC<{ productTypes: SecurityProductTypes }> = ({ - productTypes, -}) => { +export interface GetStartedProps { + productTypes: SecurityProductTypes; +} + +export const GetStartedComponent: React.FC = ({ productTypes }) => { const { euiTheme } = useEuiTheme(); const shadow = useEuiShadow('s'); const { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.test.ts similarity index 98% rename from x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/helpers.test.ts index f5511d4eaa85d..050d42fbec573 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/helpers.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.test.ts @@ -12,19 +12,15 @@ import { setupCards, updateCard, } from './helpers'; +import type { ActiveCards, Card, CardId, Section, StepId } from './types'; import { - ActiveCards, - Card, - CardId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, IntroductionSteps, - Section, SectionId, - StepId, } from './types'; import * as sectionsConfigs from './sections'; -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; const mockSections = jest.spyOn(sectionsConfigs, 'getSections'); describe('getCardTimeInMinutes', () => { it('should calculate the total time in minutes for a card correctly', () => { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.ts similarity index 92% rename from x-pack/plugins/serverless_security/public/components/get_started/helpers.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/helpers.ts index 0042550a34c4b..202e00dc1a40a 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/helpers.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/helpers.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; +import type { ProductLine } from '../../common/product'; import { getSections } from './sections'; -import { ActiveCard, ActiveCards, Card, CardId, SectionId, StepId } from './types'; +import type { ActiveCard, ActiveCards, Card, CardId, SectionId, StepId } from './types'; export const getCardTimeInMinutes = (card: Card, stepsDone: Set) => card.steps?.reduce( (totalMin, { timeInMinutes, id: stepId }) => - (totalMin += stepsDone.has(stepId) ? 0 : timeInMinutes ?? 0), + totalMin + (stepsDone.has(stepId) ? 0 : timeInMinutes ?? 0), 0 ) ?? 0; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/invite.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/invite.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/invite.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/invite.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/progress.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/progress.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/progress.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/progress.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/protect.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/protect.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/protect.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/protect.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/respond.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/respond.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/respond.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/respond.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/images/step.svg b/x-pack/plugins/security_solution_serverless/public/get_started/images/step.svg similarity index 100% rename from x-pack/plugins/serverless_security/public/components/get_started/images/step.svg rename to x-pack/plugins/security_solution_serverless/public/get_started/images/step.svg diff --git a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/index.tsx similarity index 53% rename from x-pack/plugins/serverless_security/public/components/get_started/index.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/index.tsx index 0ee8c7a1ce62d..c457d47a3da30 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/index.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/index.tsx @@ -7,18 +7,18 @@ import React from 'react'; -import { KibanaServicesProvider, type Services } from '../../common/services'; -import type { GetStartedComponent } from './types'; +import { KibanaServicesProvider, type Services } from '../common/services'; import { GetStarted } from './lazy'; -import { SecurityProductTypes } from '../../../common/config'; +import type { SecurityProductTypes } from '../../common/config'; export const getSecurityGetStartedComponent = ( services: Services, productTypes: SecurityProductTypes -): GetStartedComponent => { - return () => ( - - - - ); -}; +): React.ComponentType => + function GetStartedComponent() { + return ( + + + + ); + }; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/lazy.tsx similarity index 80% rename from x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/lazy.tsx index 3130bbe272f52..99f89ada0055d 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/lazy.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/lazy.tsx @@ -6,13 +6,13 @@ */ import React, { lazy, Suspense } from 'react'; import { EuiLoadingLogo } from '@elastic/eui'; -import { SecurityProductTypes } from '../../../common/config'; +import type { GetStartedProps } from './get_started'; const GetStartedLazy = lazy(() => import('./get_started')); const centerLogoStyle = { display: 'flex', margin: 'auto' }; -export const GetStarted = ({ productTypes }: { productTypes: SecurityProductTypes }) => ( +export const GetStarted = ({ productTypes }: GetStartedProps) => ( }> diff --git a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.test.tsx similarity index 95% rename from x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/product_switch.test.tsx index 29c01ddce5376..5c54c87ccdd21 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { ProductSwitch } from './product_switch'; -import { EuiThemeComputed } from '@elastic/eui'; -import { ProductLine } from '../../../common/config'; +import type { EuiThemeComputed } from '@elastic/eui'; +import { ProductLine } from '../../common/product'; describe('ProductSwitch', () => { const onProductSwitchChangedMock = jest.fn(); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.tsx similarity index 91% rename from x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/product_switch.tsx index 822e5f3e69ca0..62f58caaacd6d 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/product_switch.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/product_switch.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import { EuiPanel, EuiSwitch, EuiText, EuiThemeComputed, EuiTitle } from '@elastic/eui'; +import { EuiPanel, EuiSwitch, EuiText, EuiTitle, type EuiThemeComputed } from '@elastic/eui'; import { css } from '@emotion/react'; import React, { useMemo } from 'react'; -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; import * as i18n from './translations'; -import { Switch } from './types'; +import type { Switch } from './types'; const switches: Switch[] = [ { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.test.ts similarity index 96% rename from x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/reducer.test.ts index 259923080bfaa..fe38c68a1a160 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/reducer.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; import { reducer, getFinishedStepsInitialStates, @@ -13,16 +13,16 @@ import { getActiveCardsInitialStates, } from './reducer'; import { - ActiveCards, - CardId, GetSetUpCardId, GetStartedPageActions, IntroductionSteps, SectionId, - StepId, - ToggleProductAction, - AddFinishedStepAction, GetMoreFromElasticSecurityCardId, + type ActiveCards, + type CardId, + type StepId, + type ToggleProductAction, + type AddFinishedStepAction, } from './types'; describe('reducer', () => { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/reducer.tsx index 403bfb85e0a93..f59911aa11808 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/reducer.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/reducer.tsx @@ -5,15 +5,15 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; +import type { ProductLine } from '../../common/product'; import { setupCards, updateCard } from './helpers'; import { - CardId, + type CardId, + type StepId, + type ToggleProductAction, + type TogglePanelReducer, + type AddFinishedStepAction, GetStartedPageActions, - StepId, - ToggleProductAction, - TogglePanelReducer, - AddFinishedStepAction, } from './types'; export const reducer = ( diff --git a/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/sections.tsx similarity index 95% rename from x-pack/plugins/serverless_security/public/components/get_started/sections.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/sections.tsx index 33dbb6f62aa40..11b15264d53ea 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/sections.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/sections.tsx @@ -5,18 +5,17 @@ * 2.0. */ import React from 'react'; - import { - Section, SectionId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, IntroductionSteps, + type Section, } from './types'; import * as i18n from './translations'; import respond from './images/respond.svg'; import protect from './images/protect.svg'; -import { ProductLine } from '../../../common/config'; +import { ProductLine } from '../../common/product'; export const introductionSteps = [ { @@ -61,7 +60,7 @@ export const sections: Section[] = [ id: GetSetUpCardId.introduction, steps: introductionSteps, timeInMins: introductionSteps.reduce( - (totalMin, { timeInMinutes }) => (totalMin += timeInMinutes), + (totalMin, { timeInMinutes }) => totalMin + timeInMinutes, 0 ), stepsLeft: introductionSteps.length, diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts b/x-pack/plugins/security_solution_serverless/public/get_started/storage.test.ts similarity index 95% rename from x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/storage.test.ts index e55c4ef28948b..a5d013bd5a4e0 100644 --- a/x-pack/plugins/serverless_security/public/lib/get_started/storage.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/storage.test.ts @@ -6,12 +6,12 @@ */ import { getStartedStorage } from './storage'; -import { GetSetUpCardId, IntroductionSteps, StepId } from '../../components/get_started/types'; -import { storage } from '../storage'; -import { MockStorage } from '../__mocks__/storage'; -import { ProductLine } from '../../../common/config'; +import { GetSetUpCardId, IntroductionSteps, type StepId } from './types'; +import { storage } from '../common/lib/storage'; +import type { MockStorage } from '../common/lib/__mocks__/storage'; +import { ProductLine } from '../../common/product'; -jest.mock('../storage'); +jest.mock('../common/lib/storage'); describe('useStorage', () => { const mockStorage = storage as unknown as MockStorage; diff --git a/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts b/x-pack/plugins/security_solution_serverless/public/get_started/storage.ts similarity index 77% rename from x-pack/plugins/serverless_security/public/lib/get_started/storage.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/storage.ts index 1d9c52813c832..e01a0c7064df8 100644 --- a/x-pack/plugins/serverless_security/public/lib/get_started/storage.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/storage.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { ProductLine } from '../../../common/config'; -import { CardId, StepId } from '../../components/get_started/types'; -import { storage } from '../storage'; +import type { ProductLine } from '../../common/product'; +import type { CardId, StepId } from './types'; +import { storage } from '../common/lib/storage'; export const ACTIVE_PRODUCTS_STORAGE_KEY = 'ACTIVE_PRODUCTS'; export const FINISHED_STEPS_STORAGE_KEY = 'FINISHED_STEPS'; @@ -15,11 +15,10 @@ export const FINISHED_STEPS_STORAGE_KEY = 'FINISHED_STEPS'; export const getStartedStorage = { getActiveProductsFromStorage: () => { const activeProducts: ProductLine[] = storage.get(ACTIVE_PRODUCTS_STORAGE_KEY); - return activeProducts ?? new Array(); + return activeProducts ?? []; }, toggleActiveProductsInStorage: (productId: ProductLine) => { - const activeProducts: ProductLine[] = - storage.get(ACTIVE_PRODUCTS_STORAGE_KEY) ?? new Array(); + const activeProducts: ProductLine[] = storage.get(ACTIVE_PRODUCTS_STORAGE_KEY) ?? []; const index = activeProducts.indexOf(productId); if (index < 0) { activeProducts.push(productId); @@ -31,7 +30,7 @@ export const getStartedStorage = { }, getFinishedStepsFromStorageByCardId: (cardId: CardId) => { const finishedSteps = storage.get(FINISHED_STEPS_STORAGE_KEY) ?? {}; - const card: StepId[] = finishedSteps[cardId] ?? new Array(); + const card: StepId[] = finishedSteps[cardId] ?? []; return card; }, getAllFinishedStepsFromStorage: () => { @@ -41,7 +40,7 @@ export const getStartedStorage = { }, addFinishedStepToStorage: (cardId: CardId, stepId: StepId) => { const finishedSteps: Record = storage.get(FINISHED_STEPS_STORAGE_KEY) ?? {}; - const card: StepId[] = finishedSteps[cardId] ?? new Array(); + const card: StepId[] = finishedSteps[cardId] ?? []; if (card.indexOf(stepId) < 0) { card.push(stepId); storage.set(FINISHED_STEPS_STORAGE_KEY, { ...finishedSteps, [cardId]: card }); @@ -49,7 +48,7 @@ export const getStartedStorage = { }, removeFinishedStepFromStorage: (cardId: CardId, stepId: StepId) => { const finishedSteps = storage.get(FINISHED_STEPS_STORAGE_KEY) ?? {}; - const steps: StepId[] = finishedSteps[cardId] ?? new Array(); + const steps: StepId[] = finishedSteps[cardId] ?? []; const index = steps.indexOf(stepId); if (index >= 0) { steps.splice(index, 1); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.test.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.test.tsx index 1a924b70fc45f..57fead23ad57d 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.test.tsx @@ -8,8 +8,9 @@ import React from 'react'; import { render } from '@testing-library/react'; import { TogglePanel } from './toggle_panel'; import { useSetUpCardSections } from './use_setup_cards'; -import { ActiveCards, CardId, GetSetUpCardId, IntroductionSteps, SectionId, StepId } from './types'; -import { ProductLine } from '../../../common/config'; +import type { ActiveCards, CardId, StepId } from './types'; +import { GetSetUpCardId, IntroductionSteps, SectionId } from './types'; +import { ProductLine } from '../../common/product'; jest.mock('@elastic/eui', () => ({ ...jest.requireActual('@elastic/eui'), @@ -17,8 +18,6 @@ jest.mock('@elastic/eui', () => ({ useEuiShadow: jest.fn(), })); -jest.mock('../../lib/get_started/storage'); - jest.mock('./use_setup_cards', () => ({ useSetUpCardSections: jest.fn(), })); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.tsx index af365b83bd80c..a110b33f87545 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/toggle_panel.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/toggle_panel.tsx @@ -13,8 +13,8 @@ import { css } from '@emotion/react'; import * as i18n from './translations'; import { useSetUpCardSections } from './use_setup_cards'; -import { ActiveCards, CardId, IntroductionSteps, SectionId } from './types'; -import { ProductLine } from '../../../common/config'; +import type { ActiveCards, CardId, IntroductionSteps, SectionId } from './types'; +import type { ProductLine } from '../../common/product'; const TogglePanelComponent: React.FC<{ finishedSteps: Record>; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/translations.ts b/x-pack/plugins/security_solution_serverless/public/get_started/translations.ts similarity index 58% rename from x-pack/plugins/serverless_security/public/components/get_started/translations.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/translations.ts index 0f30a03a2ec0e..5f30b5b135d1a 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/translations.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/translations.ts @@ -7,206 +7,215 @@ import { i18n } from '@kbn/i18n'; -export const GET_STARTED_PAGE_TITLE = i18n.translate('xpack.serverlessSecurity.getStarted.title', { - defaultMessage: `Welcome`, -}); +export const GET_STARTED_PAGE_TITLE = i18n.translate( + 'xpack.securitySolutionServerless.getStarted.title', + { + defaultMessage: `Welcome`, + } +); export const GET_STARTED_PAGE_SUBTITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.subTitle', + 'xpack.securitySolutionServerless.getStarted.subTitle', { - defaultMessage: `Let’s get started`, + defaultMessage: `Let's get started`, } ); export const GET_STARTED_PAGE_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.description', + 'xpack.securitySolutionServerless.getStarted.description', { defaultMessage: `Set up your Elastic Security workspace. Use the toggles below to curate a list of tasks that best fits your environment`, } ); export const WELCOME_PANEL_PROJECT_CREATED_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.projectCreated.title', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.projectCreated.title', { defaultMessage: `Project created`, } ); export const WELCOME_PANEL_PROJECT_CREATED_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.projectCreated.description', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.projectCreated.description', { defaultMessage: `View all projects here.`, } ); export const WELCOME_PANEL_INVITE_YOUR_TEAM_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.inviteYourTeam.title', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.inviteYourTeam.title', { defaultMessage: 'Invite your team', } ); export const WELCOME_PANEL_INVITE_YOUR_TEAM_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.inviteYourTeam.description', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.inviteYourTeam.description', { defaultMessage: `Boost security through collaboration`, } ); export const WELCOME_PANEL_PROGRESS_TRACKER_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.welcomePanel.progressTracker.title', + 'xpack.securitySolutionServerless.getStarted.welcomePanel.progressTracker.title', { defaultMessage: 'Progress tracker', } ); export const STEP_TIME_MIN = (min: number) => - i18n.translate('xpack.serverlessSecurity.getStarted.togglePanel.progressTracker.stepTimeMin', { - defaultMessage: 'About {min} {min, plural, =1 {min} other {mins}}', - values: { min }, - }); + i18n.translate( + 'xpack.securitySolutionServerless.getStarted.togglePanel.progressTracker.stepTimeMin', + { + defaultMessage: 'About {min} {min, plural, =1 {min} other {mins}}', + values: { min }, + } + ); export const STEPS_LEFT = (steps: number) => - i18n.translate('xpack.serverlessSecurity.getStarted.togglePanel.progressTracker.stepsLeft', { - defaultMessage: '{steps} {steps, plural, =1 {step} other {steps}} left', - values: { steps }, - }); + i18n.translate( + 'xpack.securitySolutionServerless.getStarted.togglePanel.progressTracker.stepsLeft', + { + defaultMessage: '{steps} {steps, plural, =1 {step} other {steps}} left', + values: { steps }, + } + ); export const GET_SET_UP_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.getSetUp.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.getSetUp.title', { defaultMessage: 'Get set up', } ); export const INTRODUCTION_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.introduction.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.introduction.title', { defaultMessage: 'introduction', } ); export const WATCH_OVERVIEW_VIDEO_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.title', { defaultMessage: 'Watch the overview video', } ); export const PRODUCT_BADGE_ANALYTICS = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.productBadge.analytics', + 'xpack.securitySolutionServerless.getStarted.togglePanel.productBadge.analytics', { defaultMessage: 'Analytics', } ); export const PRODUCT_BADGE_CLOUD = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.productBadge.cloud', + 'xpack.securitySolutionServerless.getStarted.togglePanel.productBadge.cloud', { defaultMessage: 'Cloud', } ); export const PRODUCT_BADGE_EDR = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.productBadge.edr', + 'xpack.securitySolutionServerless.getStarted.togglePanel.productBadge.edr', { defaultMessage: 'EDR', } ); export const WATCH_OVERVIEW_VIDEO_DESCRIPTION1 = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.description1', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.description1', { defaultMessage: `Elastic security keeps your organization’s data safe from attack. `, } ); export const WATCH_OVERVIEW_VIDEO_DESCRIPTION2 = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.description2', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.description2', { defaultMessage: `Our unified security platform combines Analytics, EDR, and cloud security capabilities into a single SaaS product, providing organizations with a comprehensive solution to protect against a wide range of security threats. With centralized management, real-time threat detection and response, and scalability, our platform can help organizations improve their security posture and reduce the risk of data breaches.`, } ); export const WATCH_OVERVIEW_VIDEO_DESCRIPTION3 = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.description3', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.description3', { defaultMessage: `Watch the video to explore the core features that allow you to keep your data safe.`, } ); export const WATCH_OVERVIEW_VIDEO_HEADER = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.watchOverviewVideo.header', + 'xpack.securitySolutionServerless.getStarted.togglePanel.watchOverviewVideo.header', { defaultMessage: 'Elastic Security', } ); export const BRING_IN_YOUR_DATA_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.bringInYourData.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.bringInYourData.title', { defaultMessage: 'Bring in your data', } ); export const ACTIVATE_AND_CREATE_RULES_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.activateAndCreateRules.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.activateAndCreateRules.title', { defaultMessage: 'Activate and create rules', } ); export const PROTECT_YOUR_ENVIRONMENT_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.protectYourEnvironmentInRealtime.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.protectYourEnvironmentInRealtime.title', { defaultMessage: 'Protect your environment in realtime', } ); export const GET_MORE_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.getMoreFromElasticSecurity.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.getMoreFromElasticSecurity.title', { defaultMessage: 'Get more from Elastic Security', } ); export const MASTER_THE_INVESTIGATION_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.masterTheInvestigationsWorkflow.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.masterTheInvestigationsWorkflow.title', { defaultMessage: 'Master the investigations workflow', } ); export const RESPOND_TO_THREATS_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.respondToThreatsWithAutomation.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.respondToThreatsWithAutomation.title', { defaultMessage: 'Respond to threats with automation', } ); export const OPTIMIZE_YOUR_WORKSPACE_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.optimizeYourWorkspace.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.optimizeYourWorkspace.title', { defaultMessage: 'Optimize your workspace', } ); export const TOGGLE_PANEL_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStartedProductLabel.title', + 'xpack.securitySolutionServerless.getStartedProductLabel.title', { defaultMessage: `Curate your Get Started experience:`, } ); export const ANALYTICS_SWITCH_LABEL = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.switch.analytics.label', + 'xpack.securitySolutionServerless.getStarted.togglePanel.switch.analytics.label', { defaultMessage: 'Analytics', } ); export const CLOUD_SWITCH_LABEL = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.switch.cloud.label', + 'xpack.securitySolutionServerless.getStarted.togglePanel.switch.cloud.label', { defaultMessage: 'Cloud', @@ -214,21 +223,21 @@ export const CLOUD_SWITCH_LABEL = i18n.translate( ); export const ENDPOINT_SWITCH_LABEL = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.switch.endpoint.label', + 'xpack.securitySolutionServerless.getStarted.togglePanel.switch.endpoint.label', { defaultMessage: 'Endpoint', } ); export const TOGGLE_PANEL_EMPTY_TITLE = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.empty.title', + 'xpack.securitySolutionServerless.getStarted.togglePanel.empty.title', { defaultMessage: `Hmm, there doesn't seem to be anything there`, } ); export const TOGGLE_PANEL_EMPTY_DESCRIPTION = i18n.translate( - 'xpack.serverlessSecurity.getStarted.togglePanel.empty.description', + 'xpack.securitySolutionServerless.getStarted.togglePanel.empty.description', { defaultMessage: `Switch on a toggle to continue your curated "Get Started" experience`, } diff --git a/x-pack/plugins/serverless_security/public/components/get_started/types.ts b/x-pack/plugins/security_solution_serverless/public/get_started/types.ts similarity index 88% rename from x-pack/plugins/serverless_security/public/components/get_started/types.ts rename to x-pack/plugins/security_solution_serverless/public/get_started/types.ts index d19041432569d..69c970f398132 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/types.ts +++ b/x-pack/plugins/security_solution_serverless/public/get_started/types.ts @@ -5,14 +5,9 @@ * 2.0. */ -import { EuiIconProps } from '@elastic/eui'; -import React from 'react'; -import { ProductLine } from '../../../common/config'; - -// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -export type GetStartedComponentProps = {}; - -export type GetStartedComponent = (props?: GetStartedComponentProps) => JSX.Element; +import type { EuiIconProps } from '@elastic/eui'; +import type React from 'react'; +import type { ProductLine } from '../../common/product'; export interface HeaderSection { description?: string; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.test.tsx similarity index 94% rename from x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.test.tsx index 6e726fd9a002f..efb07e0ade09f 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.test.tsx @@ -6,16 +6,14 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { EuiThemeComputed } from '@elastic/eui'; +import type { EuiThemeComputed } from '@elastic/eui'; import { useSetUpCardSections } from './use_setup_cards'; +import type { ActiveCards, CardId, StepId } from './types'; import { - ActiveCards, - CardId, GetMoreFromElasticSecurityCardId, GetSetUpCardId, IntroductionSteps, SectionId, - StepId, } from './types'; const mockEuiTheme: EuiThemeComputed = { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.tsx similarity index 93% rename from x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.tsx index bd762042196ee..5c45e75ea4f93 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_setup_cards.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_setup_cards.tsx @@ -5,11 +5,11 @@ * 2.0. */ -import { EuiSpacer, EuiThemeComputed } from '@elastic/eui'; +import type { EuiThemeComputed } from '@elastic/eui'; +import { EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; import React, { useCallback } from 'react'; import { css } from '@emotion/react'; -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; -import { ActiveCards, CardId, SectionId, StepId } from './types'; +import type { ActiveCards, CardId, SectionId, StepId } from './types'; import { CardItem } from './card_item'; import { getSections } from './sections'; diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.test.tsx similarity index 97% rename from x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.test.tsx index 6201009395935..41131ec5c5453 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.test.tsx @@ -6,8 +6,9 @@ */ import { renderHook, act } from '@testing-library/react-hooks'; import { useTogglePanel } from './use_toggle_panel'; -import { getStartedStorage } from '../../lib/get_started/storage'; -import { ProductLine, SecurityProductTypes } from '../../../common/config'; +import { getStartedStorage } from './storage'; +import { ProductLine } from '../../common/product'; +import type { SecurityProductTypes } from '../../common/config'; import { GetMoreFromElasticSecurityCardId, GetSetUpCardId, @@ -15,7 +16,7 @@ import { SectionId, } from './types'; -jest.mock('../../lib/get_started/storage'); +jest.mock('./storage'); describe('useTogglePanel', () => { const productTypes = [ diff --git a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.tsx similarity index 90% rename from x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.tsx index f449478572c45..4ea767ae498ba 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/use_toggle_panel.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/use_toggle_panel.tsx @@ -6,15 +6,17 @@ */ import { useCallback, useMemo, useReducer } from 'react'; -import { ProductLine, SecurityProductTypes } from '../../../common/config'; -import { getStartedStorage } from '../../lib/get_started/storage'; +import { ProductLine } from '../../common/product'; +import type { SecurityProductTypes } from '../../common/config'; +import { getStartedStorage } from './storage'; import { getActiveCardsInitialStates, getActiveSectionsInitialStates, getFinishedStepsInitialStates, reducer, } from './reducer'; -import { CardId, GetStartedPageActions, SectionId, StepId, Switch } from './types'; +import type { CardId, SectionId, StepId, Switch } from './types'; +import { GetStartedPageActions } from './types'; export const useTogglePanel = ({ productTypes }: { productTypes: SecurityProductTypes }) => { const { diff --git a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.test.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.test.tsx similarity index 96% rename from x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.test.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.test.tsx index 27a68f640e175..a15c70df33428 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { render, RenderResult } from '@testing-library/react'; +import { render, type RenderResult } from '@testing-library/react'; import { WelcomePanel } from './welcome_panel'; jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); diff --git a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.tsx b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.tsx similarity index 98% rename from x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.tsx rename to x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.tsx index c6e25a085998d..79eecfbac7a33 100644 --- a/x-pack/plugins/serverless_security/public/components/get_started/welcome_panel.tsx +++ b/x-pack/plugins/security_solution_serverless/public/get_started/welcome_panel.tsx @@ -10,7 +10,7 @@ import { css } from '@emotion/react'; import React from 'react'; import progress from './images/progress.svg'; import invite from './images/invite.svg'; -import { HeaderSection } from './types'; +import type { HeaderSection } from './types'; import { WELCOME_PANEL_PROJECT_CREATED_TITLE, WELCOME_PANEL_PROJECT_CREATED_DESCRIPTION, diff --git a/x-pack/plugins/serverless_security/public/index.ts b/x-pack/plugins/security_solution_serverless/public/index.ts similarity index 58% rename from x-pack/plugins/serverless_security/public/index.ts rename to x-pack/plugins/security_solution_serverless/public/index.ts index 1a6466261b1bd..20c00e6985332 100644 --- a/x-pack/plugins/serverless_security/public/index.ts +++ b/x-pack/plugins/security_solution_serverless/public/index.ts @@ -5,13 +5,16 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/public'; -import { ServerlessSecurityPlugin } from './plugin'; +import type { PluginInitializerContext } from '@kbn/core/public'; +import { SecuritySolutionServerlessPlugin } from './plugin'; // This exports static code and TypeScript types, // as well as, Kibana Platform `plugin()` initializer. export function plugin(initializerContext: PluginInitializerContext) { - return new ServerlessSecurityPlugin(initializerContext); + return new SecuritySolutionServerlessPlugin(initializerContext); } -export type { ServerlessSecurityPluginSetup, ServerlessSecurityPluginStart } from './types'; +export type { + SecuritySolutionServerlessPluginSetup, + SecuritySolutionServerlessPluginStart, +} from './types'; diff --git a/x-pack/plugins/security_solution_serverless/public/jest.config.js b/x-pack/plugins/security_solution_serverless/public/jest.config.js new file mode 100644 index 0000000000000..cf3ad9340c14d --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/jest.config.js @@ -0,0 +1,29 @@ +/* + * 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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + /** all nested directories have their own Jest config file */ + testMatch: [ + '/x-pack/plugins/security_solution_serverless/public/**/*.test.{js,mjs,ts,tsx}', + ], + roots: ['/x-pack/plugins/security_solution_serverless/public'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution_serverless/public', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution_serverless/public/**/*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/{__test__,__snapshots__,__examples__,*mock*,tests,test_helpers,integration_tests,types}/**/*', + '!/x-pack/plugins/security_solution_serverless/public/*mock*.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/*.test.{ts,tsx}', + '!/x-pack/plugins/security_solution_serverless/public/*.d.ts', + '!/x-pack/plugins/security_solution_serverless/public/*.config.ts', + '!/x-pack/plugins/security_solution_serverless/public/index.{js,ts,tsx}', + ], +}; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts b/x-pack/plugins/security_solution_serverless/public/navigation/breadcrumbs.ts similarity index 90% rename from x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/breadcrumbs.ts index d4e9d13b37698..195a1a070abcf 100644 --- a/x-pack/plugins/serverless_security/public/common/navigation/breadcrumbs.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/breadcrumbs.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { Services } from '../services'; +import type { Services } from '../common/services'; export const subscribeBreadcrumbs = (services: Services) => { const { securitySolution, serverless } = services; diff --git a/x-pack/plugins/security_solution_serverless/public/navigation/index.ts b/x-pack/plugins/security_solution_serverless/public/navigation/index.ts new file mode 100644 index 0000000000000..226c20997ef5e --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/navigation/index.ts @@ -0,0 +1,29 @@ +/* + * 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 { APP_PATH, MANAGE_PATH } from '@kbn/security-solution-plugin/common'; +import type { Services } from '../common/services'; +import { subscribeBreadcrumbs } from './breadcrumbs'; +import { subscribeNavigationTree } from './navigation_tree'; +import { getSecuritySideNavComponent } from './side_navigation'; + +const SECURITY_MANAGE_PATH = `${APP_PATH}${MANAGE_PATH}`; + +/** + * Configures the serverless project navigation + */ +export const setServerlessNavigation = (services: Services) => { + const { serverless, securitySolution, management } = services; + securitySolution.setIsSidebarEnabled(false); + management.setLandingPageRedirect(SECURITY_MANAGE_PATH); + + serverless.setProjectHome(APP_PATH); + serverless.setSideNavComponent(getSecuritySideNavComponent(services)); + + subscribeNavigationTree(services); + subscribeBreadcrumbs(services); +}; diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/index.ts b/x-pack/plugins/security_solution_serverless/public/navigation/links/index.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/common/navigation/links/index.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/links/index.ts diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.ts b/x-pack/plugins/security_solution_serverless/public/navigation/links/nav_links.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/common/navigation/links/nav_links.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/links/nav_links.ts diff --git a/x-pack/plugins/serverless_security/public/common/navigation/links/types.ts b/x-pack/plugins/security_solution_serverless/public/navigation/links/types.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/common/navigation/links/types.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/links/types.ts diff --git a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.test.ts similarity index 86% rename from x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.test.ts index 91d020c332702..b1e619a30fc13 100644 --- a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.test.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.test.ts @@ -6,10 +6,9 @@ */ import type { ChromeNavLink } from '@kbn/core/public'; import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { servicesMocks } from '../services.mock'; import { subscribeNavigationTree } from './navigation_tree'; import { BehaviorSubject } from 'rxjs'; -import { mockProjectNavLinks } from '../services.mock'; +import { mockServices, mockProjectNavLinks } from '../common/__mocks__/services.mock'; import type { ProjectNavigationLink } from './links'; const mockChromeNavLinks = jest.fn((): ChromeNavLink[] => []); @@ -21,12 +20,12 @@ const mockChromeNavLinksHas = jest.fn((id: string): boolean => mockChromeNavLinks().some((link) => link.id === id) ); -const mockServices = { - ...servicesMocks, +const testServices = { + ...mockServices, chrome: { - ...servicesMocks.chrome, + ...mockServices.chrome, navLinks: { - ...servicesMocks.chrome.navLinks, + ...mockServices.chrome.navLinks, get: mockChromeNavLinksGet, has: mockChromeNavLinksHas, getNavLinks$: mockChromeGetNavLinks, @@ -66,10 +65,10 @@ describe('subscribeNavigationTree', () => { it('should call serverless setNavigation', async () => { mockProjectNavLinks.mockReturnValueOnce([link1]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -98,10 +97,10 @@ describe('subscribeNavigationTree', () => { mockChromeNavLinks.mockReturnValue([chromeNavLinkExpected]); mockProjectNavLinks.mockReturnValueOnce([externalLink]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -124,10 +123,10 @@ describe('subscribeNavigationTree', () => { it('should call serverless setNavigation with nested children', async () => { mockProjectNavLinks.mockReturnValueOnce([{ ...link1, links: [link2] }]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -158,20 +157,20 @@ describe('subscribeNavigationTree', () => { it('should not call serverless setNavigation when projectNavLinks is empty', async () => { mockProjectNavLinks.mockReturnValueOnce([]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + expect(testServices.serverless.setNavigation).not.toHaveBeenCalled(); }); it('should not call serverless setNavigation when chrome navLinks is empty', async () => { mockChromeNavLinks.mockReturnValue([]); mockProjectNavLinks.mockReturnValueOnce([link1]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + expect(testServices.serverless.setNavigation).not.toHaveBeenCalled(); }); it('should debounce updates', async () => { @@ -185,18 +184,18 @@ describe('subscribeNavigationTree', () => { mockChromeNavLinks.mockReturnValue([chromeNavLink1, chromeNavLink2, chromeNavLinkExpected]); mockProjectNavLinks.mockReturnValueOnce([linkExpected]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); chromeGetNavLinks$.next([chromeNavLink1]); chromeGetNavLinks$.next([chromeNavLink2]); chromeGetNavLinks$.next([chromeNavLinkExpected]); - expect(mockServices.serverless.setNavigation).not.toHaveBeenCalled(); + expect(testServices.serverless.setNavigation).not.toHaveBeenCalled(); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledTimes(1); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledTimes(1); + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -220,10 +219,10 @@ describe('subscribeNavigationTree', () => { mockChromeNavLinks.mockReturnValue([chromeNavLink2]); mockProjectNavLinks.mockReturnValueOnce([link1, link2]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', @@ -254,10 +253,10 @@ describe('subscribeNavigationTree', () => { link2, ]); - subscribeNavigationTree(mockServices); + subscribeNavigationTree(testServices); await waitForDebounce(); - expect(mockServices.serverless.setNavigation).toHaveBeenCalledWith({ + expect(testServices.serverless.setNavigation).toHaveBeenCalledWith({ navigationTree: [ { id: 'root', diff --git a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.ts similarity index 98% rename from x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.ts index 70464c0c53f5d..82555ae54332f 100644 --- a/x-pack/plugins/serverless_security/public/common/navigation/navigation_tree.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/navigation_tree.ts @@ -8,7 +8,7 @@ import type { ChromeNavLinks, ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; import { APP_UI_ID, SecurityPageName } from '@kbn/security-solution-plugin/common'; import { combineLatest, skipWhile, debounceTime } from 'rxjs'; -import type { Services } from '../services'; +import type { Services } from '../common/services'; import type { ProjectNavigationLink } from './links/types'; // We need to hide breadcrumbs for some pages (tabs) because they appear duplicated. diff --git a/x-pack/plugins/serverless_security/public/hooks/__mocks__/use_side_nav_items.ts b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/__mocks__/use_side_nav_items.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/hooks/__mocks__/use_side_nav_items.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/__mocks__/use_side_nav_items.ts diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/categories.ts b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/categories.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/components/side_navigation/categories.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/categories.ts diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/index.tsx similarity index 73% rename from x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/index.tsx index 399d6ecab13de..c749131300b5d 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/index.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/index.tsx @@ -10,10 +10,11 @@ import type { SideNavComponent } from '@kbn/core-chrome-browser/src/project_navi import { SecuritySideNavigation } from './lazy'; import { KibanaServicesProvider, type Services } from '../../common/services'; -export const getSecuritySideNavComponent = (services: Services): SideNavComponent => { - return () => ( - - - - ); -}; +export const getSecuritySideNavComponent = (services: Services): SideNavComponent => + function SecuritySideNavComponent() { + return ( + + + + ); + }; diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/lazy.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/lazy.tsx similarity index 100% rename from x-pack/plugins/serverless_security/public/components/side_navigation/lazy.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/lazy.tsx diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.test.tsx similarity index 85% rename from x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.test.tsx index eef0ccb8da671..1df7e2ca3008f 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.test.tsx @@ -8,11 +8,12 @@ import React from 'react'; import { render } from '@testing-library/react'; import { SecuritySideNavigation } from './side_navigation'; -import { useSideNavItems, useSideNavSelectedId } from '../../hooks/use_side_nav_items'; +import { useSideNavItems, useSideNavSelectedId } from './use_side_nav_items'; import { SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { KibanaServicesProvider } from '../../common/services.mock'; +import { ServicesWrapper } from '../../common/__mocks__/services.mock'; + +jest.mock('./use_side_nav_items'); -jest.mock('../../hooks/use_side_nav_items'); const mockUseSideNavItems = useSideNavItems as jest.Mock; const mockUseSideNavSelectedId = useSideNavSelectedId as jest.Mock; @@ -54,22 +55,22 @@ describe('SecuritySideNavigation', () => { it('should render loading when not items received', () => { mockUseSideNavItems.mockReturnValueOnce([]); - const component = render(, { wrapper: KibanaServicesProvider }); + const component = render(, { wrapper: ServicesWrapper }); expect(component.queryByTestId('sideNavLoader')).toBeInTheDocument(); }); it('should not render loading when items received', () => { - const component = render(, { wrapper: KibanaServicesProvider }); + const component = render(, { wrapper: ServicesWrapper }); expect(component.queryByTestId('sideNavLoader')).not.toBeInTheDocument(); }); it('should render the SideNav when items received', () => { - const component = render(, { wrapper: KibanaServicesProvider }); + const component = render(, { wrapper: ServicesWrapper }); expect(component.queryByTestId('solutionSideNav')).toBeInTheDocument(); }); it('should pass item props to the SolutionSideNav component', () => { - render(, { wrapper: KibanaServicesProvider }); + render(, { wrapper: ServicesWrapper }); expect(mockSolutionSideNav).toHaveBeenCalledWith( expect.objectContaining({ @@ -79,7 +80,7 @@ describe('SecuritySideNavigation', () => { }); it('should selectedId the SolutionSideNav component', () => { - render(, { wrapper: KibanaServicesProvider }); + render(, { wrapper: ServicesWrapper }); expect(mockSolutionSideNav).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.tsx similarity index 79% rename from x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.tsx index b38ff02dd3417..5ba20e26cac21 100644 --- a/x-pack/plugins/serverless_security/public/components/side_navigation/side_navigation.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/side_navigation.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { EuiLoadingSpinner, useEuiTheme } from '@elastic/eui'; import { SolutionNav } from '@kbn/shared-ux-page-solution-nav'; import { SolutionSideNav } from '@kbn/security-solution-side-nav'; -import { useSideNavItems, useSideNavSelectedId } from '../../hooks/use_side_nav_items'; +import { useSideNavItems, useSideNavSelectedId } from './use_side_nav_items'; import { CATEGORIES } from './categories'; export const SecuritySideNavigation: React.FC = () => { @@ -26,19 +26,18 @@ export const SecuritySideNavigation: React.FC = () => { canBeCollapsed={false} name={'Security'} icon={'logoSecurity'} - children={ - - } closeFlyoutButtonPosition={'inside'} headingProps={{ 'data-test-subj': 'securitySolutionNavHeading', }} - /> + > + + ); }; diff --git a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.test.tsx similarity index 82% rename from x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.test.tsx index 22c0e7118ec76..2145961e36aa5 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.test.tsx +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.test.tsx @@ -8,13 +8,10 @@ import { renderHook } from '@testing-library/react-hooks'; import { useSideNavItems, useSideNavSelectedId } from './use_side_nav_items'; import { SecurityPageName } from '@kbn/security-solution-plugin/common'; -import { - KibanaServicesProvider, - servicesMocks, - mockProjectNavLinks, -} from '../common/services.mock'; +import { mockServices, mockProjectNavLinks } from '../../common/__mocks__/services.mock'; -jest.mock('./use_link_props'); +jest.mock('../../common/hooks/use_link_props'); +jest.mock('../../common/services'); const mockUseLocation = jest.fn(() => ({ pathname: '/' })); jest.mock('react-router-dom', () => ({ @@ -28,12 +25,11 @@ describe('useSideNavItems', () => { }); it('should return empty items', async () => { - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); - + const { result } = renderHook(useSideNavItems); const items = result.current; expect(items).toEqual([]); - expect(servicesMocks.getProjectNavLinks$).toHaveBeenCalledTimes(1); + expect(mockServices.getProjectNavLinks$).toHaveBeenCalledTimes(1); }); it('should return main items', async () => { @@ -41,7 +37,7 @@ describe('useSideNavItems', () => { { id: SecurityPageName.alerts, title: 'Alerts' }, { id: SecurityPageName.case, title: 'Cases' }, ]); - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useSideNavItems); const items = result.current; expect(items).toEqual([ @@ -70,7 +66,7 @@ describe('useSideNavItems', () => { links: [{ id: SecurityPageName.detectionAndResponse, title: 'Detection & Response' }], }, ]); - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useSideNavItems); const items = result.current; expect(items).toEqual([ @@ -100,7 +96,7 @@ describe('useSideNavItems', () => { sideNavIcon: 'launch', }, ]); - const { result } = renderHook(useSideNavItems, { wrapper: KibanaServicesProvider }); + const { result } = renderHook(useSideNavItems); const items = result.current; @@ -139,10 +135,7 @@ describe('useSideNavSelectedId', () => { }, ]; - const { result } = renderHook(useSideNavSelectedId, { - wrapper: KibanaServicesProvider, - initialProps: items, - }); + const { result } = renderHook(useSideNavSelectedId, { initialProps: items }); const selectedId = result.current; expect(selectedId).toEqual(''); @@ -165,10 +158,7 @@ describe('useSideNavSelectedId', () => { }, ]; - const { result } = renderHook(useSideNavSelectedId, { - wrapper: KibanaServicesProvider, - initialProps: items, - }); + const { result } = renderHook(useSideNavSelectedId, { initialProps: items }); const selectedId = result.current; expect(selectedId).toEqual(SecurityPageName.alerts); @@ -193,10 +183,7 @@ describe('useSideNavSelectedId', () => { }, ]; - const { result } = renderHook(useSideNavSelectedId, { - wrapper: KibanaServicesProvider, - initialProps: items, - }); + const { result } = renderHook(useSideNavSelectedId, { initialProps: items }); const selectedId = result.current; expect(selectedId).toEqual(SecurityPageName.dashboards); diff --git a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.ts similarity index 95% rename from x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts rename to x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.ts index 7ec68683eb223..779dd86764d74 100644 --- a/x-pack/plugins/serverless_security/public/hooks/use_side_nav_items.ts +++ b/x-pack/plugins/security_solution_serverless/public/navigation/side_navigation/use_side_nav_items.ts @@ -12,9 +12,9 @@ import { SolutionSideNavItemPosition, type SolutionSideNavItem, } from '@kbn/security-solution-side-nav'; -import { useKibana } from '../common/services'; -import { type GetLinkProps, useGetLinkProps } from './use_link_props'; -import { useNavLinks } from './use_nav_links'; +import { useKibana } from '../../common/services'; +import { type GetLinkProps, useGetLinkProps } from '../../common/hooks/use_link_props'; +import { useNavLinks } from '../../common/hooks/use_nav_links'; type NavigationLink = ReturnType[number]; diff --git a/x-pack/plugins/security_solution_serverless/public/plugin.ts b/x-pack/plugins/security_solution_serverless/public/plugin.ts new file mode 100644 index 0000000000000..307a438c6e9c3 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/plugin.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; + +import { getSecurityGetStartedComponent } from './get_started'; +import type { + SecuritySolutionServerlessPluginSetup, + SecuritySolutionServerlessPluginStart, + SecuritySolutionServerlessPluginSetupDeps, + SecuritySolutionServerlessPluginStartDeps, + ServerlessSecurityPublicConfig, +} from './types'; +import { registerUpsellings } from './upselling'; +import { createServices } from './common/services'; +import { setServerlessNavigation } from './navigation'; + +export class SecuritySolutionServerlessPlugin + implements + Plugin< + SecuritySolutionServerlessPluginSetup, + SecuritySolutionServerlessPluginStart, + SecuritySolutionServerlessPluginSetupDeps, + SecuritySolutionServerlessPluginStartDeps + > +{ + private config: ServerlessSecurityPublicConfig; + + constructor(private readonly initializerContext: PluginInitializerContext) { + this.config = this.initializerContext.config.get(); + } + + public setup( + _core: CoreSetup, + setupDeps: SecuritySolutionServerlessPluginSetupDeps + ): SecuritySolutionServerlessPluginSetup { + registerUpsellings(setupDeps.securitySolution.upselling, this.config.productTypes); + return {}; + } + + public start( + core: CoreStart, + startDeps: SecuritySolutionServerlessPluginStartDeps + ): SecuritySolutionServerlessPluginStart { + const { securitySolution } = startDeps; + const { productTypes } = this.config; + + const services = createServices(core, startDeps); + + securitySolution.setGetStartedPage(getSecurityGetStartedComponent(services, productTypes)); + + setServerlessNavigation(services); + + return {}; + } + + public stop() {} +} diff --git a/x-pack/plugins/serverless_security/public/types.ts b/x-pack/plugins/security_solution_serverless/public/types.ts similarity index 78% rename from x-pack/plugins/serverless_security/public/types.ts rename to x-pack/plugins/security_solution_serverless/public/types.ts index 73052810127ad..e65813aa68f6c 100644 --- a/x-pack/plugins/serverless_security/public/types.ts +++ b/x-pack/plugins/security_solution_serverless/public/types.ts @@ -11,23 +11,23 @@ import type { PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/public'; import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public'; -import { ManagementSetup, ManagementStart } from '@kbn/management-plugin/public'; +import type { ManagementSetup, ManagementStart } from '@kbn/management-plugin/public'; import type { SecurityProductTypes } from '../common/config'; // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ServerlessSecurityPluginSetup {} +export interface SecuritySolutionServerlessPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ServerlessSecurityPluginStart {} +export interface SecuritySolutionServerlessPluginStart {} -export interface ServerlessSecurityPluginSetupDependencies { +export interface SecuritySolutionServerlessPluginSetupDeps { security: SecurityPluginSetup; securitySolution: SecuritySolutionPluginSetup; serverless: ServerlessPluginSetup; management: ManagementSetup; } -export interface ServerlessSecurityPluginStartDependencies { +export interface SecuritySolutionServerlessPluginStartDeps { security: SecurityPluginStart; securitySolution: SecuritySolutionPluginStart; serverless: ServerlessPluginStart; diff --git a/x-pack/plugins/serverless_security/public/components/upselling/hooks/use_product_type_by_pli.ts b/x-pack/plugins/security_solution_serverless/public/upselling/hooks/use_product_type_by_pli.ts similarity index 93% rename from x-pack/plugins/serverless_security/public/components/upselling/hooks/use_product_type_by_pli.ts rename to x-pack/plugins/security_solution_serverless/public/upselling/hooks/use_product_type_by_pli.ts index f1486469247cb..df4a97e3b0347 100644 --- a/x-pack/plugins/serverless_security/public/components/upselling/hooks/use_product_type_by_pli.ts +++ b/x-pack/plugins/security_solution_serverless/public/upselling/hooks/use_product_type_by_pli.ts @@ -6,7 +6,7 @@ */ import type { AppFeatureKey } from '@kbn/security-solution-plugin/common'; -import { PLI_APP_FEATURES } from '../../../../common/pli/pli_config'; +import { PLI_APP_FEATURES } from '../../../common/pli/pli_config'; export const useProductTypeByPLI = (requiredPLI: AppFeatureKey): string | null => { if (PLI_APP_FEATURES.security.essentials.includes(requiredPLI)) { diff --git a/x-pack/plugins/serverless_security/public/components/upselling/index.ts b/x-pack/plugins/security_solution_serverless/public/upselling/index.ts similarity index 100% rename from x-pack/plugins/serverless_security/public/components/upselling/index.ts rename to x-pack/plugins/security_solution_serverless/public/upselling/index.ts diff --git a/x-pack/plugins/serverless_security/public/components/upselling/pages/generic_upselling_page.tsx b/x-pack/plugins/security_solution_serverless/public/upselling/pages/generic_upselling_page.tsx similarity index 83% rename from x-pack/plugins/serverless_security/public/components/upselling/pages/generic_upselling_page.tsx rename to x-pack/plugins/security_solution_serverless/public/upselling/pages/generic_upselling_page.tsx index aed8d76898495..cc6440358da61 100644 --- a/x-pack/plugins/serverless_security/public/components/upselling/pages/generic_upselling_page.tsx +++ b/x-pack/plugins/security_solution_serverless/public/upselling/pages/generic_upselling_page.tsx @@ -11,16 +11,16 @@ import type { AppFeatureKey } from '@kbn/security-solution-plugin/common'; import { useProductTypeByPLI } from '../hooks/use_product_type_by_pli'; export const GenericUpsellingPage: React.FC<{ requiredPLI: AppFeatureKey }> = React.memo( - ({ requiredPLI }) => { + function GenericUpsellingPage({ requiredPLI }) { const productTypeRequired = useProductTypeByPLI(requiredPLI); return ( This is a testing component for a Serverless upselling prompt.} + title={<>{'This is a testing component for a Serverless upselling prompt.'}} body={ <> - Get {productTypeRequired} to enable this feature + {'Get'} {productTypeRequired} {'to enable this feature'}