From 993ef43e4e16e50ba975e8aecb94c215dad18496 Mon Sep 17 00:00:00 2001 From: Mykola Harmash Date: Wed, 5 Jun 2024 16:44:22 +0200 Subject: [PATCH 001/122] [Onboarding] Save installed integrations to the onboarding SO (#184717) Closes https://github.com/elastic/kibana/issues/183363 ## Summary Extends the POST/GET /progress endpoints with an `install-integrations` step and it's payload that contains all the installed integrations. ## How to test 1. Run Kibana and ES locally 2. Generate Install API Key in Kibana 3. Go to System logs quick onboarding flow and copy generated ingest API key and onboarding ID 4. Open Network tab in the dev console to track `/progress` endpoint calls 5. Run the auto-detect CLI and go through the flow ```bash sudo ./x-pack/plugins/observability_solution/observability_onboarding/public/assets/auto_detect.sh --install-key="{{INSTALL_API_KEY}}" --ingest-key="{{INGEST_API_KEY}}" --kibana-url="http://localhost:5601/ftw" --id="{{ONBOARDING_ID}}" --ea-version="8.13.4" ``` 6. Check response from the `/progress` endpoint In the dev console. Make sure there is an `install-integrations` step and it has all of the selected integrations. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../check_registered_types.test.ts | 2 +- .../server/routes/flow/get_has_logs.ts | 2 +- .../server/routes/flow/route.ts | 48 +++++++++---------- .../server/routes/types.ts | 32 +++++++++++++ .../observability_onboarding_status.ts | 37 ++++++++++++-- 5 files changed, 88 insertions(+), 33 deletions(-) diff --git a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts index 10d71344a0a2b..169fd6fa5cf66 100644 --- a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts +++ b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts @@ -129,7 +129,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ml-module": "94f210e60504fe0cc8241d867af97f8130250359", "ml-trained-model": "482195cefd6b04920e539d34d7356d22cb68e4f3", "monitoring-telemetry": "5d91bf75787d9d4dd2fae954d0b3f76d33d2e559", - "observability-onboarding-state": "b16064c516aac64ae699c737d7d10b6e199bfded", + "observability-onboarding-state": "34eef666124a9e4ad1c607d0097cc25128764681", "osquery-manager-usage-metric": "983bcbc3b7dda0aad29b20907db233abba709bcc", "osquery-pack": "702e86b1a936153b39f65b0781bdc136e186e123", "osquery-pack-asset": "cd140bc2e4b092e93692b587bf6e38051ef94c75", diff --git a/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/get_has_logs.ts b/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/get_has_logs.ts index 2b384d198f0c4..bedd1de0a80da 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/get_has_logs.ts +++ b/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/get_has_logs.ts @@ -9,11 +9,11 @@ import { ElasticsearchClient } from '@kbn/core/server'; import { termQuery } from '@kbn/observability-plugin/server'; import { AGENT_ID } from '../../../common/es_fields'; import { - ElasticAgentStepPayload, LogFilesState, ObservabilityOnboardingType, SystemLogsState, } from '../../saved_objects/observability_onboarding_status'; +import { ElasticAgentStepPayload } from '../types'; export async function getHasLogs({ type, diff --git a/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/route.ts b/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/route.ts index e759cb0a16953..b43edf76ce0a5 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/route.ts +++ b/x-pack/plugins/observability_solution/observability_onboarding/server/routes/flow/route.ts @@ -15,14 +15,12 @@ import { import type { TemplateAgentPolicyInput } from '@kbn/fleet-plugin/common'; import { dump } from 'js-yaml'; import { getObservabilityOnboardingFlow, saveObservabilityOnboardingFlow } from '../../lib/state'; -import { - ElasticAgentStepPayload, - ObservabilityOnboardingFlow, -} from '../../saved_objects/observability_onboarding_status'; +import { ObservabilityOnboardingFlow } from '../../saved_objects/observability_onboarding_status'; import { createObservabilityOnboardingServerRoute } from '../create_observability_onboarding_server_route'; import { getHasLogs } from './get_has_logs'; import { getFallbackESUrl } from '../../lib/get_fallback_urls'; +import { ElasticAgentStepPayload, Integration, StepProgressPayloadRT } from '../types'; const updateOnboardingFlowRoute = createObservabilityOnboardingServerRoute({ endpoint: 'PUT /internal/observability_onboarding/flow/{onboardingId}', @@ -72,7 +70,9 @@ const stepProgressUpdateRoute = createObservabilityOnboardingServerRoute({ status: t.string, }), t.partial({ message: t.string }), - t.partial({ payload: t.record(t.string, t.unknown) }), + t.partial({ + payload: StepProgressPayloadRT, + }), ]), }), async handler(resources) { @@ -112,7 +112,7 @@ const stepProgressUpdateRoute = createObservabilityOnboardingServerRoute({ [name]: { status, message, - payload: payload as unknown as ElasticAgentStepPayload, + payload, }, }, }, @@ -162,7 +162,7 @@ const getProgressRoute = createObservabilityOnboardingServerRoute({ type, state: savedObservabilityOnboardingState.state, esClient, - payload: progress['ea-status']?.payload, + payload: progress['ea-status']?.payload as ElasticAgentStepPayload, }); if (hasLogs) { progress['logs-ingest'] = { status: 'complete' }; @@ -239,14 +239,6 @@ const integrationsInstallRoute = createObservabilityOnboardingServerRoute({ }); } - await saveObservabilityOnboardingFlow({ - savedObjectsClient, - savedObjectId: params.path.onboardingId, - observabilityOnboardingState: { - ...savedObservabilityOnboardingState, - } as ObservabilityOnboardingFlow, - }); - let agentPolicyInputs: TemplateAgentPolicyInput[] = []; try { agentPolicyInputs = await ensureInstalledIntegrations(integrationsToInstall, packageClient); @@ -261,6 +253,21 @@ const integrationsInstallRoute = createObservabilityOnboardingServerRoute({ throw error; } + await saveObservabilityOnboardingFlow({ + savedObjectsClient, + savedObjectId: params.path.onboardingId, + observabilityOnboardingState: { + ...savedObservabilityOnboardingState, + progress: { + ...savedObservabilityOnboardingState.progress, + 'install-integrations': { + status: 'complete', + payload: integrationsToInstall, + }, + }, + } as ObservabilityOnboardingFlow, + }); + const elasticsearchUrl = plugins.cloud?.setup?.elasticsearchUrl ? [plugins.cloud?.setup?.elasticsearchUrl] : await getFallbackESUrl(services.esLegacyConfigService); @@ -277,17 +284,6 @@ const integrationsInstallRoute = createObservabilityOnboardingServerRoute({ }, }); -type Integration = - | { - pkgName: string; - installSource: 'registry'; - } - | { - pkgName: string; - installSource: 'custom'; - logFilePaths: string[]; - }; - async function ensureInstalledIntegrations( integrationsToInstall: Integration[], packageClient: PackageClient diff --git a/x-pack/plugins/observability_solution/observability_onboarding/server/routes/types.ts b/x-pack/plugins/observability_solution/observability_onboarding/server/routes/types.ts index 11efacc415e57..e9ab6b14dab54 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/server/routes/types.ts +++ b/x-pack/plugins/observability_solution/observability_onboarding/server/routes/types.ts @@ -11,6 +11,7 @@ import { KibanaResponseFactory, Logger, } from '@kbn/core/server'; +import * as t from 'io-ts'; import { ObservabilityOnboardingServerRouteRepository } from '.'; import { ObservabilityOnboardingConfig } from '..'; import { EsLegacyConfigService } from '../services/es_legacy_config_service'; @@ -50,3 +51,34 @@ export interface ObservabilityOnboardingRouteCreateOptions { xsrfRequired?: boolean; }; } + +export const IntegrationRT = t.union([ + t.type({ + pkgName: t.string, + installSource: t.literal('registry'), + }), + t.type({ + pkgName: t.string, + installSource: t.literal('custom'), + logFilePaths: t.array(t.string), + }), +]); + +export type Integration = t.TypeOf; + +export const ElasticAgentStepPayloadRT = t.type({ + agentId: t.string, +}); + +export type ElasticAgentStepPayload = t.TypeOf; + +export const InstallIntegrationsStepPayloadRT = t.array(IntegrationRT); + +export type InstallIntegrationsStepPayload = t.TypeOf; + +export const StepProgressPayloadRT = t.union([ + ElasticAgentStepPayloadRT, + InstallIntegrationsStepPayloadRT, +]); + +export type StepProgressPayload = t.TypeOf; diff --git a/x-pack/plugins/observability_solution/observability_onboarding/server/saved_objects/observability_onboarding_status.ts b/x-pack/plugins/observability_solution/observability_onboarding/server/saved_objects/observability_onboarding_status.ts index afaa6461cc4f4..297f7f33a9d64 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/server/saved_objects/observability_onboarding_status.ts +++ b/x-pack/plugins/observability_solution/observability_onboarding/server/saved_objects/observability_onboarding_status.ts @@ -7,8 +7,10 @@ import { SavedObjectsType } from '@kbn/core/server'; import { schema } from '@kbn/config-schema'; +import { StepProgressPayload } from '../routes/types'; export const OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE = 'observability-onboarding-state'; + export interface LogFilesState { datasetName: string; serviceName?: string; @@ -21,10 +23,6 @@ export interface SystemLogsState { namespace: string; } -export interface ElasticAgentStepPayload { - agentId: string; -} - export type ObservabilityOnboardingType = 'logFiles' | 'systemLogs'; type ObservabilityOnboardingFlowState = LogFilesState | SystemLogsState | undefined; @@ -37,7 +35,7 @@ export interface ObservabilityOnboardingFlow { { status: string; message?: string; - payload?: ElasticAgentStepPayload; + payload?: StepProgressPayload; } >; } @@ -63,6 +61,14 @@ const ElasticAgentStepPayloadSchema = schema.object({ agentId: schema.string(), }); +export const InstallIntegrationsStepPayloadSchema = schema.arrayOf( + schema.object({ + pkgName: schema.string(), + installSource: schema.string(), + logFilePaths: schema.maybe(schema.arrayOf(schema.string())), + }) +); + export const observabilityOnboardingFlow: SavedObjectsType = { name: OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, hidden: false, @@ -92,5 +98,26 @@ export const observabilityOnboardingFlow: SavedObjectsType = { }), }, }, + '2': { + changes: [], + schemas: { + create: schema.object({ + type: schema.string(), + state: schema.maybe( + schema.oneOf([LogFilesStateSchema, SystemLogsStateSchema, schema.never()]) + ), + progress: schema.mapOf( + schema.string(), + schema.object({ + status: schema.string(), + message: schema.maybe(schema.string()), + payload: schema.maybe( + schema.oneOf([ElasticAgentStepPayloadSchema, InstallIntegrationsStepPayloadSchema]) + ), + }) + ), + }), + }, + }, }, }; From 36f2ff409fbfea5aabc451391ee843f220b6bb97 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 5 Jun 2024 08:51:37 -0600 Subject: [PATCH 002/122] [Embeddable Rebuild] [Controls] Add control registry + example React control (#182842) Closes https://github.com/elastic/kibana/issues/184373 ## Summary This PR marks the first step of the control group migration to the new React embeddable system. A few notes about this: - In the new system, each individual control will no longer be an "embeddable" - instead, we are creating a **new** control-specific registry for all controls. This is **modelled** after the embeddable registry, but it is locked down and much more controls-specific. - Most of the work accomplished in this PR is hidden away in the `examples` plugin - that way, user-facing code is not impacted. After some discussion, we decided to do it this way because refactoring the control group to work with both legacy and new controls (like we did for the dashboard container) felt like a very large undertaking for minimal benefit. Instead, all work will be contained in the example plugin (including building out the existing control types with the new framework) and we will do a final "swap" of the legacy control group with the new React control group as part of https://github.com/elastic/kibana/issues/174961 - This PR does **not** contain a fully functional control group embeddable - instead, the main point of this PR is to introduce the control registry and an example control. The current control group embeddable is provided just to give the **bare minimum** of functionality. - In order to find the new Search control example, navigate to Developer Examples > Controls > Register a new React control - The example search control only works on text fields. See https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html and https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html for information on the two search techniques. ### Checklist - [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] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- examples/controls_example/kibana.jsonc | 4 +- examples/controls_example/public/app.tsx | 49 --- examples/controls_example/public/app/app.tsx | 90 ++++ .../app/control_group_renderer_examples.tsx | 46 ++ .../add_button_example.tsx | 0 .../basic_redux_example.tsx | 0 .../edit_example.tsx | 0 .../search_example.tsx | 2 +- .../public/app/react_control_example.tsx | 234 ++++++++++ examples/controls_example/public/plugin.tsx | 55 ++- .../actions/edit_control_action.tsx | 89 ++++ .../control_error_component.tsx | 56 +++ .../control_factory_registry.ts | 49 +++ .../control_group/control_group_editor.tsx | 245 +++++++++++ .../control_group_editor_constants.tsx | 113 +++++ .../get_control_group_factory.tsx | 241 +++++++++++ .../open_edit_control_group_flyout.tsx | 114 +++++ .../control_group/serialization_utils.ts | 99 +++++ .../react_controls/control_group/types.ts | 91 ++++ .../public/react_controls/control_panel.tsx | 179 ++++++++ .../react_controls/control_renderer.tsx | 86 ++++ .../data_controls/data_control_constants.tsx | 154 +++++++ .../data_controls/data_control_editor.tsx | 403 ++++++++++++++++++ .../data_control_editor_utils.ts | 46 ++ .../data_controls/initialize_data_control.tsx | 137 ++++++ .../open_data_control_editor.tsx | 131 ++++++ .../get_search_control_factory.tsx | 227 ++++++++++ .../data_controls/search_control/types.tsx | 20 + .../react_controls/data_controls/types.ts | 55 +++ .../initialize_default_control_api.tsx | 64 +++ .../public/react_controls/types.ts | 96 +++++ examples/controls_example/tsconfig.json | 14 +- .../presentation_containers/index.ts | 1 + .../interfaces/presentation_container.ts | 44 +- .../presentation_publishing/index.ts | 3 + .../fetch/publishes_unified_search.ts | 27 +- src/plugins/controls/common/index.ts | 2 + .../actions/clear_control_action.tsx | 71 +-- .../actions/delete_control_action.tsx | 74 ++-- .../component/control_frame_component.tsx | 2 +- .../control_group/editor/control_editor.tsx | 8 - .../embeddable/control_group_container.tsx | 16 +- src/plugins/controls/public/index.ts | 4 + .../embeddable/options_list_embeddable.tsx | 17 +- .../embeddable/range_slider_embeddable.tsx | 4 +- .../embeddable/time_slider_embeddable.tsx | 4 +- src/plugins/controls/public/types.ts | 14 +- src/plugins/controls/tsconfig.json | 2 + .../dashboard_control_group_integration.ts | 27 +- .../data_views/sync_dashboard_data_views.ts | 18 +- .../embeddable/dashboard_container.tsx | 6 +- .../react_embeddable_renderer.test.tsx | 9 +- .../react_embeddable_renderer.tsx | 41 +- .../public/react_embeddable_system/types.ts | 35 +- .../floating_actions/floating_actions.tsx | 17 +- src/plugins/presentation_util/tsconfig.json | 1 + 56 files changed, 3407 insertions(+), 229 deletions(-) delete mode 100644 examples/controls_example/public/app.tsx create mode 100644 examples/controls_example/public/app/app.tsx create mode 100644 examples/controls_example/public/app/control_group_renderer_examples.tsx rename examples/controls_example/public/{ => app/control_group_renderer_examples}/add_button_example.tsx (100%) rename examples/controls_example/public/{ => app/control_group_renderer_examples}/basic_redux_example.tsx (100%) rename examples/controls_example/public/{ => app/control_group_renderer_examples}/edit_example.tsx (100%) rename examples/controls_example/public/{ => app/control_group_renderer_examples}/search_example.tsx (99%) create mode 100644 examples/controls_example/public/app/react_control_example.tsx create mode 100644 examples/controls_example/public/react_controls/actions/edit_control_action.tsx create mode 100644 examples/controls_example/public/react_controls/control_error_component.tsx create mode 100644 examples/controls_example/public/react_controls/control_factory_registry.ts create mode 100644 examples/controls_example/public/react_controls/control_group/control_group_editor.tsx create mode 100644 examples/controls_example/public/react_controls/control_group/control_group_editor_constants.tsx create mode 100644 examples/controls_example/public/react_controls/control_group/get_control_group_factory.tsx create mode 100644 examples/controls_example/public/react_controls/control_group/open_edit_control_group_flyout.tsx create mode 100644 examples/controls_example/public/react_controls/control_group/serialization_utils.ts create mode 100644 examples/controls_example/public/react_controls/control_group/types.ts create mode 100644 examples/controls_example/public/react_controls/control_panel.tsx create mode 100644 examples/controls_example/public/react_controls/control_renderer.tsx create mode 100644 examples/controls_example/public/react_controls/data_controls/data_control_constants.tsx create mode 100644 examples/controls_example/public/react_controls/data_controls/data_control_editor.tsx create mode 100644 examples/controls_example/public/react_controls/data_controls/data_control_editor_utils.ts create mode 100644 examples/controls_example/public/react_controls/data_controls/initialize_data_control.tsx create mode 100644 examples/controls_example/public/react_controls/data_controls/open_data_control_editor.tsx create mode 100644 examples/controls_example/public/react_controls/data_controls/search_control/get_search_control_factory.tsx create mode 100644 examples/controls_example/public/react_controls/data_controls/search_control/types.tsx create mode 100644 examples/controls_example/public/react_controls/data_controls/types.ts create mode 100644 examples/controls_example/public/react_controls/initialize_default_control_api.tsx create mode 100644 examples/controls_example/public/react_controls/types.ts diff --git a/examples/controls_example/kibana.jsonc b/examples/controls_example/kibana.jsonc index 2a6907e130d2e..2a1dd89aaec3a 100644 --- a/examples/controls_example/kibana.jsonc +++ b/examples/controls_example/kibana.jsonc @@ -12,7 +12,9 @@ "developerExamples", "embeddable", "navigation", - "presentationUtil" + "presentationUtil", + "uiActions", + "dataViews" ] } } diff --git a/examples/controls_example/public/app.tsx b/examples/controls_example/public/app.tsx deleted file mode 100644 index 55ce24ca5fd34..0000000000000 --- a/examples/controls_example/public/app.tsx +++ /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 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 React from 'react'; -import ReactDOM from 'react-dom'; -import { EuiSpacer } from '@elastic/eui'; - -import { AppMountParameters } from '@kbn/core/public'; -import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; -import { ControlsExampleStartDeps } from './plugin'; -import { BasicReduxExample } from './basic_redux_example'; -import { EditExample } from './edit_example'; -import { SearchExample } from './search_example'; -import { AddButtonExample } from './add_button_example'; - -export const renderApp = async ( - { data, navigation }: ControlsExampleStartDeps, - { element }: AppMountParameters -) => { - const dataViews = await data.dataViews.find('kibana_sample_data_logs'); - const examples = - dataViews.length > 0 ? ( - <> - - - - - - - - - ) : ( -
{'Install web logs sample data to run controls examples.'}
- ); - - ReactDOM.render( - - - {examples} - , - element - ); - return () => ReactDOM.unmountComponentAtNode(element); -}; diff --git a/examples/controls_example/public/app/app.tsx b/examples/controls_example/public/app/app.tsx new file mode 100644 index 0000000000000..aad5dc38df167 --- /dev/null +++ b/examples/controls_example/public/app/app.tsx @@ -0,0 +1,90 @@ +/* + * 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 { + EuiPage, + EuiPageBody, + EuiPageHeader, + EuiPageSection, + EuiPageTemplate, + EuiSpacer, + EuiTab, + EuiTabs, +} from '@elastic/eui'; +import React, { useState } from 'react'; +import ReactDOM from 'react-dom'; + +import { AppMountParameters, CoreStart } from '@kbn/core/public'; +import { ControlsExampleStartDeps } from '../plugin'; +import { ControlGroupRendererExamples } from './control_group_renderer_examples'; +import { ReactControlExample } from './react_control_example'; + +const CONTROLS_AS_A_BUILDING_BLOCK = 'controls_as_a_building_block'; +const CONTROLS_REFACTOR_TEST = 'controls_refactor_test'; + +const App = ({ + core, + data, + navigation, +}: { core: CoreStart } & Pick) => { + const [selectedTabId, setSelectedTabId] = useState(CONTROLS_REFACTOR_TEST); // TODO: Make this the first tab + + function onSelectedTabChanged(tabId: string) { + setSelectedTabId(tabId); + } + + function renderTabContent() { + if (selectedTabId === CONTROLS_REFACTOR_TEST) { + return ; + } + + return ; + } + + return ( + + + + + + + + + onSelectedTabChanged(CONTROLS_REFACTOR_TEST)} + isSelected={CONTROLS_REFACTOR_TEST === selectedTabId} + > + Register a new React control + + onSelectedTabChanged(CONTROLS_AS_A_BUILDING_BLOCK)} + isSelected={CONTROLS_AS_A_BUILDING_BLOCK === selectedTabId} + > + Controls as a building block + + + + + + {renderTabContent()} + + + + + ); +}; + +export const renderApp = ( + core: CoreStart, + { data, navigation }: Pick, + { element }: AppMountParameters +) => { + ReactDOM.render(, element); + + return () => ReactDOM.unmountComponentAtNode(element); +}; diff --git a/examples/controls_example/public/app/control_group_renderer_examples.tsx b/examples/controls_example/public/app/control_group_renderer_examples.tsx new file mode 100644 index 0000000000000..f35b713cc3f28 --- /dev/null +++ b/examples/controls_example/public/app/control_group_renderer_examples.tsx @@ -0,0 +1,46 @@ +/* + * 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 React from 'react'; +import useAsync from 'react-use/lib/useAsync'; + +import { EuiLoadingSpinner, EuiSpacer, EuiText } from '@elastic/eui'; +import { SearchExample } from './control_group_renderer_examples/search_example'; +import { EditExample } from './control_group_renderer_examples/edit_example'; +import { BasicReduxExample } from './control_group_renderer_examples/basic_redux_example'; +import { AddButtonExample } from './control_group_renderer_examples/add_button_example'; +import { ControlsExampleStartDeps } from '../plugin'; + +export const ControlGroupRendererExamples = ({ + data, + navigation, +}: Pick) => { + const { + loading, + value: dataViews, + error, + } = useAsync(async () => { + return await data.dataViews.find('kibana_sample_data_logs'); + }, []); + + if (loading) return ; + + return dataViews && dataViews.length > 0 && !error ? ( + <> + + + + + + + + + ) : ( + {'Install web logs sample data to run controls examples.'} + ); +}; diff --git a/examples/controls_example/public/add_button_example.tsx b/examples/controls_example/public/app/control_group_renderer_examples/add_button_example.tsx similarity index 100% rename from examples/controls_example/public/add_button_example.tsx rename to examples/controls_example/public/app/control_group_renderer_examples/add_button_example.tsx diff --git a/examples/controls_example/public/basic_redux_example.tsx b/examples/controls_example/public/app/control_group_renderer_examples/basic_redux_example.tsx similarity index 100% rename from examples/controls_example/public/basic_redux_example.tsx rename to examples/controls_example/public/app/control_group_renderer_examples/basic_redux_example.tsx diff --git a/examples/controls_example/public/edit_example.tsx b/examples/controls_example/public/app/control_group_renderer_examples/edit_example.tsx similarity index 100% rename from examples/controls_example/public/edit_example.tsx rename to examples/controls_example/public/app/control_group_renderer_examples/edit_example.tsx diff --git a/examples/controls_example/public/search_example.tsx b/examples/controls_example/public/app/control_group_renderer_examples/search_example.tsx similarity index 99% rename from examples/controls_example/public/search_example.tsx rename to examples/controls_example/public/app/control_group_renderer_examples/search_example.tsx index 85c37a1e21628..d303e9e2ec973 100644 --- a/examples/controls_example/public/search_example.tsx +++ b/examples/controls_example/public/app/control_group_renderer_examples/search_example.tsx @@ -23,7 +23,7 @@ import { EuiTitle, } from '@elastic/eui'; import { AwaitingControlGroupAPI, ControlGroupRenderer } from '@kbn/controls-plugin/public'; -import { PLUGIN_ID } from './constants'; +import { PLUGIN_ID } from '../../constants'; interface Props { data: DataPublicPluginStart; diff --git a/examples/controls_example/public/app/react_control_example.tsx b/examples/controls_example/public/app/react_control_example.tsx new file mode 100644 index 0000000000000..859f747be1db2 --- /dev/null +++ b/examples/controls_example/public/app/react_control_example.tsx @@ -0,0 +1,234 @@ +/* + * 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 { + EuiButton, + EuiButtonGroup, + EuiCodeBlock, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiSpacer, +} from '@elastic/eui'; +import { CONTROL_GROUP_TYPE } from '@kbn/controls-plugin/common'; +import { CoreStart } from '@kbn/core/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { ReactEmbeddableRenderer, ViewMode } from '@kbn/embeddable-plugin/public'; +import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; +import { PresentationContainer } from '@kbn/presentation-containers'; +import { + HasUniqueId, + PublishesUnifiedSearch, + PublishesViewMode, + useStateFromPublishingSubject, + ViewMode as ViewModeType, +} from '@kbn/presentation-publishing'; +import { toMountPoint } from '@kbn/react-kibana-mount'; +import React, { useEffect, useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; +import useMount from 'react-use/lib/useMount'; +import { BehaviorSubject } from 'rxjs'; +import { ControlGroupApi } from '../react_controls/control_group/types'; + +const toggleViewButtons = [ + { + id: `viewModeToggle_edit`, + value: ViewMode.EDIT, + label: 'Edit mode', + }, + { + id: `viewModeToggle_view`, + value: ViewMode.VIEW, + label: 'View mode', + }, +]; + +/** + * I am mocking the dashboard API so that the data table embeddble responds to changes to the + * data view publishing subject from the control group + */ +type MockedDashboardApi = PresentationContainer & + PublishesViewMode & + PublishesUnifiedSearch & { + publishFilters: (newFilters: Filter[] | undefined) => void; + setViewMode: (newViewMode: ViewMode) => void; + setChild: (child: HasUniqueId) => void; + }; + +export const ReactControlExample = ({ + core, + dataViews: dataViewsService, +}: { + core: CoreStart; + dataViews: DataViewsPublicPluginStart; +}) => { + const [dashboardApi, setDashboardApi] = useState(undefined); + const [controlGroupApi, setControlGroupApi] = useState(undefined); + const viewModeSelected = useStateFromPublishingSubject(dashboardApi?.viewMode); + + useMount(() => { + const viewMode = new BehaviorSubject(ViewMode.EDIT as ViewModeType); + const filters$ = new BehaviorSubject([]); + const query$ = new BehaviorSubject(undefined); + const timeRange$ = new BehaviorSubject(undefined); + const children$ = new BehaviorSubject<{ [key: string]: unknown }>({}); + + setDashboardApi({ + viewMode, + filters$, + query$, + timeRange$, + children$, + publishFilters: (newFilters) => filters$.next(newFilters), + setViewMode: (newViewMode) => viewMode.next(newViewMode), + setChild: (child) => children$.next({ ...children$.getValue(), [child.uuid]: child }), + removePanel: () => {}, + replacePanel: () => { + return Promise.resolve(''); + }, + getPanelCount: () => { + return 2; + }, + addNewPanel: () => { + return Promise.resolve(undefined); + }, + }); + }); + + // TODO: Maybe remove `useAsync` - see https://github.com/elastic/kibana/pull/182842#discussion_r1624909709 + const { + loading, + value: dataViews, + error, + } = useAsync(async () => { + return await dataViewsService.find('kibana_sample_data_logs'); + }, []); + + useEffect(() => { + if (!controlGroupApi) return; + + const subscription = controlGroupApi.filters$.subscribe((controlGroupFilters) => { + if (dashboardApi) dashboardApi.publishFilters(controlGroupFilters); + }); + + return () => { + subscription.unsubscribe(); + }; + }, [dashboardApi, controlGroupApi]); + + if (error || (!dataViews?.[0]?.id && !loading)) + return ( + There was an error!} + body={

{error ? error.message : 'Please add at least one data view.'}

} + /> + ); + + return loading ? ( + + ) : ( + <> + + + { + controlGroupApi?.onEdit(); + }} + size="s" + > + Control group settings + + + + { + core.overlays.openModal( + toMountPoint( + + {JSON.stringify(controlGroupApi?.serializeState(), null, 2)} + , + { + theme: core.theme, + i18n: core.i18n, + } + ) + ); + }} + size="s" + > + Serialize control group + + + + { + dashboardApi?.setViewMode(value); + }} + /> + + + + { + dashboardApi?.setChild(api); + setControlGroupApi(api as ControlGroupApi); + }} + hidePanelChrome={true} + type={CONTROL_GROUP_TYPE} + getParentApi={() => ({ + ...dashboardApi, + getSerializedStateForChild: () => ({ + rawState: { + controlStyle: 'oneLine', + chainingSystem: 'HIERARCHICAL', + showApplySelections: false, + panelsJSON: + '{"a957862f-beae-4f0c-8a3a-a6ea4c235651":{"type":"searchControl","order":0,"grow":true,"width":"medium","explicitInput":{"id":"a957862f-beae-4f0c-8a3a-a6ea4c235651","fieldName":"message","title":"Message","grow":true,"width":"medium","searchString": "this","enhancements":{}}}}', + ignoreParentSettingsJSON: + '{"ignoreFilters":false,"ignoreQuery":false,"ignoreTimerange":false,"ignoreValidations":false}', + } as object, + references: [ + { + name: 'controlGroup_a957862f-beae-4f0c-8a3a-a6ea4c235651:searchControlDataView', + type: 'index-pattern', + id: dataViews?.[0].id!, + }, + ], + }), + })} + key={`control_group`} + /> + +
+ ({ + ...dashboardApi, + getSerializedStateForChild: () => ({ + rawState: { + timeRange: { from: 'now-60d/d', to: 'now+60d/d' }, + }, + references: [], + }), + })} + hidePanelChrome={false} + onApiAvailable={(api) => { + dashboardApi?.setChild(api); + }} + /> +
+ + ); +}; diff --git a/examples/controls_example/public/plugin.tsx b/examples/controls_example/public/plugin.tsx index 235613afda744..57fd451cc81a9 100644 --- a/examples/controls_example/public/plugin.tsx +++ b/examples/controls_example/public/plugin.tsx @@ -6,46 +6,85 @@ * Side Public License, v 1. */ +import { CONTROL_GROUP_TYPE } from '@kbn/controls-plugin/common'; import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public'; +import { EmbeddableSetup, PANEL_HOVER_TRIGGER } from '@kbn/embeddable-plugin/public'; import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public'; -import img from './control_group_image.png'; +import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { PLUGIN_ID } from './constants'; +import img from './control_group_image.png'; +import { EditControlAction } from './react_controls/actions/edit_control_action'; +import { registerControlFactory } from './react_controls/control_factory_registry'; +import { SEARCH_CONTROL_TYPE } from './react_controls/data_controls/search_control/types'; interface SetupDeps { developerExamples: DeveloperExamplesSetup; + embeddable: EmbeddableSetup; } export interface ControlsExampleStartDeps { data: DataPublicPluginStart; navigation: NavigationPublicPluginStart; + uiActions: UiActionsStart; } export class ControlsExamplePlugin implements Plugin { - public setup(core: CoreSetup, { developerExamples }: SetupDeps) { + public setup( + core: CoreSetup, + { developerExamples, embeddable }: SetupDeps + ) { + embeddable.registerReactEmbeddableFactory(CONTROL_GROUP_TYPE, async () => { + const [{ getControlGroupEmbeddableFactory }, [coreStart, depsStart]] = await Promise.all([ + import('./react_controls/control_group/get_control_group_factory'), + core.getStartServices(), + ]); + return getControlGroupEmbeddableFactory({ + core: coreStart, + dataViews: depsStart.data.dataViews, + }); + }); + + registerControlFactory(SEARCH_CONTROL_TYPE, async () => { + const [{ getSearchControlFactory: getSearchEmbeddableFactory }, [coreStart, depsStart]] = + await Promise.all([ + import('./react_controls/data_controls/search_control/get_search_control_factory'), + core.getStartServices(), + ]); + + return getSearchEmbeddableFactory({ + core: coreStart, + dataViewsService: depsStart.data.dataViews, + }); + }); + core.application.register({ id: PLUGIN_ID, title: 'Controls examples', visibleIn: [], async mount(params: AppMountParameters) { - const [, depsStart] = await core.getStartServices(); - const { renderApp } = await import('./app'); - return renderApp(depsStart, params); + const [coreStart, depsStart] = await core.getStartServices(); + const { renderApp } = await import('./app/app'); + return renderApp(coreStart, depsStart, params); }, }); developerExamples.register({ appId: 'controlsExamples', - title: 'Controls as a Building Block', - description: `Showcases different ways to embed a control group into your app`, + title: 'Controls', + description: `Learn how to create new control types and use controls in your application`, image: img, }); } - public start(core: CoreStart) {} + public start(core: CoreStart, deps: ControlsExampleStartDeps) { + const editControlAction = new EditControlAction(); + deps.uiActions.registerAction(editControlAction); + deps.uiActions.attachAction(PANEL_HOVER_TRIGGER, editControlAction.id); + } public stop() {} } diff --git a/examples/controls_example/public/react_controls/actions/edit_control_action.tsx b/examples/controls_example/public/react_controls/actions/edit_control_action.tsx new file mode 100644 index 0000000000000..c8165c2a3642b --- /dev/null +++ b/examples/controls_example/public/react_controls/actions/edit_control_action.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 React from 'react'; + +import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; +import { CONTROL_GROUP_TYPE } from '@kbn/controls-plugin/common'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; +import { i18n } from '@kbn/i18n'; +import { apiIsPresentationContainer } from '@kbn/presentation-containers'; +import { + apiCanAccessViewMode, + apiHasParentApi, + apiHasType, + apiHasUniqueId, + apiIsOfType, + EmbeddableApiContext, + getInheritedViewMode, + hasEditCapabilities, +} from '@kbn/presentation-publishing'; +import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; + +import { DataControlApi } from '../data_controls/types'; + +const isApiCompatible = (api: unknown | null): api is DataControlApi => + Boolean( + apiHasType(api) && + apiHasUniqueId(api) && + hasEditCapabilities(api) && + apiHasParentApi(api) && + apiCanAccessViewMode(api.parentApi) && + apiIsOfType(api.parentApi, CONTROL_GROUP_TYPE) && + apiIsPresentationContainer(api.parentApi) + ); + +const ACTION_EDIT_CONTROL = 'editDataControl'; + +export class EditControlAction implements Action { + public readonly type = ACTION_EDIT_CONTROL; + public readonly id = ACTION_EDIT_CONTROL; + public order = 2; + + constructor() {} + + public readonly MenuItem = ({ context }: { context: EmbeddableApiContext }) => { + if (!isApiCompatible(context.embeddable)) throw new IncompatibleActionError(); + return ( + + this.execute(context)} + color="text" + /> + + ); + }; + + public getDisplayName({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); + return i18n.translate('controls.controlGroup.floatingActions.editTitle', { + defaultMessage: 'Edit', + }); + } + + public getIconType({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); + return 'pencil'; + } + + public async isCompatible({ embeddable }: EmbeddableApiContext) { + return ( + isApiCompatible(embeddable) && + getInheritedViewMode(embeddable.parentApi) === ViewMode.EDIT && + embeddable.isEditingEnabled() + ); + } + + public async execute({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); + await embeddable.onEdit(); + } +} diff --git a/examples/controls_example/public/react_controls/control_error_component.tsx b/examples/controls_example/public/react_controls/control_error_component.tsx new file mode 100644 index 0000000000000..eea1709db6480 --- /dev/null +++ b/examples/controls_example/public/react_controls/control_error_component.tsx @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 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 React, { useState } from 'react'; + +import { EuiButtonEmpty, EuiPopover } from '@elastic/eui'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; +import { Markdown } from '@kbn/shared-ux-markdown'; + +/** TODO: This file is duplicated from the controls plugin to avoid exporting it */ + +interface ControlErrorProps { + error: Error | string; +} + +export const ControlError = ({ error }: ControlErrorProps) => { + const [isPopoverOpen, setPopoverOpen] = useState(false); + const errorMessage = error instanceof Error ? error.message : error; + + const popoverButton = ( + setPopoverOpen((open) => !open)} + className={'errorEmbeddableCompact__button'} + textProps={{ className: 'errorEmbeddableCompact__text' }} + > + + + ); + + return ( + + setPopoverOpen(false)} + > + + {errorMessage} + + + + ); +}; diff --git a/examples/controls_example/public/react_controls/control_factory_registry.ts b/examples/controls_example/public/react_controls/control_factory_registry.ts new file mode 100644 index 0000000000000..b4dcde2d2253d --- /dev/null +++ b/examples/controls_example/public/react_controls/control_factory_registry.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 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 { i18n } from '@kbn/i18n'; +import { ControlFactory, DefaultControlApi } from './types'; + +const registry: { [key: string]: ControlFactory } = {}; + +export const registerControlFactory = async < + State extends object = object, + ApiType extends DefaultControlApi = DefaultControlApi +>( + type: string, + getFactory: () => Promise> +) => { + if (registry[type] !== undefined) + throw new Error( + i18n.translate('controlFactoryRegistry.factoryAlreadyExistsError', { + defaultMessage: 'A control factory for type: {key} is already registered.', + values: { key: type }, + }) + ); + registry[type] = (await getFactory()) as ControlFactory; +}; + +export const getControlFactory = < + State extends object = object, + ApiType extends DefaultControlApi = DefaultControlApi +>( + key: string +): ControlFactory => { + if (registry[key] === undefined) + throw new Error( + i18n.translate('controlFactoryRegistry.factoryNotFoundError', { + defaultMessage: 'No control factory found for type: {key}', + values: { key }, + }) + ); + return registry[key] as ControlFactory; +}; + +export const getAllControlTypes = () => { + return Object.keys(registry); +}; diff --git a/examples/controls_example/public/react_controls/control_group/control_group_editor.tsx b/examples/controls_example/public/react_controls/control_group/control_group_editor.tsx new file mode 100644 index 0000000000000..de62427a1cd1a --- /dev/null +++ b/examples/controls_example/public/react_controls/control_group/control_group_editor.tsx @@ -0,0 +1,245 @@ +/* + * 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 React, { useCallback, useMemo } from 'react'; + +import { + EuiButton, + EuiButtonEmpty, + EuiButtonGroup, + EuiFlexGroup, + EuiFlexItem, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiForm, + EuiFormRow, + EuiHorizontalRule, + EuiIconTip, + EuiSpacer, + EuiSwitch, + EuiTitle, +} from '@elastic/eui'; +import { css } from '@emotion/react'; +import { ControlStyle, ParentIgnoreSettings } from '@kbn/controls-plugin/public'; +import { useBatchedPublishingSubjects } from '@kbn/presentation-publishing'; + +import { ControlStateManager } from '../types'; +import { + ControlGroupEditorStrings, + CONTROL_LAYOUT_OPTIONS, +} from './control_group_editor_constants'; +import { ControlGroupApi, ControlGroupEditorState } from './types'; + +interface EditControlGroupProps { + onCancel: () => void; + onSave: () => void; + onDeleteAll: () => void; + stateManager: ControlStateManager; + api: ControlGroupApi; // controls must always have a parent API +} + +export const ControlGroupEditor = ({ + onCancel, + onSave, + onDeleteAll, + stateManager, + api, +}: EditControlGroupProps) => { + const [ + children, + selectedLabelPosition, + selectedChainingSystem, + selectedShowApplySelections, + selectedIgnoreParentSettings, + ] = useBatchedPublishingSubjects( + api.children$, + stateManager.labelPosition, + stateManager.chainingSystem, + stateManager.showApplySelections, + stateManager.ignoreParentSettings + ); + + const controlCount = useMemo(() => Object.keys(children).length, [children]); + + const updateIgnoreSetting = useCallback( + (newSettings: Partial) => { + stateManager.ignoreParentSettings.next({ + ...(selectedIgnoreParentSettings ?? {}), + ...newSettings, + }); + }, + [stateManager.ignoreParentSettings, selectedIgnoreParentSettings] + ); + + return ( + <> + + +

{ControlGroupEditorStrings.management.getFlyoutTitle()}

+
+
+ + + + { + stateManager.labelPosition.next(newPosition as ControlStyle); + }} + /> + + + +
+ + updateIgnoreSetting({ + ignoreFilters: !e.target.checked, + ignoreQuery: !e.target.checked, + }) + } + checked={ + !Boolean(selectedIgnoreParentSettings?.ignoreFilters) || + !Boolean(selectedIgnoreParentSettings?.ignoreQuery) + } + /> + + updateIgnoreSetting({ ignoreTimerange: !e.target.checked })} + checked={!Boolean(selectedIgnoreParentSettings?.ignoreTimerange)} + /> +
+
+ + +
+ + } + checked={!Boolean(selectedIgnoreParentSettings?.ignoreValidations)} + onChange={(e) => updateIgnoreSetting({ ignoreValidations: !e.target.checked })} + /> + + + } + checked={selectedChainingSystem === 'HIERARCHICAL'} + onChange={(e) => + stateManager.chainingSystem.next(e.target.checked ? 'HIERARCHICAL' : 'NONE') + } + /> + + + } + checked={!selectedShowApplySelections} + onChange={(e) => stateManager.showApplySelections.next(!e.target.checked)} + /> +
+
+ + {controlCount > 0 && ( + <> + + + + {ControlGroupEditorStrings.management.getDeleteAllButtonTitle()} + + + + )} +
+
+ + + + { + onCancel(); + }} + > + {ControlGroupEditorStrings.getCancelTitle()} + + + + { + onSave(); + }} + > + {ControlGroupEditorStrings.getSaveChangesTitle()} + + + + + + ); +}; + +const ControlSettingTooltipLabel = ({ label, tooltip }: { label: string; tooltip: string }) => ( + + {label} + + + + +); diff --git a/examples/controls_example/public/react_controls/control_group/control_group_editor_constants.tsx b/examples/controls_example/public/react_controls/control_group/control_group_editor_constants.tsx new file mode 100644 index 0000000000000..f08e93886ddc3 --- /dev/null +++ b/examples/controls_example/public/react_controls/control_group/control_group_editor_constants.tsx @@ -0,0 +1,113 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const ControlGroupEditorStrings = { + getSaveChangesTitle: () => + i18n.translate('controls.controlGroup.manageControl.saveChangesTitle', { + defaultMessage: 'Save and close', + }), + getCancelTitle: () => + i18n.translate('controls.controlGroup.manageControl.cancelTitle', { + defaultMessage: 'Cancel', + }), + management: { + getFlyoutTitle: () => + i18n.translate('controls.controlGroup.management.flyoutTitle', { + defaultMessage: 'Control settings', + }), + getDeleteAllButtonTitle: () => + i18n.translate('controls.controlGroup.management.deleteAll', { + defaultMessage: 'Delete all', + }), + labelPosition: { + getLabelPositionTitle: () => + i18n.translate('controls.controlGroup.management.labelPosition.title', { + defaultMessage: 'Label position', + }), + getLabelPositionLegend: () => + i18n.translate('controls.controlGroup.management.labelPosition.designSwitchLegend', { + defaultMessage: 'Switch label position between inline and above', + }), + getInlineTitle: () => + i18n.translate('controls.controlGroup.management.labelPosition.inline', { + defaultMessage: 'Inline', + }), + getAboveTitle: () => + i18n.translate('controls.controlGroup.management.labelPosition.above', { + defaultMessage: 'Above', + }), + }, + selectionSettings: { + getSelectionSettingsTitle: () => + i18n.translate('controls.controlGroup.management.selectionSettings', { + defaultMessage: 'Selections', + }), + validateSelections: { + getValidateSelectionsTitle: () => + i18n.translate('controls.controlGroup.management.validate.title', { + defaultMessage: 'Validate user selections', + }), + getValidateSelectionsTooltip: () => + i18n.translate('controls.controlGroup.management.validate.tooltip', { + defaultMessage: 'Highlight control selections that result in no data.', + }), + }, + controlChaining: { + getHierarchyTitle: () => + i18n.translate('controls.controlGroup.management.hierarchy.title', { + defaultMessage: 'Chain controls', + }), + getHierarchyTooltip: () => + i18n.translate('controls.controlGroup.management.hierarchy.tooltip', { + defaultMessage: + 'Selections in one control narrow down available options in the next. Controls are chained from left to right.', + }), + }, + showApplySelections: { + getShowApplySelectionsTitle: () => + i18n.translate('controls.controlGroup.management.showApplySelections.title', { + defaultMessage: 'Apply selections automatically', + }), + getShowApplySelectionsTooltip: () => + i18n.translate('controls.controlGroup.management.showApplySelections.tooltip', { + defaultMessage: + 'If disabled, control selections will only be applied after clicking apply.', + }), + }, + }, + filteringSettings: { + getFilteringSettingsTitle: () => + i18n.translate('controls.controlGroup.management.filteringSettings', { + defaultMessage: 'Filtering', + }), + getUseGlobalFiltersTitle: () => + i18n.translate('controls.controlGroup.management.filtering.useGlobalFilters', { + defaultMessage: 'Apply global filters to controls', + }), + getUseGlobalTimeRangeTitle: () => + i18n.translate('controls.controlGroup.management.filtering.useGlobalTimeRange', { + defaultMessage: 'Apply global time range to controls', + }), + }, + }, +}; + +export const CONTROL_LAYOUT_OPTIONS = [ + { + id: `oneLine`, + 'data-test-subj': 'control-editor-layout-oneLine', + label: ControlGroupEditorStrings.management.labelPosition.getInlineTitle(), + }, + { + id: `twoLine`, + 'data-test-subj': 'control-editor-layout-twoLine', + label: ControlGroupEditorStrings.management.labelPosition.getAboveTitle(), + }, +]; diff --git a/examples/controls_example/public/react_controls/control_group/get_control_group_factory.tsx b/examples/controls_example/public/react_controls/control_group/get_control_group_factory.tsx new file mode 100644 index 0000000000000..703d31f18db1d --- /dev/null +++ b/examples/controls_example/public/react_controls/control_group/get_control_group_factory.tsx @@ -0,0 +1,241 @@ +/* + * 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 React, { useEffect } from 'react'; +import { BehaviorSubject } from 'rxjs'; + +import { + ControlGroupChainingSystem, + ControlWidth, + CONTROL_GROUP_TYPE, + DEFAULT_CONTROL_GROW, + DEFAULT_CONTROL_STYLE, + DEFAULT_CONTROL_WIDTH, +} from '@kbn/controls-plugin/common'; +import { ControlStyle, ParentIgnoreSettings } from '@kbn/controls-plugin/public'; +import { CoreStart } from '@kbn/core/public'; +import { DataView } from '@kbn/data-views-plugin/common'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public'; +import { Filter } from '@kbn/es-query'; +import { i18n } from '@kbn/i18n'; +import { combineCompatibleChildrenApis } from '@kbn/presentation-containers'; +import { + apiPublishesDataViews, + apiPublishesFilters, + PublishesDataViews, + PublishesFilters, + PublishingSubject, + useStateFromPublishingSubject, +} from '@kbn/presentation-publishing'; + +import { EuiFlexGroup } from '@elastic/eui'; +import { ControlRenderer } from '../control_renderer'; +import { DefaultControlApi } from '../types'; +import { openEditControlGroupFlyout } from './open_edit_control_group_flyout'; +import { deserializeControlGroup, serializeControlGroup } from './serialization_utils'; +import { + ControlGroupApi, + ControlGroupRuntimeState, + ControlGroupSerializedState, + ControlGroupUnsavedChanges, +} from './types'; + +export const getControlGroupEmbeddableFactory = (services: { + core: CoreStart; + dataViews: DataViewsPublicPluginStart; +}) => { + const controlGroupEmbeddableFactory: ReactEmbeddableFactory< + ControlGroupSerializedState, + ControlGroupApi, + ControlGroupRuntimeState + > = { + type: CONTROL_GROUP_TYPE, + deserializeState: (state) => deserializeControlGroup(state), + buildEmbeddable: async (initialState, buildApi, uuid, parentApi, setApi) => { + const { + initialChildControlState: childControlState, + defaultControlGrow, + defaultControlWidth, + labelPosition, + chainingSystem, + showApplySelections: initialShowApply, + ignoreParentSettings: initialParentSettings, + } = initialState; + + const children$ = new BehaviorSubject<{ [key: string]: DefaultControlApi }>({}); + const filters$ = new BehaviorSubject([]); + const dataViews = new BehaviorSubject(undefined); + const chainingSystem$ = new BehaviorSubject(chainingSystem); + const showApplySelections = new BehaviorSubject(initialShowApply); + const ignoreParentSettings = new BehaviorSubject( + initialParentSettings + ); + const grow = new BehaviorSubject( + defaultControlGrow === undefined ? DEFAULT_CONTROL_GROW : defaultControlGrow + ); + const width = new BehaviorSubject( + defaultControlWidth ?? DEFAULT_CONTROL_WIDTH + ); + const labelPosition$ = new BehaviorSubject( // TODO: Rename `ControlStyle` + labelPosition ?? DEFAULT_CONTROL_STYLE // TODO: Rename `DEFAULT_CONTROL_STYLE` + ); + + /** TODO: Handle loading; loading should be true if any child is loading */ + const dataLoading$ = new BehaviorSubject(true); + + /** TODO: Handle unsaved changes + * - Each child has an unsaved changed behaviour subject it pushes to + * - The control group listens to all of them (anyChildHasUnsavedChanges) and publishes its + * own unsaved changes if either one of its children has unsaved changes **or** one of + * the control group settings changed. + * - Children should **not** publish unsaved changes based on their output filters or selections. + * Instead, the control group will handle unsaved changes for filters. + */ + const unsavedChanges = new BehaviorSubject | undefined>( + undefined + ); + + const controlOrder = new BehaviorSubject>( + Object.keys(childControlState) + .map((key) => ({ + id: key, + order: childControlState[key].order, + type: childControlState[key].type, + })) + .sort((a, b) => (a.order > b.order ? 1 : -1)) + ); + const api = setApi({ + unsavedChanges, + resetUnsavedChanges: () => { + // TODO: Implement this + }, + snapshotRuntimeState: () => { + // TODO: Remove this if it ends up being unnecessary + return {} as unknown as ControlGroupSerializedState; + }, + dataLoading: dataLoading$, + children$: children$ as PublishingSubject<{ + [key: string]: unknown; + }>, + onEdit: async () => { + openEditControlGroupFlyout( + api, + { + chainingSystem: chainingSystem$, + labelPosition: labelPosition$, + showApplySelections, + ignoreParentSettings, + }, + { core: services.core } + ); + }, + isEditingEnabled: () => true, + getTypeDisplayName: () => + i18n.translate('controls.controlGroup.displayName', { + defaultMessage: 'Controls', + }), + getSerializedStateForChild: (childId) => { + return { rawState: childControlState[childId] }; + }, + serializeState: () => { + return serializeControlGroup( + children$.getValue(), + controlOrder.getValue().map(({ id }) => id), + { + labelPosition: labelPosition$.getValue(), + chainingSystem: chainingSystem$.getValue(), + showApplySelections: showApplySelections.getValue(), + ignoreParentSettings: ignoreParentSettings.getValue(), + } + ); + }, + getPanelCount: () => { + return (Object.keys(children$.getValue()) ?? []).length; + }, + addNewPanel: (panel) => { + // TODO: Add a new child control + return Promise.resolve(undefined); + }, + removePanel: (panelId) => { + // TODO: Remove a child control + }, + replacePanel: async (panelId, newPanel) => { + // TODO: Replace a child control + return Promise.resolve(panelId); + }, + grow, + width, + filters$, + dataViews, + labelPosition: labelPosition$, + }); + + /** + * Subscribe to all children's output filters, combine them, and output them + * TODO: If `showApplySelections` is true, publish to "unpublishedFilters" instead + * and only output to filters$ when the apply button is clicked. + * OR + * Always publish to "unpublishedFilters" and publish them manually on click + * (when `showApplySelections` is true) or after a small debounce (when false) + * See: https://github.com/elastic/kibana/pull/182842#discussion_r1624929511 + * - Note: Unsaved changes of control group **should** take into consideration the + * output filters, but not the "unpublishedFilters" + */ + const outputFiltersSubscription = combineCompatibleChildrenApis( + api, + 'filters$', + apiPublishesFilters, + [] + ).subscribe((newFilters) => filters$.next(newFilters)); + + /** Subscribe to all children's output data views, combine them, and output them */ + const childDataViewsSubscription = combineCompatibleChildrenApis< + PublishesDataViews, + DataView[] + >(api, 'dataViews', apiPublishesDataViews, []).subscribe((newDataViews) => + dataViews.next(newDataViews) + ); + + return { + api, + Component: (props, test) => { + const controlsInOrder = useStateFromPublishingSubject(controlOrder); + + useEffect(() => { + return () => { + outputFiltersSubscription.unsubscribe(); + childDataViewsSubscription.unsubscribe(); + }; + }, []); + + return ( + + {controlsInOrder.map(({ id, type }) => ( + api} + onApiAvailable={(controlApi) => { + children$.next({ + ...children$.getValue(), + [controlApi.uuid]: controlApi, + }); + }} + /> + ))} + + ); + }, + }; + }, + }; + + return controlGroupEmbeddableFactory; +}; diff --git a/examples/controls_example/public/react_controls/control_group/open_edit_control_group_flyout.tsx b/examples/controls_example/public/react_controls/control_group/open_edit_control_group_flyout.tsx new file mode 100644 index 0000000000000..7ca8b993083c3 --- /dev/null +++ b/examples/controls_example/public/react_controls/control_group/open_edit_control_group_flyout.tsx @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { OverlayRef } from '@kbn/core-mount-utils-browser'; +import { CoreStart } from '@kbn/core/public'; +import { i18n } from '@kbn/i18n'; +import { tracksOverlays } from '@kbn/presentation-containers'; +import { apiHasParentApi } from '@kbn/presentation-publishing'; +import { toMountPoint } from '@kbn/react-kibana-mount'; +import React from 'react'; +import { BehaviorSubject } from 'rxjs'; + +import { ControlStateManager } from '../types'; +import { ControlGroupEditor } from './control_group_editor'; +import { ControlGroupApi, ControlGroupEditorState } from './types'; + +export const openEditControlGroupFlyout = ( + controlGroupApi: ControlGroupApi, + stateManager: ControlStateManager, + services: { + core: CoreStart; + } +) => { + /** + * Duplicate all state into a new manager because we do not want to actually apply the changes + * to the control group until the user hits save. + */ + const editorStateManager: ControlStateManager = Object.keys( + stateManager + ).reduce((prev, key) => { + return { + ...prev, + [key as keyof ControlGroupEditorState]: new BehaviorSubject( + stateManager[key as keyof ControlGroupEditorState].getValue() + ), + }; + }, {} as ControlStateManager); + + const closeOverlay = (overlayRef: OverlayRef) => { + if (apiHasParentApi(controlGroupApi) && tracksOverlays(controlGroupApi.parentApi)) { + controlGroupApi.parentApi.clearOverlays(); + } + overlayRef.close(); + }; + + const onDeleteAll = (ref: OverlayRef) => { + services.core.overlays + .openConfirm( + i18n.translate('controls.controlGroup.management.delete.sub', { + defaultMessage: 'Controls are not recoverable once removed.', + }), + { + confirmButtonText: i18n.translate('controls.controlGroup.management.delete.confirm', { + defaultMessage: 'Delete', + }), + cancelButtonText: i18n.translate('controls.controlGroup.management.delete.cancel', { + defaultMessage: 'Cancel', + }), + title: i18n.translate('controls.controlGroup.management.delete.deleteAllTitle', { + defaultMessage: 'Delete all controls?', + }), + buttonColor: 'danger', + } + ) + .then((confirmed) => { + if (confirmed) + Object.keys(controlGroupApi.children$.getValue()).forEach((childId) => { + controlGroupApi.removePanel(childId); + }); + ref.close(); + }); + }; + + const overlay = services.core.overlays.openFlyout( + toMountPoint( + { + Object.keys(stateManager).forEach((key) => { + ( + stateManager[key as keyof ControlGroupEditorState] as BehaviorSubject< + ControlGroupEditorState[keyof ControlGroupEditorState] + > + ).next(editorStateManager[key as keyof ControlGroupEditorState].getValue()); + }); + closeOverlay(overlay); + }} + onDeleteAll={() => onDeleteAll(overlay)} + onCancel={() => closeOverlay(overlay)} + />, + { + theme: services.core.theme, + i18n: services.core.i18n, + } + ), + { + 'aria-label': i18n.translate('controls.controlGroup.manageControl', { + defaultMessage: 'Edit control settings', + }), + outsideClickCloses: false, + onClose: () => closeOverlay(overlay), + } + ); + + if (apiHasParentApi(controlGroupApi) && tracksOverlays(controlGroupApi.parentApi)) { + controlGroupApi.parentApi.openOverlay(overlay); + } +}; diff --git a/examples/controls_example/public/react_controls/control_group/serialization_utils.ts b/examples/controls_example/public/react_controls/control_group/serialization_utils.ts new file mode 100644 index 0000000000000..94566bf20af82 --- /dev/null +++ b/examples/controls_example/public/react_controls/control_group/serialization_utils.ts @@ -0,0 +1,99 @@ +/* + * 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 { Reference } from '@kbn/content-management-utils'; +import { DEFAULT_CONTROL_GROW, DEFAULT_CONTROL_WIDTH } from '@kbn/controls-plugin/common'; +import { SerializedPanelState } from '@kbn/presentation-containers'; +import { omit } from 'lodash'; +import { DefaultControlApi, DefaultControlState } from '../types'; +import { ControlGroupRuntimeState, ControlGroupSerializedState } from './types'; + +export const deserializeControlGroup = ( + state: SerializedPanelState +): ControlGroupRuntimeState => { + const panels = JSON.parse(state.rawState.panelsJSON); + const ignoreParentSettings = JSON.parse(state.rawState.ignoreParentSettingsJSON); + + /** Inject data view references into each individual control */ + const references = state.references ?? []; + references.forEach((reference) => { + const referenceName = reference.name; + const panelId = referenceName.substring('controlGroup_'.length, referenceName.lastIndexOf(':')); + if (panels[panelId]) { + panels[panelId].dataViewId = reference.id; + } + }); + + /** Flatten the state of each panel by removing `explicitInput` */ + const flattenedPanels = Object.keys(panels).reduce((prev, panelId) => { + const currentPanel = panels[panelId]; + const currentPanelExplicitInput = panels[panelId].explicitInput; + return { + ...prev, + [panelId]: { ...omit(currentPanel, 'explicitInput'), ...currentPanelExplicitInput }, + }; + }, {}); + + return { + ...omit(state.rawState, ['panelsJSON', 'ignoreParentSettingsJSON']), + initialChildControlState: flattenedPanels, + ignoreParentSettings, + labelPosition: state.rawState.controlStyle, // Rename "controlStyle" to "labelPosition" + defaultControlGrow: DEFAULT_CONTROL_GROW, + defaultControlWidth: DEFAULT_CONTROL_WIDTH, + }; +}; + +export const serializeControlGroup = ( + children: { + [key: string]: DefaultControlApi; + }, + idsInOrder: string[], + state: Omit< + ControlGroupRuntimeState, + | 'anyChildHasUnsavedChanges' + | 'defaultControlGrow' + | 'defaultControlWidth' + | 'initialChildControlState' + > +): SerializedPanelState => { + let references: Reference[] = []; + + /** Re-add the `explicitInput` layer on serialize so control group saved object retains shape */ + const explicitInputPanels = Object.keys(children).reduce((prev, panelId) => { + const child: DefaultControlApi = children[panelId]; + const type = child.type; + const { + rawState: { grow, width, ...rest }, + references: childReferences, + } = (child.serializeState as () => SerializedPanelState)(); + + if (childReferences && childReferences.length > 0) { + references = [...references, ...childReferences]; + } + + /** + * Note: With legacy control embeddables, `grow` and `width` were duplicated under + * explicit input - this is no longer the case. + */ + return { + ...prev, + [panelId]: { grow, order: idsInOrder.indexOf(panelId), type, width, explicitInput: rest }, + }; + }, {}); + + return { + rawState: { + ...omit(state, ['ignoreParentSettings', 'labelPosition']), + controlStyle: state.labelPosition, // Rename "labelPosition" to "controlStyle" + ignoreParentSettingsJSON: JSON.stringify(state.ignoreParentSettings), + panelsJSON: JSON.stringify(explicitInputPanels), + }, + references, + }; +}; diff --git a/examples/controls_example/public/react_controls/control_group/types.ts b/examples/controls_example/public/react_controls/control_group/types.ts new file mode 100644 index 0000000000000..b1807d31d801b --- /dev/null +++ b/examples/controls_example/public/react_controls/control_group/types.ts @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { ControlGroupChainingSystem } from '@kbn/controls-plugin/common/control_group/types'; +import { ParentIgnoreSettings } from '@kbn/controls-plugin/public'; +import { ControlStyle, ControlWidth } from '@kbn/controls-plugin/public/types'; +import { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public'; +import { Filter } from '@kbn/es-query'; +import { HasSerializedChildState, PresentationContainer } from '@kbn/presentation-containers'; +import { + HasEditCapabilities, + HasParentApi, + PublishesDataLoading, + PublishesFilters, + PublishesUnifiedSearch, + PublishesUnsavedChanges, + PublishingSubject, +} from '@kbn/presentation-publishing'; +import { PublishesDataViews } from '@kbn/presentation-publishing/interfaces/publishes_data_views'; +import { DefaultControlState, PublishesControlDisplaySettings } from '../types'; + +/** The control display settings published by the control group are the "default" */ +type PublishesControlGroupDisplaySettings = PublishesControlDisplaySettings & { + labelPosition: PublishingSubject; +}; +export interface ControlPanelsState { + [panelId: string]: ControlState; +} + +export type ControlGroupUnsavedChanges = Omit< + ControlGroupRuntimeState, + 'initialChildControlState' | 'defaultControlGrow' | 'defaultControlWidth' +> & { + filters: Filter[] | undefined; +}; + +export type ControlPanelState = DefaultControlState & { type: string; order: number }; + +export type ControlGroupApi = PresentationContainer & + DefaultEmbeddableApi & + PublishesFilters & + PublishesDataViews & + HasSerializedChildState & + HasEditCapabilities & + PublishesDataLoading & + PublishesUnsavedChanges & + PublishesControlGroupDisplaySettings & + Partial>; + +export interface ControlGroupRuntimeState { + chainingSystem: ControlGroupChainingSystem; + defaultControlGrow?: boolean; + defaultControlWidth?: ControlWidth; + labelPosition: ControlStyle; // TODO: Rename this type to ControlLabelPosition + showApplySelections?: boolean; + ignoreParentSettings?: ParentIgnoreSettings; + + initialChildControlState: ControlPanelsState; + /** TODO: Handle the editor config, which is used with the control group renderer component */ + editorConfig?: { + hideDataViewSelector?: boolean; + hideWidthSettings?: boolean; + hideAdditionalSettings?: boolean; + }; +} + +export type ControlGroupEditorState = Pick< + ControlGroupRuntimeState, + 'chainingSystem' | 'labelPosition' | 'showApplySelections' | 'ignoreParentSettings' +>; + +export type ControlGroupSerializedState = Omit< + ControlGroupRuntimeState, + | 'labelPosition' + | 'ignoreParentSettings' + | 'defaultControlGrow' + | 'defaultControlWidth' + | 'anyChildHasUnsavedChanges' + | 'initialChildControlState' +> & { + panelsJSON: string; + ignoreParentSettingsJSON: string; + // In runtime state, we refer to this property as `labelPosition`; however, to avoid migrations, we will + // continue to refer to this property as the legacy `controlStyle` in the serialized state + controlStyle: ControlStyle; +}; diff --git a/examples/controls_example/public/react_controls/control_panel.tsx b/examples/controls_example/public/react_controls/control_panel.tsx new file mode 100644 index 0000000000000..ec431e61b9dcf --- /dev/null +++ b/examples/controls_example/public/react_controls/control_panel.tsx @@ -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 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 classNames from 'classnames'; +import React, { useState } from 'react'; + +import { EuiFlexItem, EuiFormControlLayout, EuiFormLabel, EuiFormRow, EuiIcon } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; +import { i18n } from '@kbn/i18n'; +import { + apiHasParentApi, + apiPublishesViewMode, + useBatchedOptionalPublishingSubjects, +} from '@kbn/presentation-publishing'; +import { FloatingActions } from '@kbn/presentation-util-plugin/public'; +import { euiThemeVars } from '@kbn/ui-theme'; + +import { ControlError } from './control_error_component'; +import { ControlPanelProps, DefaultControlApi } from './types'; + +/** + * TODO: Handle dragging + */ +const DragHandle = ({ isEditable, controlTitle }: { isEditable: boolean; controlTitle?: string }) => + isEditable ? ( + + ) : null; + +export const ControlPanel = ({ + Component, +}: ControlPanelProps) => { + const [api, setApi] = useState(null); + + const viewModeSubject = (() => { + if ( + apiHasParentApi(api) && + apiHasParentApi(api.parentApi) && // api.parentApi => controlGroupApi + apiPublishesViewMode(api.parentApi.parentApi) // controlGroupApi.parentApi => dashboardApi + ) + return api.parentApi.parentApi.viewMode; // get view mode from dashboard API + })(); + + const [ + dataLoading, + blockingError, + panelTitle, + defaultPanelTitle, + grow, + width, + labelPosition, + rawViewMode, + ] = useBatchedOptionalPublishingSubjects( + api?.dataLoading, + api?.blockingError, + api?.panelTitle, + api?.defaultPanelTitle, + api?.grow, + api?.width, + api?.parentApi?.labelPosition, + viewModeSubject + ); + const usingTwoLineLayout = labelPosition === 'twoLine'; + + const [initialLoadComplete, setInitialLoadComplete] = useState(!dataLoading); + if (!initialLoadComplete && (dataLoading === false || (api && !api.dataLoading))) { + setInitialLoadComplete(true); + } + + const viewMode = (rawViewMode ?? ViewMode.VIEW) as ViewMode; + const isEditable = viewMode === ViewMode.EDIT; + + return ( + (draggingIndex ?? -1), + })} + > + + + {blockingError ? ( + + + + ) : ( + {api.getCustomPrepend()} + ) : usingTwoLineLayout ? ( + + ) : ( + <> + {' '} + + {panelTitle || defaultPanelTitle} + + + ) + } + > + { + if (newApi && !api) setApi(newApi); + }} + /> + + )} + + + + ); +}; diff --git a/examples/controls_example/public/react_controls/control_renderer.tsx b/examples/controls_example/public/react_controls/control_renderer.tsx new file mode 100644 index 0000000000000..471b12894bae7 --- /dev/null +++ b/examples/controls_example/public/react_controls/control_renderer.tsx @@ -0,0 +1,86 @@ +/* + * 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 React, { useImperativeHandle, useMemo } from 'react'; +import { BehaviorSubject } from 'rxjs'; +import { v4 as generateId } from 'uuid'; + +import { SerializedStyles } from '@emotion/react'; +import { StateComparators } from '@kbn/presentation-publishing'; + +import { getControlFactory } from './control_factory_registry'; +import { ControlGroupApi } from './control_group/types'; +import { ControlPanel } from './control_panel'; +import { ControlApiRegistration, DefaultControlApi, DefaultControlState } from './types'; + +/** + * Renders a component from the control registry into a Control Panel + */ +export const ControlRenderer = < + StateType extends DefaultControlState = DefaultControlState, + ApiType extends DefaultControlApi = DefaultControlApi +>({ + type, + maybeId, + getParentApi, + onApiAvailable, +}: { + type: string; + maybeId?: string; + getParentApi: () => ControlGroupApi; + onApiAvailable?: (api: ApiType) => void; +}) => { + const component = useMemo( + () => + (() => { + const parentApi = getParentApi(); + const uuid = maybeId ?? generateId(); + const factory = getControlFactory(type); + + const buildApi = ( + apiRegistration: ControlApiRegistration, + comparators: StateComparators // TODO: Use these to calculate unsaved changes + ): ApiType => { + const fullApi = { + ...apiRegistration, + uuid, + parentApi, + unsavedChanges: new BehaviorSubject | undefined>(undefined), + resetUnsavedChanges: () => {}, + type: factory.type, + } as unknown as ApiType; + + onApiAvailable?.(fullApi); + return fullApi; + }; + + const { rawState: initialState } = parentApi.getSerializedStateForChild(uuid); + + const { api, Component } = factory.buildControl( + initialState as unknown as StateType, + buildApi, + uuid, + parentApi + ); + + return React.forwardRef((props, ref) => { + // expose the api into the imperative handle + useImperativeHandle(ref, () => api, []); + return ; + }); + })(), + /** + * Disabling exhaustive deps because we do not want to re-fetch the component + * from the embeddable registry unless the type changes. + */ + // eslint-disable-next-line react-hooks/exhaustive-deps + [type] + ); + + return Component={component} />; +}; diff --git a/examples/controls_example/public/react_controls/data_controls/data_control_constants.tsx b/examples/controls_example/public/react_controls/data_controls/data_control_constants.tsx new file mode 100644 index 0000000000000..9bc9eddbfc0d2 --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/data_control_constants.tsx @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { RANGE_SLIDER_CONTROL } from '@kbn/controls-plugin/common'; +import { i18n } from '@kbn/i18n'; + +export const DataControlEditorStrings = { + manageControl: { + getFlyoutCreateTitle: () => + i18n.translate('controls.controlGroup.manageControl.createFlyoutTitle', { + defaultMessage: 'Create control', + }), + getFlyoutEditTitle: () => + i18n.translate('controls.controlGroup.manageControl.editFlyoutTitle', { + defaultMessage: 'Edit control', + }), + dataSource: { + getFormGroupTitle: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.formGroupTitle', { + defaultMessage: 'Data source', + }), + getFormGroupDescription: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.formGroupDescription', { + defaultMessage: 'Select the data view and field that you want to create a control for.', + }), + getSelectDataViewMessage: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.selectDataViewMessage', { + defaultMessage: 'Please select a data view', + }), + getDataViewTitle: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.dataViewTitle', { + defaultMessage: 'Data view', + }), + getDataViewListErrorTitle: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.dataViewListErrorTitle', { + defaultMessage: 'Error loading data views', + }), + getFieldTitle: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.fieldTitle', { + defaultMessage: 'Field', + }), + getFieldListErrorTitle: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.fieldListErrorTitle', { + defaultMessage: 'Error loading the field list', + }), + getControlTypeTitle: () => + i18n.translate('controls.controlGroup.manageControl.dataSource.controlTypesTitle', { + defaultMessage: 'Control type', + }), + getControlTypeErrorMessage: ({ + fieldSelected, + controlType, + }: { + fieldSelected?: boolean; + controlType?: string; + }) => { + if (!fieldSelected) { + return i18n.translate( + 'controls.controlGroup.manageControl.dataSource.controlTypErrorMessage.noField', + { + defaultMessage: 'Select a field first.', + } + ); + } + + switch (controlType) { + /** + * Note that options list controls are currently compatible with every field type; so, there is no + * need to have a special error message for these. + */ + case RANGE_SLIDER_CONTROL: { + return i18n.translate( + 'controls.controlGroup.manageControl.dataSource.controlTypeErrorMessage.rangeSlider', + { + defaultMessage: 'Range sliders are only compatible with number fields.', + } + ); + } + default: { + /** This shouldn't ever happen - but, adding just in case as a fallback. */ + return i18n.translate( + 'controls.controlGroup.manageControl.dataSource.controlTypeErrorMessage.default', + { + defaultMessage: 'Select a compatible control type.', + } + ); + } + } + }, + }, + displaySettings: { + getFormGroupTitle: () => + i18n.translate('controls.controlGroup.manageControl.displaySettings.formGroupTitle', { + defaultMessage: 'Display settings', + }), + getFormGroupDescription: () => + i18n.translate('controls.controlGroup.manageControl.displaySettings.formGroupDescription', { + defaultMessage: 'Change how the control appears on your dashboard.', + }), + getTitleInputTitle: () => + i18n.translate('controls.controlGroup.manageControl.displaySettings.titleInputTitle', { + defaultMessage: 'Label', + }), + getWidthInputTitle: () => + i18n.translate('controls.controlGroup.manageControl.displaySettings.widthInputTitle', { + defaultMessage: 'Minimum width', + }), + getGrowSwitchTitle: () => + i18n.translate('controls.controlGroup.manageControl.displaySettings.growSwitchTitle', { + defaultMessage: 'Expand width to fit available space', + }), + }, + controlTypeSettings: { + getFormGroupTitle: (type: string) => + i18n.translate('controls.controlGroup.manageControl.controlTypeSettings.formGroupTitle', { + defaultMessage: '{controlType} settings', + values: { controlType: type }, + }), + getFormGroupDescription: (type: string) => + i18n.translate( + 'controls.controlGroup.manageControl.controlTypeSettings.formGroupDescription', + { + defaultMessage: 'Custom settings for your {controlType} control.', + values: { controlType: type.toLocaleLowerCase() }, + } + ), + }, + getSaveChangesTitle: () => + i18n.translate('controls.controlGroup.manageControl.saveChangesTitle', { + defaultMessage: 'Save and close', + }), + getCancelTitle: () => + i18n.translate('controls.controlGroup.manageControl.cancelTitle', { + defaultMessage: 'Cancel', + }), + getDeleteButtonTitle: () => + i18n.translate('controls.controlGroup.management.delete', { + defaultMessage: 'Delete control', + }), + }, + management: { + controlWidth: { + getWidthSwitchLegend: () => + i18n.translate('controls.controlGroup.management.layout.controlWidthLegend', { + defaultMessage: 'Change control size', + }), + }, + }, +}; diff --git a/examples/controls_example/public/react_controls/data_controls/data_control_editor.tsx b/examples/controls_example/public/react_controls/data_controls/data_control_editor.tsx new file mode 100644 index 0000000000000..9f0db921b0778 --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/data_control_editor.tsx @@ -0,0 +1,403 @@ +/* * 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 React, { useEffect, useMemo, useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; + +import { + EuiButton, + EuiButtonEmpty, + EuiButtonGroup, + EuiCallOut, + EuiDescribedFormGroup, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiForm, + EuiFormRow, + EuiIcon, + EuiKeyPadMenu, + EuiKeyPadMenuItem, + EuiSpacer, + EuiSwitch, + EuiTitle, + EuiToolTip, +} from '@elastic/eui'; +import { DataViewField } from '@kbn/data-views-plugin/common'; +import { useBatchedPublishingSubjects } from '@kbn/presentation-publishing'; +import { + LazyDataViewPicker, + LazyFieldPicker, + withSuspense, +} from '@kbn/presentation-util-plugin/public'; + +import { + ControlWidth, + DEFAULT_CONTROL_GROW, + DEFAULT_CONTROL_WIDTH, +} from '@kbn/controls-plugin/common'; +import { CONTROL_WIDTH_OPTIONS } from '@kbn/controls-plugin/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { getAllControlTypes, getControlFactory } from '../control_factory_registry'; +import { ControlGroupApi } from '../control_group/types'; +import { ControlStateManager } from '../types'; +import { DataControlEditorStrings } from './data_control_constants'; +import { getDataControlFieldRegistry } from './data_control_editor_utils'; +import { DataControlFactory, DefaultDataControlState, isDataControlFactory } from './types'; + +export interface ControlEditorProps< + State extends DefaultDataControlState = DefaultDataControlState +> { + controlId?: string; // if provided, then editing existing control; otherwise, creating a new control + controlType?: string; + onCancel: () => void; + onSave: (type?: string) => void; + stateManager: ControlStateManager; + parentApi: ControlGroupApi; // controls must always have a parent API + services: { + dataViews: DataViewsPublicPluginStart; + }; +} + +const FieldPicker = withSuspense(LazyFieldPicker, null); +const DataViewPicker = withSuspense(LazyDataViewPicker, null); + +export const DataControlEditor = ({ + controlId, + controlType, + onSave, + onCancel, + stateManager, + parentApi: controlGroup, + /** TODO: These should not be props */ + services: { dataViews: dataViewService }, +}: ControlEditorProps) => { + const [ + selectedDataViewId, + selectedFieldName, + currentTitle, + selectedGrow, + selectedWidth, + defaultGrow, + defaultWidth, + ] = useBatchedPublishingSubjects( + stateManager.dataViewId, + stateManager.fieldName, + stateManager.title, + stateManager.grow, + stateManager.width, + controlGroup.grow, + controlGroup.width + // controlGroup.lastUsedDataViewId, // TODO: Implement last used data view id + ); + + const [selectedFieldDisplayName, setSelectedFieldDisplayName] = useState(selectedFieldName); + const [selectedControlType, setSelectedControlType] = useState(controlType); + const [controlEditorValid, setControlEditorValid] = useState(false); + /** TODO: Make `editorConfig` work when refactoring the `ControlGroupRenderer` */ + // const editorConfig = controlGroup.getEditorConfig(); + + // TODO: Maybe remove `useAsync` - see https://github.com/elastic/kibana/pull/182842#discussion_r1624909709 + const { + loading: dataViewListLoading, + value: dataViewListItems = [], + error: dataViewListError, + } = useAsync(() => { + return dataViewService.getIdsWithTitle(); + }); + + // TODO: Maybe remove `useAsync` - see https://github.com/elastic/kibana/pull/182842#discussion_r1624909709 + const { + loading: dataViewLoading, + value: { selectedDataView, fieldRegistry } = { + selectedDataView: undefined, + fieldRegistry: undefined, + }, + error: fieldListError, + } = useAsync(async () => { + if (!selectedDataViewId) { + return; + } + const dataView = await dataViewService.get(selectedDataViewId); + const registry = await getDataControlFieldRegistry(dataView); + return { + selectedDataView: dataView, + fieldRegistry: registry, + }; + }, [selectedDataViewId]); + + useEffect(() => { + setControlEditorValid( + Boolean(selectedFieldName) && Boolean(selectedDataView) && Boolean(selectedControlType) + ); + }, [selectedFieldName, setControlEditorValid, selectedDataView, selectedControlType]); + + const dataControlFactories = useMemo(() => { + return getAllControlTypes() + .map((type) => getControlFactory(type)) + .filter((factory) => { + return isDataControlFactory(factory); + }); + }, []); + + const CompatibleControlTypesComponent = useMemo(() => { + return ( + + {dataControlFactories.map((factory) => { + const disabled = + fieldRegistry && selectedFieldName + ? !fieldRegistry[selectedFieldName]?.compatibleControlTypes.includes(factory.type) + : true; + const keyPadMenuItem = ( + setSelectedControlType(factory.type)} + label={factory.getDisplayName()} + > + + + ); + + return disabled ? ( + + {keyPadMenuItem} + + ) : ( + keyPadMenuItem + ); + })} + + ); + }, [selectedFieldName, fieldRegistry, selectedControlType, controlType, dataControlFactories]); + + const CustomSettingsComponent = useMemo(() => { + if (!selectedControlType || !selectedFieldName || !fieldRegistry) return; + + const controlFactory = getControlFactory(selectedControlType) as DataControlFactory; + const CustomSettings = controlFactory.CustomOptionsComponent; + + if (!CustomSettings) return; + + return ( + + {DataControlEditorStrings.manageControl.controlTypeSettings.getFormGroupTitle( + controlFactory.getDisplayName() + )} + + } + description={DataControlEditorStrings.manageControl.controlTypeSettings.getFormGroupDescription( + controlFactory.getDisplayName() + )} + data-test-subj="control-editor-custom-settings" + > + + + ); + }, [fieldRegistry, selectedControlType, selectedFieldName, stateManager]); + + return ( + <> + + +

+ {!controlType + ? DataControlEditorStrings.manageControl.getFlyoutCreateTitle() + : DataControlEditorStrings.manageControl.getFlyoutEditTitle()} +

+
+
+ + + {DataControlEditorStrings.manageControl.dataSource.getFormGroupTitle()}} + description={DataControlEditorStrings.manageControl.dataSource.getFormGroupDescription()} + > + {/* {!editorConfig?.hideDataViewSelector && ( */} + + {dataViewListError ? ( + +

{dataViewListError.message}

+
+ ) : ( + { + stateManager.dataViewId.next(newDataViewId); + }} + trigger={{ + label: + selectedDataView?.getName() ?? + DataControlEditorStrings.manageControl.dataSource.getSelectDataViewMessage(), + }} + selectableProps={{ isLoading: dataViewListLoading }} + /> + )} +
+ {/* )} */} + + + {fieldListError ? ( + +

{fieldListError.message}

+
+ ) : ( + { + /** TODO: Make `fieldFilterPredicate` work when refactoring the `ControlGroupRenderer` */ + // const customPredicate = controlGroup.fieldFilterPredicate?.(field) ?? true; + return Boolean(fieldRegistry?.[field.name]); + }} + selectedFieldName={selectedFieldName} + dataView={selectedDataView} + onSelectField={(field) => { + setSelectedControlType(fieldRegistry?.[field.name]?.compatibleControlTypes[0]); + const newDefaultTitle = field.displayName ?? field.name; + stateManager.fieldName.next(field.name); + setSelectedFieldDisplayName(newDefaultTitle); + if (!currentTitle || currentTitle === selectedFieldDisplayName) { + stateManager.title.next(newDefaultTitle); + } + }} + selectableProps={{ isLoading: dataViewListLoading || dataViewLoading }} + /> + )} +
+ + {CompatibleControlTypesComponent} + +
+ {DataControlEditorStrings.manageControl.displaySettings.getFormGroupTitle()} + } + description={DataControlEditorStrings.manageControl.displaySettings.getFormGroupDescription()} + > + + stateManager.title.next(e.target.value)} + /> + + {/* {!editorConfig?.hideWidthSettings && ( */} + +
+ stateManager.width.next(newWidth as ControlWidth)} + /> + + stateManager.grow.next(!selectedGrow)} + data-test-subj="control-editor-grow-switch" + /> +
+
+ {/* )} */} +
+ {CustomSettingsComponent} + {/* {!editorConfig?.hideAdditionalSettings ? CustomSettingsComponent : null} */} + {controlId && ( + <> + + { + onCancel(); + controlGroup.removePanel(controlId); + }} + > + {DataControlEditorStrings.manageControl.getDeleteButtonTitle()} + + + )} +
+
+ + + + { + onCancel(); + }} + > + {DataControlEditorStrings.manageControl.getCancelTitle()} + + + + { + onSave(); + }} + > + {DataControlEditorStrings.manageControl.getSaveChangesTitle()} + + + + + + ); +}; diff --git a/examples/controls_example/public/react_controls/data_controls/data_control_editor_utils.ts b/examples/controls_example/public/react_controls/data_controls/data_control_editor_utils.ts new file mode 100644 index 0000000000000..d4ced0b1aafa6 --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/data_control_editor_utils.ts @@ -0,0 +1,46 @@ +/* + * 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 { memoize } from 'lodash'; + +import { DataControlFieldRegistry } from '@kbn/controls-plugin/public/types'; +import { DataView } from '@kbn/data-views-plugin/common'; +import { getAllControlTypes, getControlFactory } from '../control_factory_registry'; +import { isDataControlFactory } from './types'; + +/** TODO: This funciton is duplicated from the controls plugin to avoid exporting it */ +export const getDataControlFieldRegistry = memoize( + async (dataView: DataView) => { + return await loadFieldRegistryFromDataView(dataView); + }, + (dataView: DataView) => [dataView.id, JSON.stringify(dataView.fields.getAll())].join('|') +); + +/** TODO: This function is duplicated from the controls plugin to avoid exporting it */ +const loadFieldRegistryFromDataView = async ( + dataView: DataView +): Promise => { + const controlFactories = getAllControlTypes().map((controlType) => + getControlFactory(controlType) + ); + const fieldRegistry: DataControlFieldRegistry = {}; + return new Promise((resolve) => { + for (const field of dataView.fields.getAll()) { + const compatibleControlTypes = []; + for (const factory of controlFactories) { + if (isDataControlFactory(factory) && factory.isFieldCompatible(field)) { + compatibleControlTypes.push(factory.type); + } + } + if (compatibleControlTypes.length > 0) { + fieldRegistry[field.name] = { field, compatibleControlTypes }; + } + } + resolve(fieldRegistry); + }); +}; diff --git a/examples/controls_example/public/react_controls/data_controls/initialize_data_control.tsx b/examples/controls_example/public/react_controls/data_controls/initialize_data_control.tsx new file mode 100644 index 0000000000000..988104ca11d1a --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/initialize_data_control.tsx @@ -0,0 +1,137 @@ +/* + * 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 { BehaviorSubject, combineLatestWith, switchMap } from 'rxjs'; + +import { CoreStart } from '@kbn/core-lifecycle-browser'; +import { DataView, DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { Filter } from '@kbn/es-query'; +import { SerializedPanelState } from '@kbn/presentation-containers'; +import { StateComparators } from '@kbn/presentation-publishing'; + +import { ControlGroupApi } from '../control_group/types'; +import { initializeDefaultControlApi } from '../initialize_default_control_api'; +import { ControlApiInitialization, ControlStateManager, DefaultControlState } from '../types'; +import { openDataControlEditor } from './open_data_control_editor'; +import { DataControlApi, DefaultDataControlState } from './types'; + +export const initializeDataControl = ( + controlId: string, + controlType: string, + state: DefaultDataControlState, + editorStateManager: ControlStateManager, + controlGroup: ControlGroupApi, + services: { + core: CoreStart; + dataViews: DataViewsPublicPluginStart; + } +): { + dataControlApi: ControlApiInitialization; + dataControlComparators: StateComparators; + dataControlStateManager: ControlStateManager; + serializeDataControl: () => SerializedPanelState; +} => { + const { + defaultControlApi, + defaultControlComparators, + defaultControlStateManager, + serializeDefaultControl, + } = initializeDefaultControlApi(state); + + const panelTitle = new BehaviorSubject(state.title); + const defaultPanelTitle = new BehaviorSubject(undefined); + const dataViewId = new BehaviorSubject(state.dataViewId); + const fieldName = new BehaviorSubject(state.fieldName); + const dataViews = new BehaviorSubject(undefined); + const filters = new BehaviorSubject(undefined); + + const dataControlComparators: StateComparators = { + ...defaultControlComparators, + title: [panelTitle, (value: string | undefined) => panelTitle.next(value)], + dataViewId: [dataViewId, (value: string) => dataViewId.next(value)], + fieldName: [fieldName, (value: string) => fieldName.next(value)], + }; + + const stateManager: ControlStateManager = { + ...defaultControlStateManager, + dataViewId, + fieldName, + title: panelTitle, + }; + + /** + * Fetch the data view + field whenever the selected data view ID or field name changes; use the + * fetched field spec to set the default panel title, which is always equal to either the field + * name or the field's display name. + */ + dataViewId + .pipe( + combineLatestWith(fieldName), + switchMap(async ([currentDataViewId, currentFieldName]) => { + defaultControlApi.setDataLoading(true); + const dataView = await services.dataViews.get(currentDataViewId); + const field = dataView.getFieldByName(currentFieldName); + defaultControlApi.setDataLoading(false); + return { dataView, field }; + }) + ) + .subscribe(async ({ dataView, field }) => { + if (!dataView || !field) return; + dataViews.next([dataView]); + defaultPanelTitle.next(field.displayName || field.name); + }); + + const onEdit = async () => { + openDataControlEditor( + { ...stateManager, ...editorStateManager } as ControlStateManager< + DefaultDataControlState & EditorState + >, + controlGroup, + services, + controlType, + controlId + ); + }; + + const dataControlApi: ControlApiInitialization = { + ...defaultControlApi, + panelTitle, + defaultPanelTitle, + dataViews, + onEdit, + filters$: filters, + setOutputFilter: (newFilter: Filter | undefined) => { + filters.next(newFilter ? [newFilter] : undefined); + }, + isEditingEnabled: () => true, + }; + + return { + dataControlApi, + dataControlComparators, + dataControlStateManager: stateManager, + serializeDataControl: () => { + return { + rawState: { + ...serializeDefaultControl().rawState, + dataViewId: dataViewId.getValue(), + fieldName: fieldName.getValue(), + title: panelTitle.getValue(), + }, + references: [ + { + name: `controlGroup_${controlId}:${controlType}DataView`, + type: DATA_VIEW_SAVED_OBJECT_TYPE, + id: dataViewId.getValue(), + }, + ], + }; + }, + }; +}; diff --git a/examples/controls_example/public/react_controls/data_controls/open_data_control_editor.tsx b/examples/controls_example/public/react_controls/data_controls/open_data_control_editor.tsx new file mode 100644 index 0000000000000..5c25ffcc7947d --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/open_data_control_editor.tsx @@ -0,0 +1,131 @@ +/* + * 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 React from 'react'; +import deepEqual from 'react-fast-compare'; +import { BehaviorSubject } from 'rxjs'; + +import { CoreStart, OverlayRef } from '@kbn/core/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { i18n } from '@kbn/i18n'; +import { tracksOverlays } from '@kbn/presentation-containers'; +import { apiHasParentApi } from '@kbn/presentation-publishing'; +import { toMountPoint } from '@kbn/react-kibana-mount'; + +import { ControlGroupApi } from '../control_group/types'; +import { DataControlEditor } from './data_control_editor'; +import { DefaultDataControlState } from './types'; +import { ControlStateManager } from '../types'; + +export const openDataControlEditor = async < + State extends DefaultDataControlState = DefaultDataControlState +>( + stateManager: ControlStateManager, + controlGroupApi: ControlGroupApi, + services: { + core: CoreStart; + dataViews: DataViewsPublicPluginStart; + }, + controlType?: string, + controlId?: string +): Promise => { + return new Promise((resolve) => { + /** + * Duplicate all state into a new manager because we do not want to actually apply the changes + * to the control until the user hits save. + */ + const editorStateManager: ControlStateManager = Object.keys(stateManager).reduce( + (prev, key) => { + return { + ...prev, + [key as keyof State]: new BehaviorSubject(stateManager[key as keyof State].getValue()), + }; + }, + {} as ControlStateManager + ); + + const closeOverlay = (overlayRef: OverlayRef) => { + if (apiHasParentApi(controlGroupApi) && tracksOverlays(controlGroupApi.parentApi)) { + controlGroupApi.parentApi.clearOverlays(); + } + overlayRef.close(); + }; + + const onCancel = (overlay: OverlayRef) => { + const initialState = Object.keys(stateManager).map((key) => { + return stateManager[key as keyof State].getValue(); + }); + const newState = Object.keys(editorStateManager).map((key) => { + return editorStateManager[key as keyof State].getValue(); + }); + + if (deepEqual(initialState, newState)) { + closeOverlay(overlay); + return; + } + services.core.overlays + .openConfirm( + i18n.translate('controls.controlGroup.management.discard.sub', { + defaultMessage: `Changes that you've made to this control will be discarded, are you sure you want to continue?`, + }), + { + confirmButtonText: i18n.translate('controls.controlGroup.management.discard.confirm', { + defaultMessage: 'Discard changes', + }), + cancelButtonText: i18n.translate('controls.controlGroup.management.discard.cancel', { + defaultMessage: 'Cancel', + }), + title: i18n.translate('controls.controlGroup.management.discard.title', { + defaultMessage: 'Discard changes?', + }), + buttonColor: 'danger', + } + ) + .then((confirmed) => { + if (confirmed) { + closeOverlay(overlay); + } + }); + }; + + const overlay = services.core.overlays.openFlyout( + toMountPoint( + { + onCancel(overlay); + }} + onSave={() => { + Object.keys(stateManager).forEach((key) => { + stateManager[key as keyof State].next( + editorStateManager[key as keyof State].getValue() + ); + }); + closeOverlay(overlay); + resolve(undefined); + }} + stateManager={editorStateManager} + services={{ dataViews: services.dataViews }} + />, + { + theme: services.core.theme, + i18n: services.core.i18n, + } + ), + { + onClose: () => closeOverlay(overlay), + } + ); + + if (apiHasParentApi(controlGroupApi) && tracksOverlays(controlGroupApi.parentApi)) { + controlGroupApi.parentApi.openOverlay(overlay); + } + }); +}; diff --git a/examples/controls_example/public/react_controls/data_controls/search_control/get_search_control_factory.tsx b/examples/controls_example/public/react_controls/data_controls/search_control/get_search_control_factory.tsx new file mode 100644 index 0000000000000..6e401cff5a37c --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/search_control/get_search_control_factory.tsx @@ -0,0 +1,227 @@ +/* + * 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 React, { useEffect } from 'react'; +import deepEqual from 'react-fast-compare'; +import { BehaviorSubject, combineLatest, debounceTime, distinctUntilChanged } from 'rxjs'; + +import { EuiFieldSearch, EuiFormRow, EuiRadioGroup } from '@elastic/eui'; +import { CoreStart } from '@kbn/core/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { i18n } from '@kbn/i18n'; +import { useStateFromPublishingSubject } from '@kbn/presentation-publishing'; + +import { initializeDataControl } from '../initialize_data_control'; +import { DataControlFactory } from '../types'; +import { + SearchControlApi, + SearchControlState, + SearchControlTechniques, + SEARCH_CONTROL_TYPE, +} from './types'; + +const allSearchOptions = [ + { + id: 'match', + label: i18n.translate('controlsExamples.searchControl.searchTechnique.match', { + defaultMessage: 'Fuzzy match', + }), + 'data-test-subj': 'searchControl__matchSearchOptionAdditionalSetting', + }, + { + id: 'simple_query_string', + label: i18n.translate('controlsExamples.searchControl.searchTechnique.simpleQueryString', { + defaultMessage: 'Query string', + }), + 'data-test-subj': 'optionsListControl__queryStringSearchOptionAdditionalSetting', + }, +]; + +const DEFAULT_SEARCH_TECHNIQUE = 'match'; + +export const getSearchControlFactory = ({ + core, + dataViewsService, +}: { + core: CoreStart; + dataViewsService: DataViewsPublicPluginStart; +}): DataControlFactory => { + return { + type: SEARCH_CONTROL_TYPE, + getIconType: () => 'search', + getDisplayName: () => + i18n.translate('controlsExamples.searchControl.displayName', { defaultMessage: 'Search' }), + isFieldCompatible: (field) => { + return ( + field.searchable && + field.spec.type === 'string' && + (field.spec.esTypes ?? []).includes('text') + ); + }, + CustomOptionsComponent: ({ stateManager }) => { + const searchTechnique = useStateFromPublishingSubject(stateManager.searchTechnique); + + return ( + + { + const newSearchTechnique = id as SearchControlTechniques; + stateManager.searchTechnique.next(newSearchTechnique); + }} + /> + + ); + }, + buildControl: (initialState, buildApi, uuid, parentApi) => { + const searchString = new BehaviorSubject(initialState.searchString); + const searchTechnique = new BehaviorSubject( + initialState.searchTechnique ?? DEFAULT_SEARCH_TECHNIQUE + ); + const editorStateManager = { searchTechnique }; + + const { + dataControlApi, + dataControlComparators, + dataControlStateManager, + serializeDataControl, + } = initializeDataControl>( + uuid, + SEARCH_CONTROL_TYPE, + initialState, + editorStateManager, + parentApi, + { + core, + dataViews: dataViewsService, + } + ); + + const api = buildApi( + { + ...dataControlApi, + getTypeDisplayName: () => + i18n.translate('controlsExamples.searchControl.displayName', { + defaultMessage: 'Search', + }), + serializeState: () => { + const { rawState: dataControlState, references } = serializeDataControl(); + return { + rawState: { + ...dataControlState, + searchString: searchString.getValue(), + searchTechnique: searchTechnique.getValue(), + }, + references, // does not have any references other than those provided by the data control serializer + }; + }, + clearSelections: () => { + searchString.next(undefined); + }, + }, + { + ...dataControlComparators, + searchTechnique: [ + searchTechnique, + (newTechnique: SearchControlTechniques | undefined) => + searchTechnique.next(newTechnique), + ], + searchString: [ + searchString, + (newString: string | undefined) => + searchString.next(newString?.length === 0 ? undefined : newString), + ], + } + ); + + /** + * If either the search string or the search technique changes, recalulate the output filter + */ + const onSearchStringChanged = combineLatest([searchString, searchTechnique]) + .pipe(debounceTime(200), distinctUntilChanged(deepEqual)) + .subscribe(([newSearchString, currentSearchTechnnique]) => { + const currentDataView = dataControlApi.dataViews.getValue()?.[0]; + const currentField = dataControlStateManager.fieldName.getValue(); + + if (currentDataView && currentField) { + if (newSearchString) { + api.setOutputFilter( + currentSearchTechnnique === 'match' + ? { + query: { match: { [currentField]: { query: newSearchString } } }, + meta: { index: currentDataView.id }, + } + : { + query: { + simple_query_string: { + query: newSearchString, + fields: [currentField], + default_operator: 'and', + }, + }, + meta: { index: currentDataView.id }, + } + ); + } else { + api.setOutputFilter(undefined); + } + } + }); + + /** + * When the field changes (which can happen if either the field name or the dataview id changes), + * clear the previous search string. + */ + const onFieldChanged = combineLatest([ + dataControlStateManager.fieldName, + dataControlStateManager.dataViewId, + ]) + .pipe(distinctUntilChanged(deepEqual)) + .subscribe(() => { + searchString.next(undefined); + }); + + return { + api, + /** + * The `conrolStyleProps` prop is necessary because it contains the props from the generic + * ControlPanel that are necessary for styling + */ + Component: (conrolStyleProps) => { + const currentSearch = useStateFromPublishingSubject(searchString); + + useEffect(() => { + return () => { + // cleanup on unmount + onSearchStringChanged.unsubscribe(); + onFieldChanged.unsubscribe(); + }; + }, []); + + return ( + { + searchString.next(event.target.value); + }} + placeholder={i18n.translate('controls.searchControl.placeholder', { + defaultMessage: 'Search...', + })} + id={uuid} + fullWidth + /> + ); + }, + }; + }, + }; +}; diff --git a/examples/controls_example/public/react_controls/data_controls/search_control/types.tsx b/examples/controls_example/public/react_controls/data_controls/search_control/types.tsx new file mode 100644 index 0000000000000..d0b2d43b69f48 --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/search_control/types.tsx @@ -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 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 { DataControlApi, DefaultDataControlState } from '../types'; + +export const SEARCH_CONTROL_TYPE = 'searchControl'; + +export type SearchControlTechniques = 'match' | 'simple_query_string'; + +export interface SearchControlState extends DefaultDataControlState { + searchString?: string; + searchTechnique?: SearchControlTechniques; +} + +export type SearchControlApi = DataControlApi; diff --git a/examples/controls_example/public/react_controls/data_controls/types.ts b/examples/controls_example/public/react_controls/data_controls/types.ts new file mode 100644 index 0000000000000..a72c6c5db1c52 --- /dev/null +++ b/examples/controls_example/public/react_controls/data_controls/types.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 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 { CanClearSelections } from '@kbn/controls-plugin/public'; +import { DataViewField } from '@kbn/data-views-plugin/common'; +import { Filter } from '@kbn/es-query'; +import { + HasEditCapabilities, + PublishesDataViews, + PublishesFilters, + PublishesPanelTitle, +} from '@kbn/presentation-publishing'; +import { + ControlFactory, + ControlStateManager, + DefaultControlApi, + DefaultControlState, +} from '../types'; + +export type DataControlApi = DefaultControlApi & + Omit & // control titles cannot be hidden + HasEditCapabilities & + CanClearSelections & + PublishesDataViews & + PublishesFilters & { + setOutputFilter: (filter: Filter | undefined) => void; // a control should only ever output a **single** filter + }; + +export interface DataControlFactory< + State extends DefaultDataControlState = DefaultDataControlState, + Api extends DataControlApi = DataControlApi +> extends ControlFactory { + isFieldCompatible: (field: DataViewField) => boolean; + CustomOptionsComponent?: React.FC<{ + stateManager: ControlStateManager; + setControlEditorValid: (valid: boolean) => void; + }>; +} + +export const isDataControlFactory = ( + factory: ControlFactory +): factory is DataControlFactory => { + return typeof (factory as DataControlFactory).isFieldCompatible === 'function'; +}; + +export interface DefaultDataControlState extends DefaultControlState { + dataViewId: string; + fieldName: string; + title?: string; // custom control label +} diff --git a/examples/controls_example/public/react_controls/initialize_default_control_api.tsx b/examples/controls_example/public/react_controls/initialize_default_control_api.tsx new file mode 100644 index 0000000000000..dd2afcaf45d6c --- /dev/null +++ b/examples/controls_example/public/react_controls/initialize_default_control_api.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 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 { BehaviorSubject } from 'rxjs'; + +import { ControlWidth } from '@kbn/controls-plugin/common'; +import { SerializedPanelState } from '@kbn/presentation-containers'; +import { StateComparators } from '@kbn/presentation-publishing'; + +import { + ControlApiInitialization, + ControlStateManager, + DefaultControlApi, + DefaultControlState, +} from './types'; + +export type ControlApi = ControlApiInitialization; + +export const initializeDefaultControlApi = ( + state: DefaultControlState +): { + defaultControlApi: ControlApi; + defaultControlStateManager: ControlStateManager; + defaultControlComparators: StateComparators; + serializeDefaultControl: () => SerializedPanelState; +} => { + const dataLoading = new BehaviorSubject(false); + const blockingError = new BehaviorSubject(undefined); + const grow = new BehaviorSubject(state.grow); + const width = new BehaviorSubject(state.width); + + const defaultControlApi: ControlApi = { + grow, + width, + dataLoading, + blockingError, + setBlockingError: (error) => blockingError.next(error), + setDataLoading: (loading) => dataLoading.next(loading), + }; + + const defaultControlStateManager: ControlStateManager = { + grow, + width, + }; + + const defaultControlComparators: StateComparators = { + grow: [grow, (newGrow: boolean | undefined) => grow.next(newGrow)], + width: [width, (newWidth: ControlWidth | undefined) => width.next(newWidth)], + }; + + return { + defaultControlApi, + defaultControlComparators, + defaultControlStateManager, + serializeDefaultControl: () => { + return { rawState: { grow: grow.getValue(), width: width.getValue() }, references: [] }; + }, + }; +}; diff --git a/examples/controls_example/public/react_controls/types.ts b/examples/controls_example/public/react_controls/types.ts new file mode 100644 index 0000000000000..7bb25ff9821bb --- /dev/null +++ b/examples/controls_example/public/react_controls/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 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 { BehaviorSubject } from 'rxjs'; + +import { SerializedStyles } from '@emotion/react'; +import { ControlWidth } from '@kbn/controls-plugin/public/types'; +import { HasSerializableState } from '@kbn/presentation-containers'; +import { PanelCompatibleComponent } from '@kbn/presentation-panel-plugin/public/panel_component/types'; +import { + HasParentApi, + HasType, + HasUniqueId, + PublishesBlockingError, + PublishesDataLoading, + PublishesDisabledActionIds, + PublishesPanelTitle, + PublishesUnsavedChanges, + PublishingSubject, + StateComparators, +} from '@kbn/presentation-publishing'; + +import { ControlGroupApi } from './control_group/types'; + +export interface PublishesControlDisplaySettings { + grow: PublishingSubject; + width: PublishingSubject; +} + +export interface HasCustomPrepend { + getCustomPrepend: () => React.FC<{}>; +} + +export type DefaultControlApi = PublishesDataLoading & + PublishesBlockingError & + PublishesUnsavedChanges & + PublishesControlDisplaySettings & + Partial & + HasType & + HasUniqueId & + HasSerializableState & + HasParentApi & { + setDataLoading: (loading: boolean) => void; + setBlockingError: (error: Error | undefined) => void; + }; + +export interface DefaultControlState { + grow?: boolean; + width?: ControlWidth; +} + +export type ControlApiRegistration = Omit< + ControlApi, + 'uuid' | 'parentApi' | 'type' | 'unsavedChanges' | 'resetUnsavedChanges' +>; + +export type ControlApiInitialization = + Omit< + ControlApiRegistration, + 'serializeState' | 'getTypeDisplayName' | 'clearSelections' + >; + +// TODO: Move this to the Control plugin's setup contract +export interface ControlFactory< + State extends DefaultControlState = DefaultControlState, + ControlApi extends DefaultControlApi = DefaultControlApi +> { + type: string; + getIconType: () => string; + getDisplayName: () => string; + buildControl: ( + initialState: State, + buildApi: ( + apiRegistration: ControlApiRegistration, + comparators: StateComparators + ) => ControlApi, + uuid: string, + parentApi: ControlGroupApi + ) => { api: ControlApi; Component: React.FC<{}> }; +} + +export type ControlStateManager = { + [key in keyof Required]: BehaviorSubject; +}; + +export interface ControlPanelProps< + ApiType extends DefaultControlApi = DefaultControlApi, + PropsType extends {} = { css: SerializedStyles } +> { + Component: PanelCompatibleComponent; +} diff --git a/examples/controls_example/tsconfig.json b/examples/controls_example/tsconfig.json index 508a61e7020e0..834ef6cebe553 100644 --- a/examples/controls_example/tsconfig.json +++ b/examples/controls_example/tsconfig.json @@ -18,9 +18,21 @@ "@kbn/data-plugin", "@kbn/controls-plugin", "@kbn/navigation-plugin", - "@kbn/shared-ux-page-kibana-template", "@kbn/embeddable-plugin", "@kbn/data-views-plugin", "@kbn/es-query", + "@kbn/presentation-containers", + "@kbn/presentation-publishing", + "@kbn/ui-actions-plugin", + "@kbn/i18n-react", + "@kbn/shared-ux-markdown", + "@kbn/i18n", + "@kbn/core-mount-utils-browser", + "@kbn/react-kibana-mount", + "@kbn/content-management-utils", + "@kbn/presentation-util-plugin", + "@kbn/ui-theme", + "@kbn/core-lifecycle-browser", + "@kbn/presentation-panel-plugin", ] } diff --git a/packages/presentation/presentation_containers/index.ts b/packages/presentation/presentation_containers/index.ts index 0c55ae715eb98..06c1d7c04ee9c 100644 --- a/packages/presentation/presentation_containers/index.ts +++ b/packages/presentation/presentation_containers/index.ts @@ -27,6 +27,7 @@ export { apiIsPresentationContainer, getContainerParentFromAPI, listenForCompatibleApi, + combineCompatibleChildrenApis, type PanelPackage, type PresentationContainer, } from './interfaces/presentation_container'; diff --git a/packages/presentation/presentation_containers/interfaces/presentation_container.ts b/packages/presentation/presentation_containers/interfaces/presentation_container.ts index be39c1a5c8be3..d201a0d346132 100644 --- a/packages/presentation/presentation_containers/interfaces/presentation_container.ts +++ b/packages/presentation/presentation_containers/interfaces/presentation_container.ts @@ -6,23 +6,16 @@ * Side Public License, v 1. */ -import { - apiHasParentApi, - apiHasUniqueId, - PublishesViewMode, - PublishingSubject, -} from '@kbn/presentation-publishing'; +import { apiHasParentApi, apiHasUniqueId, PublishingSubject } from '@kbn/presentation-publishing'; +import { BehaviorSubject, combineLatest, isObservable, map, Observable, of, switchMap } from 'rxjs'; import { apiCanAddNewPanel, CanAddNewPanel } from './can_add_new_panel'; -import { PublishesSettings } from './publishes_settings'; export interface PanelPackage { panelType: string; initialState?: SerializedState; } -export interface PresentationContainer - extends Partial, - CanAddNewPanel { +export interface PresentationContainer extends CanAddNewPanel { /** * Removes a panel from the container. */ @@ -101,3 +94,34 @@ export const listenForCompatibleApi = ( lastCleanupFunction?.(); }; }; + +export const combineCompatibleChildrenApis = ( + api: unknown, + observableKey: keyof ApiType, + isCompatible: (api: unknown) => api is ApiType, + emptyState: PublishingSubjectType, + flattenMethod?: (array: PublishingSubjectType[]) => PublishingSubjectType +): Observable => { + if (!api || !apiIsPresentationContainer(api)) return of(); + + return api.children$.pipe( + switchMap((children) => { + const compatibleChildren: Array> = []; + for (const child of Object.values(children)) { + if (isCompatible(child) && isObservable(child[observableKey])) + compatibleChildren.push(child[observableKey] as BehaviorSubject); + } + + if (compatibleChildren.length === 0) return of(emptyState); + + return combineLatest(compatibleChildren).pipe( + map( + flattenMethod + ? flattenMethod + : (nextCompatible) => + nextCompatible.flat().filter((value) => Boolean(value)) as PublishingSubjectType + ) + ); + }) + ); +}; diff --git a/packages/presentation/presentation_publishing/index.ts b/packages/presentation/presentation_publishing/index.ts index 975f6f3863de1..e3136215f3d40 100644 --- a/packages/presentation/presentation_publishing/index.ts +++ b/packages/presentation/presentation_publishing/index.ts @@ -36,13 +36,16 @@ export { } from './interfaces/fetch/initialize_time_range'; export { apiPublishesPartialUnifiedSearch, + apiPublishesFilters, apiPublishesTimeRange, apiPublishesUnifiedSearch, apiPublishesWritableUnifiedSearch, useSearchApi, type PublishesTimeRange, + type PublishesFilters, type PublishesUnifiedSearch, type PublishesWritableUnifiedSearch, + type PublishesTimeslice, } from './interfaces/fetch/publishes_unified_search'; export { apiHasAppContext, diff --git a/packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts b/packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts index 5f349665fa36b..f426859cc29b3 100644 --- a/packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts +++ b/packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts @@ -6,26 +6,33 @@ * Side Public License, v 1. */ -import { BehaviorSubject } from 'rxjs'; -import { TimeRange, Filter, Query, AggregateQuery } from '@kbn/es-query'; +import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; import { useEffect, useMemo } from 'react'; +import { BehaviorSubject } from 'rxjs'; import { PublishingSubject } from '../../publishing_subject'; -export interface PublishesTimeRange { +export interface PublishesTimeslice { + timeslice$?: PublishingSubject<[number, number] | undefined>; +} + +export interface PublishesTimeRange extends PublishesTimeslice { timeRange$: PublishingSubject; timeRestore$?: PublishingSubject; - timeslice$?: PublishingSubject<[number, number] | undefined>; } export type PublishesWritableTimeRange = PublishesTimeRange & { setTimeRange: (timeRange: TimeRange | undefined) => void; }; -export type PublishesUnifiedSearch = PublishesTimeRange & { - isCompatibleWithUnifiedSearch?: () => boolean; +export interface PublishesFilters { filters$: PublishingSubject; - query$: PublishingSubject; -}; +} + +export type PublishesUnifiedSearch = PublishesTimeRange & + PublishesFilters & { + isCompatibleWithUnifiedSearch?: () => boolean; + query$: PublishingSubject; + }; export type PublishesWritableUnifiedSearch = PublishesUnifiedSearch & PublishesWritableTimeRange & { @@ -39,6 +46,10 @@ export const apiPublishesTimeRange = ( return Boolean(unknownApi && (unknownApi as PublishesTimeRange)?.timeRange$ !== undefined); }; +export const apiPublishesFilters = (unknownApi: unknown): unknownApi is PublishesFilters => { + return Boolean(unknownApi && (unknownApi as PublishesFilters)?.filters$ !== undefined); +}; + export const apiPublishesUnifiedSearch = ( unknownApi: null | unknown ): unknownApi is PublishesUnifiedSearch => { diff --git a/src/plugins/controls/common/index.ts b/src/plugins/controls/common/index.ts index 75b9881b83ea5..69af581fc5fad 100644 --- a/src/plugins/controls/common/index.ts +++ b/src/plugins/controls/common/index.ts @@ -18,6 +18,7 @@ export { type RawControlGroupAttributes, type PersistableControlGroupInput, type SerializableControlGroupInput, + type ControlGroupChainingSystem, persistableControlGroupInputKeys, } from './control_group/types'; export { @@ -32,6 +33,7 @@ export { } from './control_group/control_group_persistence'; export { + DEFAULT_CONTROL_GROW, DEFAULT_CONTROL_WIDTH, DEFAULT_CONTROL_STYLE, } from './control_group/control_group_constants'; diff --git a/src/plugins/controls/public/control_group/actions/clear_control_action.tsx b/src/plugins/controls/public/control_group/actions/clear_control_action.tsx index 794a4efdeb436..5881538128070 100644 --- a/src/plugins/controls/public/control_group/actions/clear_control_action.tsx +++ b/src/plugins/controls/public/control_group/actions/clear_control_action.tsx @@ -9,30 +9,55 @@ import React, { SyntheticEvent } from 'react'; import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; -import { isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; +import { apiIsPresentationContainer, PresentationContainer } from '@kbn/presentation-containers'; +import { + apiCanAccessViewMode, + apiHasParentApi, + apiHasType, + apiHasUniqueId, + apiIsOfType, + EmbeddableApiContext, + HasParentApi, + HasType, + HasUniqueId, +} from '@kbn/presentation-publishing'; import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { ACTION_CLEAR_CONTROL } from '.'; +import { CanClearSelections, isClearableControl } from '../../types'; import { ControlGroupStrings } from '../control_group_strings'; -import { ControlEmbeddable, DataControlInput, isClearableControl } from '../../types'; -import { isControlGroup } from '../embeddable/control_group_helpers'; +import { CONTROL_GROUP_TYPE } from '../types'; -export interface ClearControlActionContext { - embeddable: ControlEmbeddable; -} +export type ClearControlActionApi = HasType & + HasUniqueId & + CanClearSelections & + HasParentApi; + +const isApiCompatible = (api: unknown | null): api is ClearControlActionApi => + Boolean( + apiHasType(api) && + apiHasUniqueId(api) && + isClearableControl(api) && + apiHasParentApi(api) && + apiCanAccessViewMode(api.parentApi) && + apiIsOfType(api.parentApi, CONTROL_GROUP_TYPE) && + apiIsPresentationContainer(api.parentApi) + ); -export class ClearControlAction implements Action { +export class ClearControlAction implements Action { public readonly type = ACTION_CLEAR_CONTROL; public readonly id = ACTION_CLEAR_CONTROL; public order = 1; constructor() {} - public readonly MenuItem = ({ context }: { context: ClearControlActionContext }) => { + public readonly MenuItem = ({ context }: { context: EmbeddableApiContext }) => { + if (!isApiCompatible(context.embeddable)) throw new IncompatibleActionError(); + return ( ) => { @@ -45,34 +70,22 @@ export class ClearControlAction implements Action { ); }; - public getDisplayName({ embeddable }: ClearControlActionContext) { - if (!embeddable.parent || !isControlGroup(embeddable.parent)) { - throw new IncompatibleActionError(); - } + public getDisplayName({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); return ControlGroupStrings.floatingActions.getClearButtonTitle(); } - public getIconType({ embeddable }: ClearControlActionContext) { - if (!embeddable.parent || !isControlGroup(embeddable.parent)) { - throw new IncompatibleActionError(); - } + public getIconType({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); return 'eraser'; } - public async isCompatible({ embeddable }: ClearControlActionContext) { - if (isErrorEmbeddable(embeddable)) return false; - const controlGroup = embeddable.parent; - return Boolean(controlGroup && isControlGroup(controlGroup)) && isClearableControl(embeddable); + public async isCompatible({ embeddable }: EmbeddableApiContext) { + return isApiCompatible(embeddable); } - public async execute({ embeddable }: ClearControlActionContext) { - if ( - !embeddable.parent || - !isControlGroup(embeddable.parent) || - !isClearableControl(embeddable) - ) { - throw new IncompatibleActionError(); - } + public async execute({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); embeddable.clearSelections(); } } diff --git a/src/plugins/controls/public/control_group/actions/delete_control_action.tsx b/src/plugins/controls/public/control_group/actions/delete_control_action.tsx index a519763132a23..1627eab8560c2 100644 --- a/src/plugins/controls/public/control_group/actions/delete_control_action.tsx +++ b/src/plugins/controls/public/control_group/actions/delete_control_action.tsx @@ -9,20 +9,43 @@ import React from 'react'; import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; -import { ViewMode, isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; +import { apiIsPresentationContainer, PresentationContainer } from '@kbn/presentation-containers'; +import { + apiCanAccessViewMode, + apiHasParentApi, + apiHasType, + apiHasUniqueId, + apiIsOfType, + EmbeddableApiContext, + getInheritedViewMode, + HasParentApi, + HasType, + HasUniqueId, + PublishesViewMode, +} from '@kbn/presentation-publishing'; import { ACTION_DELETE_CONTROL } from '.'; import { pluginServices } from '../../services'; import { ControlGroupStrings } from '../control_group_strings'; -import { ControlEmbeddable, DataControlInput } from '../../types'; -import { isControlGroup } from '../embeddable/control_group_helpers'; +import { CONTROL_GROUP_TYPE } from '../types'; -export interface DeleteControlActionContext { - embeddable: ControlEmbeddable; -} +export type DeleteControlActionApi = HasType & + HasUniqueId & + HasParentApi; + +const isApiCompatible = (api: unknown | null): api is DeleteControlActionApi => + Boolean( + apiHasType(api) && + apiHasUniqueId(api) && + apiHasParentApi(api) && + apiCanAccessViewMode(api.parentApi) && + apiIsOfType(api.parentApi, CONTROL_GROUP_TYPE) && + apiIsPresentationContainer(api.parentApi) + ); -export class DeleteControlAction implements Action { +export class DeleteControlAction implements Action { public readonly type = ACTION_DELETE_CONTROL; public readonly id = ACTION_DELETE_CONTROL; public order = 100; // should always be last @@ -35,11 +58,13 @@ export class DeleteControlAction implements Action { } = pluginServices.getServices()); } - public readonly MenuItem = ({ context }: { context: DeleteControlActionContext }) => { + public readonly MenuItem = ({ context }: { context: EmbeddableApiContext }) => { + if (!isApiCompatible(context.embeddable)) throw new IncompatibleActionError(); + return ( this.execute(context)} @@ -49,34 +74,25 @@ export class DeleteControlAction implements Action { ); }; - public getDisplayName({ embeddable }: DeleteControlActionContext) { - if (!embeddable.parent || !isControlGroup(embeddable.parent)) { - throw new IncompatibleActionError(); - } + public getDisplayName({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); return ControlGroupStrings.floatingActions.getRemoveButtonTitle(); } - public getIconType({ embeddable }: DeleteControlActionContext) { - if (!embeddable.parent || !isControlGroup(embeddable.parent)) { - throw new IncompatibleActionError(); - } + public getIconType({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); return 'trash'; } - public async isCompatible({ embeddable }: DeleteControlActionContext) { - if (isErrorEmbeddable(embeddable)) return false; - const controlGroup = embeddable.parent; - return Boolean( - controlGroup && - isControlGroup(controlGroup) && - controlGroup.getInput().viewMode === ViewMode.EDIT + public async isCompatible({ embeddable }: EmbeddableApiContext) { + return ( + isApiCompatible(embeddable) && getInheritedViewMode(embeddable.parentApi) === ViewMode.EDIT ); } - public async execute({ embeddable }: DeleteControlActionContext) { - if (!embeddable.parent || !isControlGroup(embeddable.parent)) { - throw new IncompatibleActionError(); - } + public async execute({ embeddable }: EmbeddableApiContext) { + if (!isApiCompatible(embeddable)) throw new IncompatibleActionError(); + this.openConfirm(ControlGroupStrings.management.deleteControls.getSubtitle(), { confirmButtonText: ControlGroupStrings.management.deleteControls.getConfirm(), cancelButtonText: ControlGroupStrings.management.deleteControls.getCancel(), @@ -84,7 +100,7 @@ export class DeleteControlAction implements Action { buttonColor: 'danger', }).then((confirmed) => { if (confirmed) { - embeddable.parent?.removeEmbeddable(embeddable.id); + embeddable.parentApi.removePanel(embeddable.uuid); } }); } diff --git a/src/plugins/controls/public/control_group/component/control_frame_component.tsx b/src/plugins/controls/public/control_group/component/control_frame_component.tsx index 771f6d7d9c596..e4c647737f48c 100644 --- a/src/plugins/controls/public/control_group/component/control_frame_component.tsx +++ b/src/plugins/controls/public/control_group/component/control_frame_component.tsx @@ -129,7 +129,7 @@ export const ControlFrame = ({ 'controlFrameFloatingActions--oneLine': !usingTwoLineLayout, })} viewMode={viewMode} - embeddable={embeddable} + api={embeddable} disabledActions={disabledActions} isEnabled={embeddable && enableActions} > diff --git a/src/plugins/controls/public/control_group/editor/control_editor.tsx b/src/plugins/controls/public/control_group/editor/control_editor.tsx index 5f39f3c6a16ec..118b310b49574 100644 --- a/src/plugins/controls/public/control_group/editor/control_editor.tsx +++ b/src/plugins/controls/public/control_group/editor/control_editor.tsx @@ -6,14 +6,6 @@ * Side Public License, v 1. */ -/* - * 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 deepEqual from 'fast-deep-equal'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import useAsync from 'react-use/lib/useAsync'; diff --git a/src/plugins/controls/public/control_group/embeddable/control_group_container.tsx b/src/plugins/controls/public/control_group/embeddable/control_group_container.tsx index 7a0509429f059..70c57f6f73cfc 100644 --- a/src/plugins/controls/public/control_group/embeddable/control_group_container.tsx +++ b/src/plugins/controls/public/control_group/embeddable/control_group_container.tsx @@ -11,8 +11,15 @@ import { isEqual, pick } from 'lodash'; import React, { createContext, useContext } from 'react'; import ReactDOM from 'react-dom'; import { batch, Provider, TypedUseSelectorHook, useSelector } from 'react-redux'; -import { BehaviorSubject, merge, Subject, Subscription } from 'rxjs'; -import { debounceTime, distinctUntilChanged, skip } from 'rxjs'; +import { + BehaviorSubject, + debounceTime, + distinctUntilChanged, + merge, + skip, + Subject, + Subscription, +} from 'rxjs'; import { OverlayRef } from '@kbn/core/public'; import { Container, EmbeddableFactory } from '@kbn/embeddable-plugin/public'; @@ -479,6 +486,11 @@ export class ControlGroupContainer extends Container< }; } + public removePanel(id: string): void { + /** TODO: This is a temporary wrapper until the control group refactor is complete */ + super.removeEmbeddable(id); + } + protected onRemoveEmbeddable(idToRemove: string) { const newPanels = super.onRemoveEmbeddable(idToRemove) as ControlsPanels; const childOrderCache = cachedChildEmbeddableOrder(this.getInput().panels); diff --git a/src/plugins/controls/public/index.ts b/src/plugins/controls/public/index.ts index 555b9d4284e89..a9d7e950ee05b 100644 --- a/src/plugins/controls/public/index.ts +++ b/src/plugins/controls/public/index.ts @@ -15,6 +15,7 @@ export type { ControlEditorProps, CommonControlOutput, IEditableControlFactory, + CanClearSelections, } from './types'; export type { @@ -65,6 +66,9 @@ export { type ControlGroupRendererProps, } from './control_group'; +/** TODO: Remove this once it is no longer needed in the examples plugin */ +export { CONTROL_WIDTH_OPTIONS } from './control_group/editor/editor_constants'; + export function plugin() { return new ControlsPlugin(); } diff --git a/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx b/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx index 31ac406a83207..81dd3ea9c64c9 100644 --- a/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx +++ b/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx @@ -11,8 +11,17 @@ import { isEmpty, isEqual } from 'lodash'; import React, { createContext, useContext } from 'react'; import ReactDOM from 'react-dom'; import { batch } from 'react-redux'; -import { merge, Subject, Subscription, switchMap, tap } from 'rxjs'; -import { debounceTime, distinctUntilChanged, map, skip } from 'rxjs'; +import { + debounceTime, + distinctUntilChanged, + map, + merge, + skip, + Subject, + Subscription, + switchMap, + tap, +} from 'rxjs'; import { DataView, FieldSpec } from '@kbn/data-views-plugin/public'; import { Embeddable, IContainer } from '@kbn/embeddable-plugin/public'; @@ -39,7 +48,7 @@ import { ControlFilterOutput } from '../../control_group/types'; import { pluginServices } from '../../services'; import { ControlsDataViewsService } from '../../services/data_views/types'; import { ControlsOptionsListService } from '../../services/options_list/types'; -import { IClearableControl } from '../../types'; +import { CanClearSelections } from '../../types'; import { OptionsListControl } from '../components/options_list_control'; import { getDefaultComponentState, optionsListReducers } from '../options_list_reducers'; import { MIN_OPTIONS_LIST_REQUEST_SIZE, OptionsListReduxState } from '../types'; @@ -81,7 +90,7 @@ type OptionsListReduxEmbeddableTools = ReduxEmbeddableTools< export class OptionsListEmbeddable extends Embeddable - implements IClearableControl + implements CanClearSelections { public readonly type = OPTIONS_LIST_CONTROL; public deferEmbeddableLoad = true; diff --git a/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx b/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx index 52e048fbb0898..2f77f8163ca3e 100644 --- a/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx +++ b/src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx @@ -38,7 +38,7 @@ import { ControlFilterOutput } from '../../control_group/types'; import { pluginServices } from '../../services'; import { ControlsDataService } from '../../services/data/types'; import { ControlsDataViewsService } from '../../services/data_views/types'; -import { IClearableControl } from '../../types'; +import { CanClearSelections } from '../../types'; import { RangeSliderControl } from '../components/range_slider_control'; import { getDefaultComponentState, rangeSliderReducers } from '../range_slider_reducers'; import { RangeSliderReduxState } from '../types'; @@ -79,7 +79,7 @@ type RangeSliderReduxEmbeddableTools = ReduxEmbeddableTools< export class RangeSliderEmbeddable extends Embeddable - implements IClearableControl + implements CanClearSelections { public readonly type = RANGE_SLIDER_CONTROL; public deferEmbeddableLoad = true; diff --git a/src/plugins/controls/public/time_slider/embeddable/time_slider_embeddable.tsx b/src/plugins/controls/public/time_slider/embeddable/time_slider_embeddable.tsx index f29611fedaeed..1639d3145ed01 100644 --- a/src/plugins/controls/public/time_slider/embeddable/time_slider_embeddable.tsx +++ b/src/plugins/controls/public/time_slider/embeddable/time_slider_embeddable.tsx @@ -26,7 +26,7 @@ import { ControlTimesliceOutput } from '../../control_group/types'; import { pluginServices } from '../../services'; import { ControlsDataService } from '../../services/data/types'; import { ControlsSettingsService } from '../../services/settings/types'; -import { ControlOutput, IClearableControl } from '../../types'; +import { CanClearSelections, ControlOutput } from '../../types'; import { TimeSlider, TimeSliderPrepend } from '../components'; import { timeSliderReducers } from '../time_slider_reducers'; import { getIsAnchored, getRoundedTimeRangeBounds } from '../time_slider_selectors'; @@ -57,7 +57,7 @@ type TimeSliderReduxEmbeddableTools = ReduxEmbeddableTools< export class TimeSliderControlEmbeddable extends Embeddable - implements IClearableControl + implements CanClearSelections { public readonly type = TIME_SLIDER_CONTROL; public deferEmbeddedLoad = true; diff --git a/src/plugins/controls/public/types.ts b/src/plugins/controls/public/types.ts index bb1bbf87b62e4..cf9c1a871558c 100644 --- a/src/plugins/controls/public/types.ts +++ b/src/plugins/controls/public/types.ts @@ -36,25 +36,23 @@ export type ControlFactory = EmbeddableFa ControlEmbeddable >; -export type ControlEmbeddable< +export interface ControlEmbeddable< TControlEmbeddableInput extends ControlInput = ControlInput, TControlEmbeddableOutput extends ControlOutput = ControlOutput -> = IEmbeddable & { +> extends IEmbeddable { isChained?: () => boolean; renderPrepend?: () => ReactNode | undefined; selectionsToFilters?: ( input: Partial ) => Promise; -}; +} -export interface IClearableControl< - TClearableControlEmbeddableInput extends ControlInput = ControlInput -> extends ControlEmbeddable { +export interface CanClearSelections { clearSelections: () => void; } -export const isClearableControl = (control: ControlEmbeddable): control is IClearableControl => { - return Boolean((control as IClearableControl).clearSelections); +export const isClearableControl = (control: unknown): control is CanClearSelections => { + return typeof (control as CanClearSelections).clearSelections === 'function'; }; /** diff --git a/src/plugins/controls/tsconfig.json b/src/plugins/controls/tsconfig.json index db72c59aee737..3a97d130e2902 100644 --- a/src/plugins/controls/tsconfig.json +++ b/src/plugins/controls/tsconfig.json @@ -39,6 +39,8 @@ "@kbn/react-kibana-mount", "@kbn/shared-ux-markdown", "@kbn/react-kibana-context-render", + "@kbn/presentation-containers", + "@kbn/presentation-publishing", ], "exclude": [ "target/**/*", diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts index 1f489fdc1a92c..675ea42634506 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts @@ -9,10 +9,11 @@ import { ControlGroupInput } from '@kbn/controls-plugin/common'; import { ControlGroupContainer } from '@kbn/controls-plugin/public'; import { compareFilters, COMPARE_ALL_OPTIONS, type Filter } from '@kbn/es-query'; -import { apiPublishesDataLoading, PublishingSubject } from '@kbn/presentation-publishing'; +import { combineCompatibleChildrenApis } from '@kbn/presentation-containers'; +import { apiPublishesDataLoading, PublishesDataLoading } from '@kbn/presentation-publishing'; import deepEqual from 'fast-deep-equal'; import { isEqual } from 'lodash'; -import { combineLatest, distinctUntilChanged, map, Observable, skip, switchMap } from 'rxjs'; +import { distinctUntilChanged, Observable, skip } from 'rxjs'; import { DashboardContainerInput } from '../../../../../common'; import { DashboardContainer } from '../../dashboard_container'; @@ -96,20 +97,14 @@ export function startSyncingDashboardControlGroup(this: DashboardContainer) { // the Control Group needs to know when any dashboard children are loading in order to know when to move on to the next time slice when playing. this.integrationSubscriptions.add( - this.children$ - .pipe( - switchMap((children) => { - const definedDataLoadingSubjects: Array> = []; - for (const child of Object.values(children)) { - if (apiPublishesDataLoading(child)) { - definedDataLoadingSubjects.push(child.dataLoading); - } - } - return combineLatest(definedDataLoadingSubjects).pipe( - map((values) => values.some(Boolean)) - ); - }) - ) + combineCompatibleChildrenApis( + this, + 'dataLoading', + apiPublishesDataLoading, + false, + (childrenLoading) => childrenLoading.some(Boolean) + ) + .pipe(skip(1)) // skip the initial output of "false" .subscribe((anyChildLoading) => this.controlGroup?.anyControlOutputConsumerLoading$.next(anyChildLoading) ) diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts index 92680d3aa10d4..3fd4c0df233cf 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts @@ -7,6 +7,7 @@ */ import { DataView } from '@kbn/data-views-plugin/common'; +import { combineCompatibleChildrenApis } from '@kbn/presentation-containers'; import { apiPublishesDataViews, PublishesDataViews } from '@kbn/presentation-publishing'; import { uniqBy } from 'lodash'; import { combineLatest, map, Observable, of, switchMap } from 'rxjs'; @@ -32,18 +33,11 @@ export function startSyncingDashboardDataViews(this: DashboardContainer) { ) : of([]); - const childDataViewsPipe: Observable = this.children$.pipe( - switchMap((children) => { - const childrenThatPublishDataViews: PublishesDataViews[] = []; - for (const child of Object.values(children)) { - if (apiPublishesDataViews(child)) childrenThatPublishDataViews.push(child); - } - if (childrenThatPublishDataViews.length === 0) return of([]); - return combineLatest(childrenThatPublishDataViews.map((child) => child.dataViews)); - }), - map( - (nextDataViews) => nextDataViews.flat().filter((dataView) => Boolean(dataView)) as DataView[] - ) + const childDataViewsPipe = combineCompatibleChildrenApis( + this, + 'dataViews', + apiPublishesDataViews, + [] ); return combineLatest([controlGroupDataViewsPipe, childDataViewsPipe]) diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx index a0190b3baee04..bb49255d41711 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx @@ -15,6 +15,7 @@ import { apiPublishesPanelTitle, apiPublishesUnsavedChanges, getPanelTitle, + PublishesViewMode, } from '@kbn/presentation-publishing'; import { RefreshInterval } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; @@ -52,6 +53,7 @@ import { batch } from 'react-redux'; import { BehaviorSubject, Subject, Subscription } from 'rxjs'; import { distinctUntilChanged, map } from 'rxjs'; import { v4 } from 'uuid'; +import { PublishesSettings } from '@kbn/presentation-containers/interfaces/publishes_settings'; import { apiHasSerializableState } from '@kbn/presentation-containers/interfaces/serialized_state'; import { DashboardLocatorParams, DASHBOARD_CONTAINER_TYPE } from '../..'; import { DashboardContainerInput, DashboardPanelState } from '../../../common'; @@ -129,7 +131,9 @@ export class DashboardContainer TracksQueryPerformance, HasSaveNotification, HasRuntimeChildState, - HasSerializedChildState + HasSerializedChildState, + PublishesSettings, + Partial { public readonly type = DASHBOARD_CONTAINER_TYPE; diff --git a/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.test.tsx b/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.test.tsx index e8ba94e61a125..3b6c8cddaa085 100644 --- a/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.test.tsx +++ b/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.test.tsx @@ -93,7 +93,8 @@ describe('react embeddable renderer', () => { { bork: 'blorp?' }, expect.any(Function), expect.any(String), - expect.any(Object) + expect.any(Object), + expect.any(Function) ); }); }); @@ -118,7 +119,8 @@ describe('react embeddable renderer', () => { { bork: 'blorp?' }, expect.any(Function), '12345', - expect.any(Object) + expect.any(Object), + expect.any(Function) ); }); }); @@ -139,7 +141,8 @@ describe('react embeddable renderer', () => { { bork: 'blorp?' }, expect.any(Function), expect.any(String), - parentApi + parentApi, + expect.any(Function) ); }); }); diff --git a/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx b/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx index 509e5a758866d..a10420a33f67f 100644 --- a/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx +++ b/src/plugins/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx @@ -19,7 +19,11 @@ import { BehaviorSubject, combineLatest, debounceTime, skip, Subscription, switc import { v4 as generateId } from 'uuid'; import { getReactEmbeddableFactory } from './react_embeddable_registry'; import { initializeReactEmbeddableState } from './react_embeddable_state'; -import { DefaultEmbeddableApi, ReactEmbeddableApiRegistration } from './types'; +import { + DefaultEmbeddableApi, + SetReactEmbeddableApiRegistration, + BuildReactEmbeddableApiRegistration, +} from './types'; const ON_STATE_CHANGE_DEBOUNCE = 100; @@ -96,8 +100,22 @@ export const ReactEmbeddableRenderer = < RuntimeState >(uuid, factory, parentApi); + const setApi = ( + apiRegistration: SetReactEmbeddableApiRegistration + ) => { + const fullApi = { + ...apiRegistration, + uuid, + phase$, + parentApi, + type: factory.type, + } as unknown as Api; + onApiAvailable?.(fullApi); + return fullApi; + }; + const buildApi = ( - apiRegistration: ReactEmbeddableApiRegistration, + apiRegistration: BuildReactEmbeddableApiRegistration, comparators: StateComparators ) => { if (onAnyStateChange) { @@ -131,21 +149,15 @@ export const ReactEmbeddableRenderer = < const { unsavedChanges, resetUnsavedChanges, cleanup, snapshotRuntimeState } = startStateDiffing(comparators); - const fullApi = { + + const fullApi = setApi({ ...apiRegistration, - uuid, - phase$, - parentApi, unsavedChanges, - type: factory.type, resetUnsavedChanges, snapshotRuntimeState, - } as unknown as Api; - cleanupFunction.current = () => { - subscriptions.unsubscribe(); - cleanup(); - }; - onApiAvailable?.(fullApi); + } as unknown as SetReactEmbeddableApiRegistration); + + cleanupFunction.current = () => cleanup(); return fullApi; }; @@ -153,7 +165,8 @@ export const ReactEmbeddableRenderer = < initialState, buildApi, uuid, - parentApi + parentApi, + setApi ); if (apiPublishesDataLoading(api)) { diff --git a/src/plugins/embeddable/public/react_embeddable_system/types.ts b/src/plugins/embeddable/public/react_embeddable_system/types.ts index 64514ac854b52..8a05698934e9c 100644 --- a/src/plugins/embeddable/public/react_embeddable_system/types.ts +++ b/src/plugins/embeddable/public/react_embeddable_system/types.ts @@ -36,21 +36,24 @@ export interface DefaultEmbeddableApi< HasSnapshottableState {} /** - * A subset of the default embeddable API used in registration to allow implementors to omit aspects - * of the API that will be automatically added by the system. + * Defines the subset of the default embeddable API that the `setApi` method uses, which allows implementors + * to omit aspects of the API that will be automatically added by `setApi`. */ -export type ReactEmbeddableApiRegistration< +export type SetReactEmbeddableApiRegistration< + SerializedState extends object = object, + Api extends DefaultEmbeddableApi = DefaultEmbeddableApi +> = Omit; + +/** + * Defines the subset of the default embeddable API that the `buildApi` method uses, which allows implementors + * to omit aspects of the API that will be automatically added by `buildApi`. + */ +export type BuildReactEmbeddableApiRegistration< SerializedState extends object = object, Api extends DefaultEmbeddableApi = DefaultEmbeddableApi > = Omit< - Api, - | 'uuid' - | 'parent' - | 'type' - | 'unsavedChanges' - | 'resetUnsavedChanges' - | 'snapshotRuntimeState' - | 'phase$' + SetReactEmbeddableApiRegistration, + 'unsavedChanges' | 'resetUnsavedChanges' | 'snapshotRuntimeState' >; /** @@ -93,11 +96,17 @@ export interface ReactEmbeddableFactory< */ buildEmbeddable: ( initialState: RuntimeState, + /** + * `buildApi` should be used by most embeddables that are used in dashboards, since it implements the unsaved + * changes logic that the dashboard expects using the provided comparators + */ buildApi: ( - apiRegistration: ReactEmbeddableApiRegistration, + apiRegistration: BuildReactEmbeddableApiRegistration, comparators: StateComparators ) => Api, uuid: string, - parentApi?: unknown + parentApi: unknown | undefined, + /** `setApi` should be used when the unsaved changes logic in `buildApi` is unnecessary */ + setApi: (api: SetReactEmbeddableApiRegistration) => Api ) => Promise<{ Component: React.FC<{}>; api: Api }>; } diff --git a/src/plugins/presentation_util/public/components/floating_actions/floating_actions.tsx b/src/plugins/presentation_util/public/components/floating_actions/floating_actions.tsx index 7cb462a5f1de7..7416c8e9eee21 100644 --- a/src/plugins/presentation_util/public/components/floating_actions/floating_actions.tsx +++ b/src/plugins/presentation_util/public/components/floating_actions/floating_actions.tsx @@ -7,14 +7,15 @@ */ import classNames from 'classnames'; import React, { FC, ReactElement, useEffect, useState } from 'react'; +import { v4 } from 'uuid'; import { panelHoverTrigger, PANEL_HOVER_TRIGGER, type EmbeddableInput, - type IEmbeddable, type ViewMode, } from '@kbn/embeddable-plugin/public'; +import { apiHasUniqueId } from '@kbn/presentation-publishing'; import { Action } from '@kbn/ui-actions-plugin/public'; import { pluginServices } from '../../services'; @@ -25,7 +26,7 @@ export interface FloatingActionsProps { className?: string; isEnabled?: boolean; - embeddable?: IEmbeddable; + api?: unknown; viewMode?: ViewMode; disabledActions?: EmbeddableInput['disabledActions']; } @@ -34,7 +35,7 @@ export const FloatingActions: FC = ({ children, viewMode, isEnabled, - embeddable, + api, className = '', disabledActions, }) => { @@ -44,12 +45,12 @@ export const FloatingActions: FC = ({ const [floatingActions, setFloatingActions] = useState(undefined); useEffect(() => { - if (!embeddable) return; + if (!api) return; const getActions = async () => { let mounted = true; const context = { - embeddable, + embeddable: api, trigger: panelHoverTrigger, }; const actions = (await getTriggerCompatibleActions(PANEL_HOVER_TRIGGER, context)) @@ -79,14 +80,16 @@ export const FloatingActions: FC = ({ }; getActions(); - }, [embeddable, getTriggerCompatibleActions, viewMode, disabledActions]); + }, [api, getTriggerCompatibleActions, viewMode, disabledActions]); return (
{children} {isEnabled && floatingActions && (
{floatingActions} diff --git a/src/plugins/presentation_util/tsconfig.json b/src/plugins/presentation_util/tsconfig.json index dc386db112c16..dea02739d9db9 100644 --- a/src/plugins/presentation_util/tsconfig.json +++ b/src/plugins/presentation_util/tsconfig.json @@ -35,6 +35,7 @@ "@kbn/code-editor", "@kbn/calculate-width-from-char-count", "@kbn/field-utils", + "@kbn/presentation-publishing", ], "exclude": ["target/**/*"] } From 5e8179f383e7a2f192cf522cdca8ecd170eff6c0 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Wed, 5 Jun 2024 08:52:14 -0600 Subject: [PATCH 003/122] [EEM] Add historical entity tracking (#184178) ## Summary This PR closes https://github.com/elastic/observed-asset-model/issues/61 by adding a second transform to generate a history of the entities into `.entities-observability.history-v1.{definition.id}.{YYYY-MM-DD}` indices. This PR also modifieds the summary transform to use the historical data as it's source. ### Changes - Added a section for `history` to the defintion configure the `interval`, `timestamp`, `intialLookback`, and `settings` for the history transform - Added a section for `summary` to the definition to configure the `settings` for the summary transform - Updates the create route to create and install both the summary and history transforms - Updates the create route to create and install both the summary and history ingest pipeline - Updates the delete route to stop and delete both the summary and history transforms - Updates the delete route to delete both the summary and history ingest pipelines - Updates the reset route to remove all the history and summary indices - Removes `indexPatterns` from the data output for both the summary and history entities - Renames `entity.metirc` to `entity.metrics` - Renames `entity.identity` to `entity.identityFields` - Modifiy `entity.id` to be a `MurmurHash3` of all the values of the `entity.identityFields` - Adds `entity.displayName` which uses `displayNameTemplate` to create the string (was `entity.id`) --- .../kbn-entities-schema/src/schema/common.ts | 3 +- .../kbn-entities-schema/src/schema/entity.ts | 28 ++-- .../src/schema/entity_definition.ts | 30 +++- .../common/constants_entities.ts | 16 +- .../create_and_install_ingest_pipeline.ts | 49 ++++-- .../entities/create_and_install_transform.ts | 34 +++-- .../server/lib/entities/delete_index.ts | 13 +- .../lib/entities/delete_ingest_pipeline.ts | 27 +++- .../errors/entity_security_exception.ts | 7 +- .../helpers/fixtures/entity_definition.ts | 21 ++- .../entities/helpers/generate_index_name.ts | 13 +- .../server/lib/entities/helpers/retry.ts | 5 + .../generate_history_processors.test.ts.snap | 111 ++++++++++++++ .../generate_latest_processors.test.ts.snap | 48 ++++++ .../generate_processors.test.ts.snap | 76 --------- .../generate_history_ingest_pipeline_id.ts} | 6 +- .../generate_history_processors.test.ts | 16 ++ .../generate_history_processors.ts | 144 ++++++++++++++++++ ... => generate_latest_ingest_pipeline_id.ts} | 6 +- ....ts => generate_latest_processors.test.ts} | 7 +- ...ssors.ts => generate_latest_processors.ts} | 33 +--- .../server/lib/entities/start_transform.ts | 16 +- .../lib/entities/stop_and_delete_transform.ts | 56 +++++-- ...> generate_history_transform.test.ts.snap} | 55 +++---- .../generate_latest_transform.test.ts.snap | 142 +++++++++++++++++ .../generate_history_transform.test.ts | 16 ++ .../transform/generate_history_transform.ts | 90 +++++++++++ .../generate_history_transform_id.ts | 13 ++ ...t.ts => generate_latest_transform.test.ts} | 8 +- .../transform/generate_latest_transform.ts | 79 ++++++++++ .../transform/generate_latest_transform_id.ts | 13 ++ .../generate_metadata_aggregations.ts | 35 ++++- .../transform/generate_metric_aggregations.ts | 32 +++- .../entities/transform/generate_transform.ts | 86 ----------- .../server/routes/entities/create.ts | 77 +++++++--- .../server/routes/entities/delete.ts | 20 ++- .../server/routes/entities/reset.ts | 40 +++-- .../server/saved_objects/entity_definition.ts | 1 - .../server/templates/components/entity.ts | 16 +- .../server/templates/entities_template.ts | 7 +- 40 files changed, 1121 insertions(+), 374 deletions(-) create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap delete mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_processors.test.ts.snap rename x-pack/plugins/observability_solution/asset_manager/server/lib/entities/{transform/generate_transform_id.ts => ingest_pipeline/generate_history_ingest_pipeline_id.ts} (58%) create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts rename x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/{generate_ingest_pipeline_id.ts => generate_latest_ingest_pipeline_id.ts} (58%) rename x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/{generate_processors.test.ts => generate_latest_processors.test.ts} (67%) rename x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/{generate_processors.ts => generate_latest_processors.ts} (68%) rename x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/{generate_transform.test.ts.snap => generate_history_transform.test.ts.snap} (67%) create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.test.ts create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.ts create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform_id.ts rename x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/{generate_transform.test.ts => generate_latest_transform.test.ts} (60%) create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform.ts create mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform_id.ts delete mode 100644 x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform.ts diff --git a/x-pack/packages/kbn-entities-schema/src/schema/common.ts b/x-pack/packages/kbn-entities-schema/src/schema/common.ts index 6b4f0cc794c2b..b2df63e93d71a 100644 --- a/x-pack/packages/kbn-entities-schema/src/schema/common.ts +++ b/x-pack/packages/kbn-entities-schema/src/schema/common.ts @@ -63,7 +63,8 @@ export const durationSchema = z const value = parseInt(parts[1], 10); const unit = parts[2] as 'm' | 's' | 'h' | 'd'; const duration = moment.duration(value, unit); - return { ...duration, toJSON: () => val }; + duration.toJSON = () => val; + return duration; }); export const percentileMetricSchema = z.object({ diff --git a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts index cf4be826acf04..8e5c411c2489e 100644 --- a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts +++ b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts @@ -8,15 +8,25 @@ import { z } from 'zod'; import { arrayOfStringsSchema } from './common'; -export const entitySchema = z.intersection( - z.object({ - entity: z.object({ - id: z.string(), - indexPatterns: arrayOfStringsSchema, - identityFields: arrayOfStringsSchema, - metric: z.record(z.string(), z.number()), - spaceId: z.string(), - }), +const entitySchema = z.object({ + entity: z.object({ + id: z.string(), + identityFields: arrayOfStringsSchema, + displayName: z.string(), + spaceId: z.string(), + metrics: z.record(z.string(), z.number()), }), +}); + +export const entitySummarySchema = z.intersection( + entitySchema.extend({ + lastSeenTimestamp: z.string(), + firstSeenTimestamp: z.string(), + }), + z.record(z.string(), z.string().or(z.number())) +); + +export const entityHistorySchema = z.intersection( + entitySchema.extend({ ['@timestamp']: z.string() }), z.record(z.string(), z.string().or(z.number())) ); diff --git a/x-pack/packages/kbn-entities-schema/src/schema/entity_definition.ts b/x-pack/packages/kbn-entities-schema/src/schema/entity_definition.ts index fa5ea596b6214..3ccc9a1ba2eea 100644 --- a/x-pack/packages/kbn-entities-schema/src/schema/entity_definition.ts +++ b/x-pack/packages/kbn-entities-schema/src/schema/entity_definition.ts @@ -24,18 +24,34 @@ export const entityDefinitionSchema = z.object({ filter: filterSchema, indexPatterns: arrayOfStringsSchema, identityFields: z.array(identityFieldsSchema), - identityTemplate: z.string(), + displayNameTemplate: z.string(), metadata: z.optional(z.array(metadataSchema)), metrics: z.optional(z.array(keyMetricSchema)), staticFields: z.optional(z.record(z.string(), z.string())), - lookback: durationSchema, - timestampField: z.string(), managed: z.optional(z.boolean()).default(false), - settings: z.optional( + history: z.object({ + timestampField: z.string(), + interval: durationSchema.refine((val) => val.asMinutes() >= 1, { + message: 'The history.interval can not be less than 1m', + }), + lookbackPeriod: z.optional(durationSchema), + settings: z.optional( + z.object({ + syncField: z.optional(z.string()), + syncDelay: z.optional(z.string()), + frequency: z.optional(z.string()), + }) + ), + }), + latest: z.optional( z.object({ - syncField: z.optional(z.string()), - syncDelay: z.optional(z.string()), - frequency: z.optional(z.string()), + settings: z.optional( + z.object({ + syncField: z.optional(z.string()), + syncDelay: z.optional(z.string()), + frequency: z.optional(z.string()), + }) + ), }) ), }); diff --git a/x-pack/plugins/observability_solution/asset_manager/common/constants_entities.ts b/x-pack/plugins/observability_solution/asset_manager/common/constants_entities.ts index aeeea398220a0..153b9f4e2ae33 100644 --- a/x-pack/plugins/observability_solution/asset_manager/common/constants_entities.ts +++ b/x-pack/plugins/observability_solution/asset_manager/common/constants_entities.ts @@ -6,8 +6,14 @@ */ export const ENTITY_VERSION = 'v1'; -export const ENTITY_BASE_PREFIX = `.entities-observability.summary-${ENTITY_VERSION}`; -export const ENTITY_TRANSFORM_PREFIX = `entities-observability-summary-${ENTITY_VERSION}`; -export const ENTITY_DEFAULT_FREQUENCY = '1m'; -export const ENTITY_DEFAULT_SYNC_DELAY = '60s'; -export const ENTITY_API_PREFIX = '/api/entities'; +export const ENTITY_BASE_PREFIX = '.entities-observability'; +export const ENTITY_HISTORY_BASE_PREFIX = `${ENTITY_BASE_PREFIX}.history-${ENTITY_VERSION}`; +export const ENTITY_LATEST_BASE_PREFIX = `${ENTITY_BASE_PREFIX}.latest-${ENTITY_VERSION}`; +export const ENTITY_HISTORY_TRANSFORM_PREFIX = `entity-history-${ENTITY_VERSION}`; +export const ENTITY_LATEST_TRANSFORM_PREFIX = `entity-latest-${ENTITY_VERSION}`; +export const ENTITY_DEFAULT_HISTORY_FREQUENCY = '1m'; +export const ENTITY_DEFAULT_HISTORY_SYNC_DELAY = '60s'; +export const ENTITY_DEFAULT_LATEST_FREQUENCY = '30s'; +export const ENTITY_DEFAULT_LATEST_SYNC_DELAY = '1s'; +export const ENTITY_DEFAULT_METADATA_LIMIT = 1000; +export const ENTITY_INTERNAL_API_PREFIX = '/internal/api/entities'; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_ingest_pipeline.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_ingest_pipeline.ts index cb820d14de487..c6fbc127230a6 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_ingest_pipeline.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_ingest_pipeline.ts @@ -7,34 +7,57 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { EntityDefinition } from '@kbn/entities-schema'; -import { generateProcessors } from './ingest_pipeline/generate_processors'; import { retryTransientEsErrors } from './helpers/retry'; -import { EntitySecurityException } from './errors/entity_security_exception'; -import { generateIngestPipelineId } from './ingest_pipeline/generate_ingest_pipeline_id'; +import { generateLatestProcessors } from './ingest_pipeline/generate_latest_processors'; +import { generateLatestIngestPipelineId } from './ingest_pipeline/generate_latest_ingest_pipeline_id'; +import { generateHistoryProcessors } from './ingest_pipeline/generate_history_processors'; +import { generateHistoryIngestPipelineId } from './ingest_pipeline/generate_history_ingest_pipeline_id'; -export async function createAndInstallIngestPipeline( +export async function createAndInstallHistoryIngestPipeline( esClient: ElasticsearchClient, definition: EntityDefinition, logger: Logger, spaceId: string ) { - const processors = generateProcessors(definition, spaceId); - const id = generateIngestPipelineId(definition); try { + const historyProcessors = generateHistoryProcessors(definition, spaceId); + const historyId = generateHistoryIngestPipelineId(definition); await retryTransientEsErrors( () => esClient.ingest.putPipeline({ - id, - processors, + id: historyId, + processors: historyProcessors, }), { logger } ); } catch (e) { - logger.error(`Cannot create entity ingest pipeline for [${definition.id}] entity definition`); - if (e.meta?.body?.error?.type === 'security_exception') { - throw new EntitySecurityException(e.meta.body.error.reason, definition); - } + logger.error( + `Cannot create entity history ingest pipelines for [${definition.id}] entity defintion` + ); + throw e; + } +} +export async function createAndInstallLatestIngestPipeline( + esClient: ElasticsearchClient, + definition: EntityDefinition, + logger: Logger, + spaceId: string +) { + try { + const latestProcessors = generateLatestProcessors(definition, spaceId); + const latestId = generateLatestIngestPipelineId(definition); + await retryTransientEsErrors( + () => + esClient.ingest.putPipeline({ + id: latestId, + processors: latestProcessors, + }), + { logger } + ); + } catch (e) { + logger.error( + `Cannot create entity latest ingest pipelines for [${definition.id}] entity defintion` + ); throw e; } - return id; } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_transform.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_transform.ts index f8cd02250d898..aca51df235fea 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_transform.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/create_and_install_transform.ts @@ -7,24 +7,38 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { EntityDefinition } from '@kbn/entities-schema'; -import { generateTransform } from './transform/generate_transform'; import { retryTransientEsErrors } from './helpers/retry'; -import { EntitySecurityException } from './errors/entity_security_exception'; +import { generateLatestTransform } from './transform/generate_latest_transform'; +import { generateHistoryTransform } from './transform/generate_history_transform'; -export async function createAndInstallTransform( +export async function createAndInstallHistoryTransform( esClient: ElasticsearchClient, definition: EntityDefinition, logger: Logger ) { - const transform = generateTransform(definition); try { - await retryTransientEsErrors(() => esClient.transform.putTransform(transform), { logger }); + const historyTransform = generateHistoryTransform(definition); + await retryTransientEsErrors(() => esClient.transform.putTransform(historyTransform), { + logger, + }); } catch (e) { - logger.error(`Cannot create entity transform for [${definition.id}] entity definition`); - if (e.meta?.body?.error?.type === 'security_exception') { - throw new EntitySecurityException(e.meta.body.error.reason, definition); - } + logger.error(`Cannot create entity history transform for [${definition.id}] entity definition`); + throw e; + } +} + +export async function createAndInstallLatestTransform( + esClient: ElasticsearchClient, + definition: EntityDefinition, + logger: Logger +) { + try { + const latestTransform = generateLatestTransform(definition); + await retryTransientEsErrors(() => esClient.transform.putTransform(latestTransform), { + logger, + }); + } catch (e) { + logger.error(`Cannot create entity latest transform for [${definition.id}] entity definition`); throw e; } - return transform.transform_id; } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_index.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_index.ts index b05dee0f0f251..dec1ef3b585dc 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_index.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_index.ts @@ -7,16 +7,21 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { EntityDefinition } from '@kbn/entities-schema'; -import { generateIndexName } from './helpers/generate_index_name'; +import { generateHistoryIndexName, generateLatestIndexName } from './helpers/generate_index_name'; -export async function deleteIndex( +export async function deleteIndices( esClient: ElasticsearchClient, definition: EntityDefinition, logger: Logger ) { - const indexName = generateIndexName(definition); try { - await esClient.indices.delete({ index: indexName, ignore_unavailable: true }); + const response = await esClient.indices.resolveIndex({ + name: `${generateHistoryIndexName(definition)}.*,${generateLatestIndexName(definition)}`, + }); + const indices = response.indices.map((doc) => doc.name); + if (indices.length) { + await esClient.indices.delete({ index: indices, ignore_unavailable: true }); + } } catch (e) { logger.error(`Unable to remove entity definition index [${definition.id}}]`); throw e; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_ingest_pipeline.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_ingest_pipeline.ts index 1e42282369ef3..80fa96b8109ef 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_ingest_pipeline.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/delete_ingest_pipeline.ts @@ -7,21 +7,38 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { EntityDefinition } from '@kbn/entities-schema'; -import { generateIngestPipelineId } from './ingest_pipeline/generate_ingest_pipeline_id'; import { retryTransientEsErrors } from './helpers/retry'; +import { generateLatestIngestPipelineId } from './ingest_pipeline/generate_latest_ingest_pipeline_id'; +import { generateHistoryIngestPipelineId } from './ingest_pipeline/generate_history_ingest_pipeline_id'; -export async function deleteIngestPipeline( +export async function deleteHistoryIngestPipeline( esClient: ElasticsearchClient, definition: EntityDefinition, logger: Logger ) { - const pipelineId = generateIngestPipelineId(definition); try { + const historyPipelineId = generateHistoryIngestPipelineId(definition); await retryTransientEsErrors(() => - esClient.ingest.deletePipeline({ id: pipelineId }, { ignore: [404] }) + esClient.ingest.deletePipeline({ id: historyPipelineId }, { ignore: [404] }) ); } catch (e) { - logger.error(`Unable to delete ingest pipeline [${pipelineId}]`); + logger.error(`Unable to delete history ingest pipeline [${definition.id}].`); + throw e; + } +} + +export async function deleteLatestIngestPipeline( + esClient: ElasticsearchClient, + definition: EntityDefinition, + logger: Logger +) { + try { + const latestPipelineId = generateLatestIngestPipelineId(definition); + await retryTransientEsErrors(() => + esClient.ingest.deletePipeline({ id: latestPipelineId }, { ignore: [404] }) + ); + } catch (e) { + logger.error(`Unable to delete latest ingest pipeline [${definition.id}].`); throw e; } } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/errors/entity_security_exception.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/errors/entity_security_exception.ts index c7e0d114c5afb..10b802c8540e5 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/errors/entity_security_exception.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/errors/entity_security_exception.ts @@ -5,14 +5,9 @@ * 2.0. */ -import { EntityDefinition } from '@kbn/entities-schema'; - export class EntitySecurityException extends Error { - public definition: EntityDefinition; - - constructor(message: string, def: EntityDefinition) { + constructor(message: string) { super(message); this.name = 'EntitySecurityException'; - this.definition = def; } } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/fixtures/entity_definition.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/fixtures/entity_definition.ts index fdb808466ba83..3e07c6860a30a 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/fixtures/entity_definition.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/fixtures/entity_definition.ts @@ -7,22 +7,21 @@ import { entityDefinitionSchema } from '@kbn/entities-schema'; export const entityDefinition = entityDefinitionSchema.parse({ - id: 'admin-console-logs-service', + id: 'admin-console-services', name: 'Services for Admin Console', type: 'service', indexPatterns: ['kbn-data-forge-fake_stack.*'], - timestampField: '@timestamp', - identityFields: ['log.logger'], - identityTemplate: 'service:{{log.logger}}', - metadata: ['tags', 'host.name', 'kubernetes.pod.name'], - staticFields: { - projectId: '1234', + history: { + timestampField: '@timestamp', + interval: '1m', }, - lookback: '5m', + identityFields: ['log.logger', { field: 'event.category', optional: true }], + displayNameTemplate: '{{log.logger}}{{#event.category}}:{{.}}{{/event.category}}', + metadata: ['tags', 'host.name'], metrics: [ { name: 'logRate', - equation: 'A / 5', + equation: 'A', metrics: [ { name: 'A', @@ -33,12 +32,12 @@ export const entityDefinition = entityDefinitionSchema.parse({ }, { name: 'errorRate', - equation: 'A / 5', + equation: 'A', metrics: [ { name: 'A', aggregation: 'doc_count', - filter: 'log.level: error', + filter: 'log.level: "ERROR"', }, ], }, diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/generate_index_name.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/generate_index_name.ts index 365104f3571eb..151ebe75c7065 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/generate_index_name.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/generate_index_name.ts @@ -6,8 +6,15 @@ */ import { EntityDefinition } from '@kbn/entities-schema'; -import { ENTITY_BASE_PREFIX } from '../../../../common/constants_entities'; +import { + ENTITY_HISTORY_BASE_PREFIX, + ENTITY_LATEST_BASE_PREFIX, +} from '../../../../common/constants_entities'; -export function generateIndexName(definition: EntityDefinition) { - return `${ENTITY_BASE_PREFIX}.${definition.id}`; +export function generateLatestIndexName(definition: EntityDefinition) { + return `${ENTITY_LATEST_BASE_PREFIX}.${definition.id}`; +} + +export function generateHistoryIndexName(definition: EntityDefinition) { + return `${ENTITY_HISTORY_BASE_PREFIX}.${definition.id}`; } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/retry.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/retry.ts index 421289d1c0479..c6ce2d9924fa3 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/retry.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/helpers/retry.ts @@ -8,6 +8,7 @@ import { setTimeout } from 'timers/promises'; import { errors as EsErrors } from '@elastic/elasticsearch'; import type { Logger } from '@kbn/logging'; +import { EntitySecurityException } from '../errors/entity_security_exception'; const MAX_ATTEMPTS = 5; @@ -48,6 +49,10 @@ export const retryTransientEsErrors = async ( return retryTransientEsErrors(esCall, { logger, attempt: retryCount }); } + if (e.meta?.body?.error?.type === 'security_exception') { + throw new EntitySecurityException(e.meta.body.error.reason); + } + throw e; } }; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap new file mode 100644 index 0000000000000..8783bab7b5589 --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap @@ -0,0 +1,111 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`generateHistoryProcessors(definition) should genearte a valid pipeline 1`] = ` +Array [ + Object { + "set": Object { + "field": "event.ingested", + "value": "{{{_ingest.timestamp}}}", + }, + }, + Object { + "set": Object { + "field": "entity.spaceId", + "value": "default", + }, + }, + Object { + "set": Object { + "field": "entity.definitionId", + "value": "admin-console-services", + }, + }, + Object { + "set": Object { + "field": "entity.displayName", + "value": "{{entity.identityFields.log.logger}}{{#entity.identityFields.event.category}}:{{.}}{{/entity.identityFields.event.category}}", + }, + }, + Object { + "script": Object { + "description": "Generated the entity.id field", + "source": " + // This function will recursively collect all the values of a HashMap of HashMaps + Collection collectValues(HashMap subject) { + Collection values = new ArrayList(); + // Iterate through the values + for(Object value: subject.values()) { + // If the value is a HashMap, recurse + if (value instanceof HashMap) { + values.addAll(collectValues((HashMap) value)); + } else { + values.add(String.valueOf(value)); + } + } + return values; + } + + // Create the string builder + StringBuilder entityId = new StringBuilder(); + + if (ctx[\\"entity\\"][\\"identityFields\\"] != null) { + // Get the values as a collection + Collection values = collectValues(ctx[\\"entity\\"][\\"identityFields\\"]); + + // Convert to a list and sort + List sortedValues = new ArrayList(values); + Collections.sort(sortedValues); + + // Create comma delimited string + for(String instanceValue: sortedValues) { + entityId.append(instanceValue); + entityId.append(\\":\\"); + } + + // Assign the slo.instanceId + ctx[\\"entity\\"][\\"id\\"] = entityId.length() > 0 ? entityId.substring(0, entityId.length() - 1) : \\"unknown\\"; + } + ", + }, + }, + Object { + "fingerprint": Object { + "fields": Array [ + "entity.id", + ], + "method": "MurmurHash3", + "target_field": "entity.id", + }, + }, + Object { + "script": Object { + "source": "if (ctx.entity?.metadata?.tags != null) { + ctx[\\"tags\\"] = ctx.entity.metadata.tags.keySet(); +} +if (ctx.entity?.metadata?.host?.name != null) { + ctx[\\"host\\"] = new HashMap(); + ctx[\\"host\\"][\\"name\\"] = ctx.entity.metadata.host.name.keySet(); +} +", + }, + }, + Object { + "remove": Object { + "field": "entity.metadata", + "ignore_missing": true, + }, + }, + Object { + "date_index_name": Object { + "date_formats": Array [ + "UNIX_MS", + "ISO8601", + "yyyy-MM-dd'T'HH:mm:ss.SSSXX", + ], + "date_rounding": "M", + "field": "@timestamp", + "index_name_prefix": ".entities-observability.history-v1.admin-console-services.default.", + }, + }, +] +`; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap new file mode 100644 index 0000000000000..3b6cee7db59f7 --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap @@ -0,0 +1,48 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`generateLatestProcessors(definition) should genearte a valid pipeline 1`] = ` +Array [ + Object { + "set": Object { + "field": "event.ingested", + "value": "{{{_ingest.timestamp}}}", + }, + }, + Object { + "set": Object { + "field": "entity.spaceId", + "value": "default", + }, + }, + Object { + "set": Object { + "field": "entity.definitionId", + "value": "admin-console-services", + }, + }, + Object { + "script": Object { + "source": "if (ctx.entity?.metadata?.tags.data != null) { + ctx[\\"tags\\"] = ctx.entity.metadata.tags.data.keySet(); +} +if (ctx.entity?.metadata?.host?.name.data != null) { + ctx[\\"host\\"] = new HashMap(); + ctx[\\"host\\"][\\"name\\"] = ctx.entity.metadata.host.name.data.keySet(); +} +", + }, + }, + Object { + "remove": Object { + "field": "entity.metadata", + "ignore_missing": true, + }, + }, + Object { + "set": Object { + "field": "_index", + "value": ".entities-observability.latest-v1.admin-console-services.default", + }, + }, +] +`; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_processors.test.ts.snap b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_processors.test.ts.snap deleted file mode 100644 index 43bae00156a4c..0000000000000 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_processors.test.ts.snap +++ /dev/null @@ -1,76 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`generateProcessors(definition) should genearte a valid pipeline 1`] = ` -Array [ - Object { - "set": Object { - "field": "event.ingested", - "value": "{{{_ingest.timestamp}}}", - }, - }, - Object { - "set": Object { - "field": "entity.spaceId", - "value": "test", - }, - }, - Object { - "set": Object { - "field": "entity.definitionId", - "value": "admin-console-logs-service", - }, - }, - Object { - "set": Object { - "field": "entity.indexPatterns", - "value": "[\\"kbn-data-forge-fake_stack.*\\"]", - }, - }, - Object { - "json": Object { - "field": "entity.indexPatterns", - }, - }, - Object { - "set": Object { - "field": "entity.id", - "value": "service:{{entity.identity.log.logger}}", - }, - }, - Object { - "set": Object { - "field": "projectId", - "value": "1234", - }, - }, - Object { - "script": Object { - "source": "if (ctx.entity?.metadata?.tags != null) { - ctx[\\"tags\\"] = ctx.entity.metadata.tags.keySet(); -} -if (ctx.entity?.metadata?.host?.name != null) { - ctx[\\"host\\"] = new HashMap(); - ctx[\\"host\\"][\\"name\\"] = ctx.entity.metadata.host.name.keySet(); -} -if (ctx.entity?.metadata?.kubernetes?.pod?.name != null) { - ctx[\\"kubernetes\\"] = new HashMap(); - ctx[\\"kubernetes\\"][\\"pod\\"] = new HashMap(); - ctx[\\"kubernetes\\"][\\"pod\\"][\\"name\\"] = ctx.entity.metadata.kubernetes.pod.name.keySet(); -} -", - }, - }, - Object { - "remove": Object { - "field": "entity.metadata", - "ignore_missing": true, - }, - }, - Object { - "set": Object { - "field": "_index", - "value": ".entities-observability.summary-v1.admin-console-logs-service", - }, - }, -] -`; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform_id.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_ingest_pipeline_id.ts similarity index 58% rename from x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform_id.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_ingest_pipeline_id.ts index 06faedb916774..103e0950d58ff 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform_id.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_ingest_pipeline_id.ts @@ -6,8 +6,8 @@ */ import { EntityDefinition } from '@kbn/entities-schema'; -import { ENTITY_TRANSFORM_PREFIX } from '../../../../common/constants_entities'; +import { ENTITY_HISTORY_BASE_PREFIX } from '../../../../common/constants_entities'; -export function generateTransformId(definition: EntityDefinition) { - return `${ENTITY_TRANSFORM_PREFIX}-${definition.id}`; +export function generateHistoryIngestPipelineId(definition: EntityDefinition) { + return `${ENTITY_HISTORY_BASE_PREFIX}.${definition.id}`; } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts new file mode 100644 index 0000000000000..8203d06c1f8ed --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { entityDefinition } from '../helpers/fixtures/entity_definition'; +import { generateHistoryProcessors } from './generate_history_processors'; + +describe('generateHistoryProcessors(definition)', () => { + it('should genearte a valid pipeline', () => { + const processors = generateHistoryProcessors(entityDefinition, 'default'); + expect(processors).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts new file mode 100644 index 0000000000000..198f129c94db5 --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts @@ -0,0 +1,144 @@ +/* + * 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 { EntityDefinition } from '@kbn/entities-schema'; +import { generateHistoryIndexName } from '../helpers/generate_index_name'; + +function createIdTemplate(definition: EntityDefinition) { + return definition.identityFields.reduce((template, id) => { + return template.replaceAll(id.field, `entity.identityFields.${id.field}`); + }, definition.displayNameTemplate); +} + +function mapDesitnationToPainless(destination: string, source: string) { + const fieldParts = destination.split('.'); + return fieldParts.reduce((acc, _part, currentIndex, parts) => { + if (currentIndex + 1 === parts.length) { + return `${acc}\n ctx${parts + .map((s) => `["${s}"]`) + .join('')} = ctx.entity.metadata.${source}.keySet();`; + } + return `${acc}\n ctx${parts + .slice(0, currentIndex + 1) + .map((s) => `["${s}"]`) + .join('')} = new HashMap();`; + }, ''); +} + +function createMetadataPainlessScript(definition: EntityDefinition) { + if (!definition.metadata) { + return ''; + } + return definition.metadata.reduce((script, def) => { + const source = def.source; + const destination = def.destination || def.source; + return `${script}if (ctx.entity?.metadata?.${source.replaceAll( + '.', + '?.' + )} != null) {${mapDesitnationToPainless(destination, source)}\n}\n`; + }, ''); +} + +export function generateHistoryProcessors(definition: EntityDefinition, spaceId: string) { + return [ + { + set: { + field: 'event.ingested', + value: '{{{_ingest.timestamp}}}', + }, + }, + { + set: { + field: 'entity.spaceId', + value: spaceId, + }, + }, + { + set: { + field: 'entity.definitionId', + value: definition.id, + }, + }, + { + set: { + field: 'entity.displayName', + value: createIdTemplate(definition), + }, + }, + { + script: { + description: 'Generated the entity.id field', + source: ` + // This function will recursively collect all the values of a HashMap of HashMaps + Collection collectValues(HashMap subject) { + Collection values = new ArrayList(); + // Iterate through the values + for(Object value: subject.values()) { + // If the value is a HashMap, recurse + if (value instanceof HashMap) { + values.addAll(collectValues((HashMap) value)); + } else { + values.add(String.valueOf(value)); + } + } + return values; + } + + // Create the string builder + StringBuilder entityId = new StringBuilder(); + + if (ctx["entity"]["identityFields"] != null) { + // Get the values as a collection + Collection values = collectValues(ctx["entity"]["identityFields"]); + + // Convert to a list and sort + List sortedValues = new ArrayList(values); + Collections.sort(sortedValues); + + // Create comma delimited string + for(String instanceValue: sortedValues) { + entityId.append(instanceValue); + entityId.append(":"); + } + + // Assign the slo.instanceId + ctx["entity"]["id"] = entityId.length() > 0 ? entityId.substring(0, entityId.length() - 1) : "unknown"; + } + `, + }, + }, + { + fingerprint: { + fields: ['entity.id'], + target_field: 'entity.id', + method: 'MurmurHash3', + }, + }, + ...(definition.staticFields != null + ? Object.keys(definition.staticFields).map((field) => ({ + set: { field, value: definition.staticFields![field] }, + })) + : []), + ...(definition.metadata != null + ? [{ script: { source: createMetadataPainlessScript(definition) } }] + : []), + { + remove: { + field: 'entity.metadata', + ignore_missing: true, + }, + }, + { + date_index_name: { + field: '@timestamp', + index_name_prefix: `${generateHistoryIndexName(definition)}.${spaceId}.`, + date_rounding: 'M', + date_formats: ['UNIX_MS', 'ISO8601', "yyyy-MM-dd'T'HH:mm:ss.SSSXX"], + }, + }, + ]; +} diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_ingest_pipeline_id.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_ingest_pipeline_id.ts similarity index 58% rename from x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_ingest_pipeline_id.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_ingest_pipeline_id.ts index c772e198e64fd..27ed87dcfb84d 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_ingest_pipeline_id.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_ingest_pipeline_id.ts @@ -6,8 +6,8 @@ */ import { EntityDefinition } from '@kbn/entities-schema'; -import { ENTITY_BASE_PREFIX } from '../../../../common/constants_entities'; +import { ENTITY_LATEST_BASE_PREFIX } from '../../../../common/constants_entities'; -export function generateIngestPipelineId(definition: EntityDefinition) { - return `${ENTITY_BASE_PREFIX}.${definition.id}`; +export function generateLatestIngestPipelineId(definition: EntityDefinition) { + return `${ENTITY_LATEST_BASE_PREFIX}.${definition.id}`; } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_processors.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts similarity index 67% rename from x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_processors.test.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts index a2eb9c3ecb6f7..63cab821b472a 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_processors.test.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts @@ -5,13 +5,12 @@ * 2.0. */ -import { generateProcessors } from './generate_processors'; import { entityDefinition } from '../helpers/fixtures/entity_definition'; +import { generateLatestProcessors } from './generate_latest_processors'; -describe('generateProcessors(definition)', () => { +describe('generateLatestProcessors(definition)', () => { it('should genearte a valid pipeline', () => { - const spaceId = 'test'; - const processors = generateProcessors(entityDefinition, spaceId); + const processors = generateLatestProcessors(entityDefinition, 'default'); expect(processors).toMatchSnapshot(); }); }); diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_processors.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts similarity index 68% rename from x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_processors.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts index 70c3b34368b3a..e84d1674b571b 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_processors.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts @@ -6,13 +6,7 @@ */ import { EntityDefinition } from '@kbn/entities-schema'; -import { generateIndexName } from '../helpers/generate_index_name'; - -function createIdTemplate(definition: EntityDefinition) { - return definition.identityFields.reduce((template, id) => { - return template.replaceAll(id.field, `entity.identity.${id.field}`); - }, definition.identityTemplate); -} +import { generateLatestIndexName } from '../helpers/generate_index_name'; function mapDesitnationToPainless(destination: string, source: string) { const fieldParts = destination.split('.'); @@ -20,7 +14,7 @@ function mapDesitnationToPainless(destination: string, source: string) { if (currentIndex + 1 === parts.length) { return `${acc}\n ctx${parts .map((s) => `["${s}"]`) - .join('')} = ctx.entity.metadata.${source}.keySet();`; + .join('')} = ctx.entity.metadata.${source}.data.keySet();`; } return `${acc}\n ctx${parts .slice(0, currentIndex + 1) @@ -39,11 +33,11 @@ function createMetadataPainlessScript(definition: EntityDefinition) { return `${script}if (ctx.entity?.metadata?.${source.replaceAll( '.', '?.' - )} != null) {${mapDesitnationToPainless(destination, source)}\n}\n`; + )}.data != null) {${mapDesitnationToPainless(destination, source)}\n}\n`; }, ''); } -export function generateProcessors(definition: EntityDefinition, spaceId: string) { +export function generateLatestProcessors(definition: EntityDefinition, spaceId: string) { return [ { set: { @@ -63,23 +57,6 @@ export function generateProcessors(definition: EntityDefinition, spaceId: string value: definition.id, }, }, - { - set: { - field: 'entity.indexPatterns', - value: JSON.stringify(definition.indexPatterns), - }, - }, - { - json: { - field: 'entity.indexPatterns', - }, - }, - { - set: { - field: 'entity.id', - value: createIdTemplate(definition), - }, - }, ...(definition.staticFields != null ? Object.keys(definition.staticFields).map((field) => ({ set: { field, value: definition.staticFields![field] }, @@ -97,7 +74,7 @@ export function generateProcessors(definition: EntityDefinition, spaceId: string { set: { field: '_index', - value: generateIndexName(definition), + value: `${generateLatestIndexName(definition)}.${spaceId}`, }, }, ]; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/start_transform.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/start_transform.ts index 766bbb10b1d67..03d199c09adf8 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/start_transform.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/start_transform.ts @@ -8,21 +8,29 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { EntityDefinition } from '@kbn/entities-schema'; import { retryTransientEsErrors } from './helpers/retry'; -import { generateTransformId } from './transform/generate_transform_id'; +import { generateLatestTransformId } from './transform/generate_latest_transform_id'; +import { generateHistoryTransformId } from './transform/generate_history_transform_id'; export async function startTransform( esClient: ElasticsearchClient, definition: EntityDefinition, logger: Logger ) { - const transformId = generateTransformId(definition); try { + const historyTransformId = generateHistoryTransformId(definition); + const latestTransformId = generateLatestTransformId(definition); await retryTransientEsErrors( - () => esClient.transform.startTransform({ transform_id: transformId }, { ignore: [409] }), + () => + esClient.transform.startTransform({ transform_id: historyTransformId }, { ignore: [409] }), + { logger } + ); + await retryTransientEsErrors( + () => + esClient.transform.startTransform({ transform_id: latestTransformId }, { ignore: [409] }), { logger } ); } catch (err) { - logger.error(`Cannot start entity transform [${transformId}]`); + logger.error(`Cannot start entity transforms [${definition.id}]`); throw err; } } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/stop_and_delete_transform.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/stop_and_delete_transform.ts index 60a250a33f0d9..2088a3dbaaeb0 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/stop_and_delete_transform.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/stop_and_delete_transform.ts @@ -7,31 +7,63 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { EntityDefinition } from '@kbn/entities-schema'; -import { generateTransformId } from './transform/generate_transform_id'; import { retryTransientEsErrors } from './helpers/retry'; +import { generateLatestTransformId } from './transform/generate_latest_transform_id'; +import { generateHistoryTransformId } from './transform/generate_history_transform_id'; -export async function stopAndDeleteTransform( +export async function stopAndDeleteHistoryTransform( esClient: ElasticsearchClient, definition: EntityDefinition, logger: Logger ) { - const transformId = generateTransformId(definition); try { + const historyTransformId = generateHistoryTransformId(definition); await retryTransientEsErrors( - async () => { - await esClient.transform.stopTransform( - { transform_id: transformId, wait_for_completion: true, force: true }, + () => + esClient.transform.stopTransform( + { transform_id: historyTransformId, wait_for_completion: true, force: true }, { ignore: [409] } - ); - await esClient.transform.deleteTransform( - { transform_id: transformId, force: true }, + ), + { logger } + ); + await retryTransientEsErrors( + () => + esClient.transform.deleteTransform( + { transform_id: historyTransformId, force: true }, + { ignore: [404] } + ), + { logger } + ); + } catch (e) { + logger.error(`Cannot stop or delete history transform [${definition.id}]`); + throw e; + } +} +export async function stopAndDeleteLatestTransform( + esClient: ElasticsearchClient, + definition: EntityDefinition, + logger: Logger +) { + try { + const latestTransformId = generateLatestTransformId(definition); + await retryTransientEsErrors( + () => + esClient.transform.stopTransform( + { transform_id: latestTransformId, wait_for_completion: true, force: true }, + { ignore: [409] } + ), + { logger } + ); + await retryTransientEsErrors( + () => + esClient.transform.deleteTransform( + { transform_id: latestTransformId, force: true }, { ignore: [404] } - ); - }, + ), { logger } ); } catch (e) { - logger.error(`Cannot stop or delete entity transform [${transformId}]`); + logger.error(`Cannot stop or delete latest transform [${definition.id}]`); throw e; } } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_transform.test.ts.snap b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap similarity index 67% rename from x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_transform.test.ts.snap rename to x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap index e692f2068eafd..96cc7bd24afe6 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_transform.test.ts.snap +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap @@ -1,11 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`generateTransform(definition) should generate a valid summary transform 1`] = ` +exports[`generateHistoryTransform(definition) should generate a valid latest transform 1`] = ` Object { "defer_validation": true, "dest": Object { - "index": ".entities-observability.summary-v1.noop", - "pipeline": ".entities-observability.summary-v1.admin-console-logs-service", + "index": ".entities-observability.history-v1.noop", + "pipeline": ".entities-observability.history-v1.admin-console-services", }, "frequency": "1m", "pivot": Object { @@ -16,8 +16,8 @@ Object { "minimum_should_match": 1, "should": Array [ Object { - "match": Object { - "log.level": "error", + "match_phrase": Object { + "log.level": "ERROR", }, }, ], @@ -38,7 +38,7 @@ Object { }, }, }, - "entity.latestTimestamp": Object { + "entity.lastSeenTimestamp": Object { "max": Object { "field": "@timestamp", }, @@ -49,43 +49,49 @@ Object { "size": 1000, }, }, - "entity.metadata.kubernetes.pod.name": Object { - "terms": Object { - "field": "kubernetes.pod.name", - "size": 1000, - }, - }, "entity.metadata.tags": Object { "terms": Object { "field": "tags", "size": 1000, }, }, - "entity.metric.errorRate": Object { + "entity.metrics.errorRate": Object { "bucket_script": Object { "buckets_path": Object { "A": "_errorRate_A>_count", }, "script": Object { "lang": "painless", - "source": "params.A / 5", + "source": "params.A", }, }, }, - "entity.metric.logRate": Object { + "entity.metrics.logRate": Object { "bucket_script": Object { "buckets_path": Object { "A": "_logRate_A>_count", }, "script": Object { "lang": "painless", - "source": "params.A / 5", + "source": "params.A", }, }, }, }, "group_by": Object { - "entity.identity.log.logger": Object { + "@timestamp": Object { + "date_histogram": Object { + "field": "@timestamp", + "fixed_interval": "1m", + }, + }, + "entity.identityFields.event.category": Object { + "terms": Object { + "field": "event.category", + "missing_bucket": true, + }, + }, + "entity.identityFields.log.logger": Object { "terms": Object { "field": "log.logger", "missing_bucket": false, @@ -101,19 +107,6 @@ Object { "index": Array [ "kbn-data-forge-fake_stack.*", ], - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "range": Object { - "@timestamp": Object { - "gte": "now-5m", - }, - }, - }, - ], - }, - }, }, "sync": Object { "time": Object { @@ -121,6 +114,6 @@ Object { "field": "@timestamp", }, }, - "transform_id": "entities-observability-summary-v1-admin-console-logs-service", + "transform_id": "entity-history-v1-admin-console-services", } `; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap new file mode 100644 index 0000000000000..ee0954add4091 --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap @@ -0,0 +1,142 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`generateLatestTransform(definition) should generate a valid latest transform 1`] = ` +Object { + "defer_validation": true, + "dest": Object { + "index": ".entities-observability.latest-v1.noop", + "pipeline": ".entities-observability.latest-v1.admin-console-services", + }, + "frequency": "30s", + "pivot": Object { + "aggs": Object { + "_errorRate": Object { + "top_metrics": Object { + "metrics": Array [ + Object { + "field": "entity.metrics.errorRate", + }, + ], + "sort": Array [ + Object { + "@timestamp": "desc", + }, + ], + }, + }, + "_logRate": Object { + "top_metrics": Object { + "metrics": Array [ + Object { + "field": "entity.metrics.logRate", + }, + ], + "sort": Array [ + Object { + "@timestamp": "desc", + }, + ], + }, + }, + "entity.firstSeenTimestamp": Object { + "min": Object { + "field": "@timestamp", + }, + }, + "entity.lastSeenTimestamp": Object { + "max": Object { + "field": "entity.lastSeenTimestamp", + }, + }, + "entity.metadata.host.name": Object { + "aggs": Object { + "data": Object { + "terms": Object { + "field": "host.name", + "size": 1000, + }, + }, + }, + "filter": Object { + "range": Object { + "event.ingested": Object { + "gte": "now-1m", + }, + }, + }, + }, + "entity.metadata.tags": Object { + "aggs": Object { + "data": Object { + "terms": Object { + "field": "tags", + "size": 1000, + }, + }, + }, + "filter": Object { + "range": Object { + "event.ingested": Object { + "gte": "now-1m", + }, + }, + }, + }, + "entity.metrics.errorRate": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_errorRate[entity.metrics.errorRate]", + }, + "script": "params.value", + }, + }, + "entity.metrics.logRate": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_logRate[entity.metrics.logRate]", + }, + "script": "params.value", + }, + }, + }, + "group_by": Object { + "entity.displayName": Object { + "terms": Object { + "field": "entity.displayName.keyword", + }, + }, + "entity.id": Object { + "terms": Object { + "field": "entity.id", + }, + }, + "entity.identityFields.event.category": Object { + "terms": Object { + "field": "entity.identityFields.event.category", + "missing_bucket": true, + }, + }, + "entity.identityFields.log.logger": Object { + "terms": Object { + "field": "entity.identityFields.log.logger", + "missing_bucket": false, + }, + }, + }, + }, + "settings": Object { + "deduce_mappings": false, + "unattended": true, + }, + "source": Object { + "index": ".entities-observability.history-v1.admin-console-services.*", + }, + "sync": Object { + "time": Object { + "delay": "1s", + "field": "event.ingested", + }, + }, + "transform_id": "entity-latest-v1-admin-console-services", +} +`; diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.test.ts new file mode 100644 index 0000000000000..8bb9f494d5f4e --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.test.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { entityDefinition } from '../helpers/fixtures/entity_definition'; +import { generateHistoryTransform } from './generate_history_transform'; + +describe('generateHistoryTransform(definition)', () => { + it('should generate a valid latest transform', () => { + const transform = generateHistoryTransform(entityDefinition); + expect(transform).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.ts new file mode 100644 index 0000000000000..0e98040e4285f --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform.ts @@ -0,0 +1,90 @@ +/* + * 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 { EntityDefinition } from '@kbn/entities-schema'; +import { + QueryDslQueryContainer, + TransformPutTransformRequest, +} from '@elastic/elasticsearch/lib/api/types'; +import { getElasticsearchQueryOrThrow } from '../helpers/get_elasticsearch_query_or_throw'; +import { generateHistoryMetricAggregations } from './generate_metric_aggregations'; +import { + ENTITY_DEFAULT_HISTORY_FREQUENCY, + ENTITY_DEFAULT_HISTORY_SYNC_DELAY, + ENTITY_HISTORY_BASE_PREFIX, +} from '../../../../common/constants_entities'; +import { generateHistoryMetadataAggregations } from './generate_metadata_aggregations'; +import { generateHistoryTransformId } from './generate_history_transform_id'; +import { generateHistoryIngestPipelineId } from '../ingest_pipeline/generate_history_ingest_pipeline_id'; + +export function generateHistoryTransform( + definition: EntityDefinition +): TransformPutTransformRequest { + const filter: QueryDslQueryContainer[] = []; + + if (definition.filter) { + filter.push(getElasticsearchQueryOrThrow(definition.filter)); + } + + return { + transform_id: generateHistoryTransformId(definition), + defer_validation: true, + source: { + index: definition.indexPatterns, + ...(filter.length > 0 && { + query: { + bool: { + filter, + }, + }, + }), + }, + dest: { + index: `${ENTITY_HISTORY_BASE_PREFIX}.noop`, + pipeline: generateHistoryIngestPipelineId(definition), + }, + frequency: definition.history.settings?.frequency ?? ENTITY_DEFAULT_HISTORY_FREQUENCY, + sync: { + time: { + field: definition.history.settings?.syncField ?? definition.history.timestampField, + delay: definition.history.settings?.syncDelay ?? ENTITY_DEFAULT_HISTORY_SYNC_DELAY, + }, + }, + settings: { + deduce_mappings: false, + unattended: true, + }, + pivot: { + group_by: { + ...definition.identityFields.reduce( + (acc, id) => ({ + ...acc, + [`entity.identityFields.${id.field}`]: { + terms: { field: id.field, missing_bucket: id.optional }, + }, + }), + {} + ), + ['@timestamp']: { + date_histogram: { + field: definition.history.timestampField, + fixed_interval: definition.history.interval.toJSON(), + }, + }, + }, + aggs: { + ...generateHistoryMetricAggregations(definition), + ...generateHistoryMetadataAggregations(definition), + 'entity.lastSeenTimestamp': { + max: { + field: definition.history.timestampField, + }, + }, + }, + }, + }; +} diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform_id.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform_id.ts new file mode 100644 index 0000000000000..60f48af97ada6 --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_history_transform_id.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EntityDefinition } from '@kbn/entities-schema'; +import { ENTITY_HISTORY_TRANSFORM_PREFIX } from '../../../../common/constants_entities'; + +export function generateHistoryTransformId(definition: EntityDefinition) { + return `${ENTITY_HISTORY_TRANSFORM_PREFIX}-${definition.id}`; +} diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform.test.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform.test.ts similarity index 60% rename from x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform.test.ts rename to x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform.test.ts index e97293b77dd4f..a293279687078 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform.test.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform.test.ts @@ -6,11 +6,11 @@ */ import { entityDefinition } from '../helpers/fixtures/entity_definition'; -import { generateTransform } from './generate_transform'; +import { generateLatestTransform } from './generate_latest_transform'; -describe('generateTransform(definition)', () => { - it('should generate a valid summary transform', () => { - const transform = generateTransform(entityDefinition); +describe('generateLatestTransform(definition)', () => { + it('should generate a valid latest transform', () => { + const transform = generateLatestTransform(entityDefinition); expect(transform).toMatchSnapshot(); }); }); diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform.ts new file mode 100644 index 0000000000000..425699aaef58d --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EntityDefinition } from '@kbn/entities-schema'; +import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; +import { + ENTITY_DEFAULT_LATEST_FREQUENCY, + ENTITY_DEFAULT_LATEST_SYNC_DELAY, + ENTITY_LATEST_BASE_PREFIX, +} from '../../../../common/constants_entities'; +import { generateLatestMetadataAggregations } from './generate_metadata_aggregations'; +import { generateLatestIngestPipelineId } from '../ingest_pipeline/generate_latest_ingest_pipeline_id'; +import { generateLatestTransformId } from './generate_latest_transform_id'; +import { generateHistoryIndexName } from '../helpers/generate_index_name'; +import { generateLatestMetricAggregations } from './generate_metric_aggregations'; + +export function generateLatestTransform( + definition: EntityDefinition +): TransformPutTransformRequest { + return { + transform_id: generateLatestTransformId(definition), + defer_validation: true, + source: { + index: `${generateHistoryIndexName(definition)}.*`, + }, + dest: { + index: `${ENTITY_LATEST_BASE_PREFIX}.noop`, + pipeline: generateLatestIngestPipelineId(definition), + }, + frequency: definition.latest?.settings?.frequency ?? ENTITY_DEFAULT_LATEST_FREQUENCY, + sync: { + time: { + field: definition.latest?.settings?.syncField ?? 'event.ingested', + delay: definition.latest?.settings?.syncDelay ?? ENTITY_DEFAULT_LATEST_SYNC_DELAY, + }, + }, + settings: { + deduce_mappings: false, + unattended: true, + }, + pivot: { + group_by: { + ['entity.id']: { + terms: { field: 'entity.id' }, + }, + ['entity.displayName']: { + terms: { field: 'entity.displayName.keyword' }, + }, + ...definition.identityFields.reduce( + (acc, id) => ({ + ...acc, + [`entity.identityFields.${id.field}`]: { + terms: { field: `entity.identityFields.${id.field}`, missing_bucket: id.optional }, + }, + }), + {} + ), + }, + aggs: { + ...generateLatestMetricAggregations(definition), + ...generateLatestMetadataAggregations(definition), + 'entity.lastSeenTimestamp': { + max: { + field: 'entity.lastSeenTimestamp', + }, + }, + 'entity.firstSeenTimestamp': { + min: { + field: '@timestamp', + }, + }, + }, + }, + }; +} diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform_id.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform_id.ts new file mode 100644 index 0000000000000..1aefc24e5ee2f --- /dev/null +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_latest_transform_id.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EntityDefinition } from '@kbn/entities-schema'; +import { ENTITY_LATEST_TRANSFORM_PREFIX } from '../../../../common/constants_entities'; + +export function generateLatestTransformId(definition: EntityDefinition) { + return `${ENTITY_LATEST_TRANSFORM_PREFIX}-${definition.id}`; +} diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metadata_aggregations.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metadata_aggregations.ts index 8c11aea138519..31ba3e9add0dc 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metadata_aggregations.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metadata_aggregations.ts @@ -6,8 +6,9 @@ */ import { EntityDefinition } from '@kbn/entities-schema'; +import { ENTITY_DEFAULT_METADATA_LIMIT } from '../../../../common/constants_entities'; -export function generateMetadataAggregations(definition: EntityDefinition) { +export function generateHistoryMetadataAggregations(definition: EntityDefinition) { if (!definition.metadata) { return {}; } @@ -17,7 +18,37 @@ export function generateMetadataAggregations(definition: EntityDefinition) { [`entity.metadata.${metadata.destination ?? metadata.source}`]: { terms: { field: metadata.source, - size: metadata.limit ?? 1000, + size: metadata.limit ?? ENTITY_DEFAULT_METADATA_LIMIT, + }, + }, + }), + {} + ); +} + +export function generateLatestMetadataAggregations(definition: EntityDefinition) { + if (!definition.metadata) { + return {}; + } + + return definition.metadata.reduce( + (aggs, metadata) => ({ + ...aggs, + [`entity.metadata.${metadata.destination}`]: { + filter: { + range: { + 'event.ingested': { + gte: `now-${definition.history.interval.toJSON()}`, + }, + }, + }, + aggs: { + data: { + terms: { + field: metadata.destination ?? metadata.source, + size: metadata.limit ?? ENTITY_DEFAULT_METADATA_LIMIT, + }, + }, }, }, }), diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metric_aggregations.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metric_aggregations.ts index 9527671768e35..bd1af365116cb 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metric_aggregations.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_metric_aggregations.ts @@ -104,15 +104,41 @@ function buildMetricEquation(keyMetric: KeyMetric) { }; } -export function generateMetricAggregations(definition: EntityDefinition) { +export function generateHistoryMetricAggregations(definition: EntityDefinition) { if (!definition.metrics) { return {}; } return definition.metrics.reduce((aggs, keyMetric) => { return { ...aggs, - ...buildMetricAggregations(keyMetric, definition.timestampField), - [`entity.metric.${keyMetric.name}`]: buildMetricEquation(keyMetric), + ...buildMetricAggregations(keyMetric, definition.history.timestampField), + [`entity.metrics.${keyMetric.name}`]: buildMetricEquation(keyMetric), + }; + }, {}); +} + +export function generateLatestMetricAggregations(definition: EntityDefinition) { + if (!definition.metrics) { + return {}; + } + + return definition.metrics.reduce((aggs, keyMetric) => { + return { + ...aggs, + [`_${keyMetric.name}`]: { + top_metrics: { + metrics: [{ field: `entity.metrics.${keyMetric.name}` }], + sort: [{ '@timestamp': 'desc' }], + }, + }, + [`entity.metrics.${keyMetric.name}`]: { + bucket_script: { + buckets_path: { + value: `_${keyMetric.name}[entity.metrics.${keyMetric.name}]`, + }, + script: 'params.value', + }, + }, }; }, {}); } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform.ts b/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform.ts deleted file mode 100644 index 6a8c0bd637715..0000000000000 --- a/x-pack/plugins/observability_solution/asset_manager/server/lib/entities/transform/generate_transform.ts +++ /dev/null @@ -1,86 +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 { EntityDefinition } from '@kbn/entities-schema'; -import { - QueryDslQueryContainer, - TransformPutTransformRequest, -} from '@elastic/elasticsearch/lib/api/types'; -import { getElasticsearchQueryOrThrow } from '../helpers/get_elasticsearch_query_or_throw'; -import { generateMetricAggregations } from './generate_metric_aggregations'; -import { - ENTITY_BASE_PREFIX, - ENTITY_DEFAULT_FREQUENCY, - ENTITY_DEFAULT_SYNC_DELAY, -} from '../../../../common/constants_entities'; -import { generateMetadataAggregations } from './generate_metadata_aggregations'; -import { generateTransformId } from './generate_transform_id'; -import { generateIngestPipelineId } from '../ingest_pipeline/generate_ingest_pipeline_id'; - -export function generateTransform(definition: EntityDefinition): TransformPutTransformRequest { - const filter: QueryDslQueryContainer[] = [ - { - range: { - [definition.timestampField]: { - gte: `now-${definition.lookback.toJSON()}`, - }, - }, - }, - ]; - - if (definition.filter) { - filter.push(getElasticsearchQueryOrThrow(definition.filter)); - } - - return { - transform_id: generateTransformId(definition), - defer_validation: true, - source: { - index: definition.indexPatterns, - query: { - bool: { - filter, - }, - }, - }, - dest: { - index: `${ENTITY_BASE_PREFIX}.noop`, - pipeline: generateIngestPipelineId(definition), - }, - frequency: definition.settings?.frequency || ENTITY_DEFAULT_FREQUENCY, - sync: { - time: { - field: definition.settings?.syncField ?? definition.timestampField, - delay: definition.settings?.syncDelay ?? ENTITY_DEFAULT_SYNC_DELAY, - }, - }, - settings: { - deduce_mappings: false, - unattended: true, - }, - pivot: { - group_by: definition.identityFields.reduce( - (acc, id) => ({ - ...acc, - [`entity.identity.${id.field}`]: { - terms: { field: id.field, missing_bucket: id.optional }, - }, - }), - {} - ), - aggs: { - ...generateMetricAggregations(definition), - ...generateMetadataAggregations(definition), - 'entity.latestTimestamp': { - max: { - field: definition.timestampField, - }, - }, - }, - }, - }; -} diff --git a/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/create.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/create.ts index 69ea6394ecb94..09d49c35bcef3 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/create.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/create.ts @@ -10,16 +10,28 @@ import { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema'; import { stringifyZodError } from '@kbn/zod-helpers'; import { SetupRouteOptions } from '../types'; import { saveEntityDefinition } from '../../lib/entities/save_entity_definition'; -import { createAndInstallIngestPipeline } from '../../lib/entities/create_and_install_ingest_pipeline'; +import { + createAndInstallHistoryIngestPipeline, + createAndInstallLatestIngestPipeline, +} from '../../lib/entities/create_and_install_ingest_pipeline'; import { EntityIdConflict } from '../../lib/entities/errors/entity_id_conflict_error'; -import { createAndInstallTransform } from '../../lib/entities/create_and_install_transform'; import { EntitySecurityException } from '../../lib/entities/errors/entity_security_exception'; import { InvalidTransformError } from '../../lib/entities/errors/invalid_transform_error'; import { startTransform } from '../../lib/entities/start_transform'; import { deleteEntityDefinition } from '../../lib/entities/delete_entity_definition'; -import { deleteIngestPipeline } from '../../lib/entities/delete_ingest_pipeline'; -import { stopAndDeleteTransform } from '../../lib/entities/stop_and_delete_transform'; -import { ENTITY_API_PREFIX } from '../../../common/constants_entities'; +import { + deleteHistoryIngestPipeline, + deleteLatestIngestPipeline, +} from '../../lib/entities/delete_ingest_pipeline'; +import { + stopAndDeleteHistoryTransform, + stopAndDeleteLatestTransform, +} from '../../lib/entities/stop_and_delete_transform'; +import { ENTITY_INTERNAL_API_PREFIX } from '../../../common/constants_entities'; +import { + createAndInstallHistoryTransform, + createAndInstallLatestTransform, +} from '../../lib/entities/create_and_install_transform'; export function createEntityDefinitionRoute({ router, @@ -28,7 +40,7 @@ export function createEntityDefinitionRoute({ }: SetupRouteOptions) { router.post( { - path: `${ENTITY_API_PREFIX}/definition`, + path: `${ENTITY_INTERNAL_API_PREFIX}/definition`, validate: { body: (body, res) => { try { @@ -40,35 +52,60 @@ export function createEntityDefinitionRoute({ }, }, async (context, req, res) => { - let definitionCreated = false; - let ingestPipelineCreated = false; - let transformCreated = false; + const installState = { + ingestPipelines: { + history: false, + latest: false, + }, + transforms: { + history: false, + latest: false, + }, + definition: false, + }; const core = await context.core; const soClient = core.savedObjects.client; const esClient = core.elasticsearch.client.asCurrentUser; const spaceId = spaces?.spacesService.getSpaceId(req) ?? 'default'; - try { const definition = await saveEntityDefinition(soClient, req.body); - definitionCreated = true; - await createAndInstallIngestPipeline(esClient, definition, logger, spaceId); - ingestPipelineCreated = true; - await createAndInstallTransform(esClient, definition, logger); - transformCreated = true; + installState.definition = true; + + // install ingest pipelines + await createAndInstallHistoryIngestPipeline(esClient, definition, logger, spaceId); + installState.ingestPipelines.history = true; + await createAndInstallLatestIngestPipeline(esClient, definition, logger, spaceId); + installState.ingestPipelines.latest = true; + + // install transfroms + await createAndInstallHistoryTransform(esClient, definition, logger); + installState.transforms.history = true; + await createAndInstallLatestTransform(esClient, definition, logger); + installState.transforms.latest = true; + await startTransform(esClient, definition, logger); return res.ok({ body: definition }); } catch (e) { // Clean up anything that was successful. - if (definitionCreated) { + if (installState.definition) { await deleteEntityDefinition(soClient, req.body, logger); } - if (ingestPipelineCreated) { - await deleteIngestPipeline(esClient, req.body, logger); + + if (installState.ingestPipelines.history) { + await deleteHistoryIngestPipeline(esClient, req.body, logger); + } + if (installState.ingestPipelines.latest) { + await deleteLatestIngestPipeline(esClient, req.body, logger); } - if (transformCreated) { - await stopAndDeleteTransform(esClient, req.body, logger); + + if (installState.transforms.history) { + await stopAndDeleteHistoryTransform(esClient, req.body, logger); } + if (installState.transforms.latest) { + await stopAndDeleteLatestTransform(esClient, req.body, logger); + } + if (e instanceof EntityIdConflict) { return res.conflict({ body: e }); } diff --git a/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/delete.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/delete.ts index e1b273780a64f..7c9044d24cd82 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/delete.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/delete.ts @@ -11,11 +11,17 @@ import { SetupRouteOptions } from '../types'; import { EntitySecurityException } from '../../lib/entities/errors/entity_security_exception'; import { InvalidTransformError } from '../../lib/entities/errors/invalid_transform_error'; import { readEntityDefinition } from '../../lib/entities/read_entity_definition'; -import { stopAndDeleteTransform } from '../../lib/entities/stop_and_delete_transform'; -import { deleteIngestPipeline } from '../../lib/entities/delete_ingest_pipeline'; +import { + stopAndDeleteHistoryTransform, + stopAndDeleteLatestTransform, +} from '../../lib/entities/stop_and_delete_transform'; +import { + deleteHistoryIngestPipeline, + deleteLatestIngestPipeline, +} from '../../lib/entities/delete_ingest_pipeline'; import { deleteEntityDefinition } from '../../lib/entities/delete_entity_definition'; import { EntityDefinitionNotFound } from '../../lib/entities/errors/entity_not_found'; -import { ENTITY_API_PREFIX } from '../../../common/constants_entities'; +import { ENTITY_INTERNAL_API_PREFIX } from '../../../common/constants_entities'; export function deleteEntityDefinitionRoute({ router, @@ -23,7 +29,7 @@ export function deleteEntityDefinitionRoute({ }: SetupRouteOptions) { router.delete<{ id: string }, unknown, unknown>( { - path: `${ENTITY_API_PREFIX}/definition/{id}`, + path: `${ENTITY_INTERNAL_API_PREFIX}/definition/{id}`, validate: { params: schema.object({ id: schema.string(), @@ -36,8 +42,10 @@ export function deleteEntityDefinitionRoute({ const esClient = (await context.core).elasticsearch.client.asCurrentUser; const definition = await readEntityDefinition(soClient, req.params.id, logger); - await stopAndDeleteTransform(esClient, definition, logger); - await deleteIngestPipeline(esClient, definition, logger); + await stopAndDeleteHistoryTransform(esClient, definition, logger); + await stopAndDeleteLatestTransform(esClient, definition, logger); + await deleteHistoryIngestPipeline(esClient, definition, logger); + await deleteLatestIngestPipeline(esClient, definition, logger); await deleteEntityDefinition(soClient, definition, logger); return res.ok({ body: { acknowledged: true } }); diff --git a/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/reset.ts b/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/reset.ts index ffe53fee63577..2a267c6c4e332 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/reset.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/routes/entities/reset.ts @@ -11,14 +11,26 @@ import { SetupRouteOptions } from '../types'; import { EntitySecurityException } from '../../lib/entities/errors/entity_security_exception'; import { InvalidTransformError } from '../../lib/entities/errors/invalid_transform_error'; import { readEntityDefinition } from '../../lib/entities/read_entity_definition'; -import { stopAndDeleteTransform } from '../../lib/entities/stop_and_delete_transform'; -import { deleteIngestPipeline } from '../../lib/entities/delete_ingest_pipeline'; -import { deleteIndex } from '../../lib/entities/delete_index'; -import { createAndInstallIngestPipeline } from '../../lib/entities/create_and_install_ingest_pipeline'; -import { createAndInstallTransform } from '../../lib/entities/create_and_install_transform'; +import { + stopAndDeleteHistoryTransform, + stopAndDeleteLatestTransform, +} from '../../lib/entities/stop_and_delete_transform'; +import { + deleteHistoryIngestPipeline, + deleteLatestIngestPipeline, +} from '../../lib/entities/delete_ingest_pipeline'; +import { deleteIndices } from '../../lib/entities/delete_index'; +import { + createAndInstallHistoryIngestPipeline, + createAndInstallLatestIngestPipeline, +} from '../../lib/entities/create_and_install_ingest_pipeline'; +import { + createAndInstallHistoryTransform, + createAndInstallLatestTransform, +} from '../../lib/entities/create_and_install_transform'; import { startTransform } from '../../lib/entities/start_transform'; import { EntityDefinitionNotFound } from '../../lib/entities/errors/entity_not_found'; -import { ENTITY_API_PREFIX } from '../../../common/constants_entities'; +import { ENTITY_INTERNAL_API_PREFIX } from '../../../common/constants_entities'; export function resetEntityDefinitionRoute({ router, @@ -27,7 +39,7 @@ export function resetEntityDefinitionRoute({ }: SetupRouteOptions) { router.post<{ id: string }, unknown, unknown>( { - path: `${ENTITY_API_PREFIX}/definition/{id}/_reset`, + path: `${ENTITY_INTERNAL_API_PREFIX}/definition/{id}/_reset`, validate: { params: schema.object({ id: schema.string(), @@ -43,13 +55,17 @@ export function resetEntityDefinitionRoute({ const definition = await readEntityDefinition(soClient, req.params.id, logger); // Delete the transform and ingest pipeline - await stopAndDeleteTransform(esClient, definition, logger); - await deleteIngestPipeline(esClient, definition, logger); - await deleteIndex(esClient, definition, logger); + await stopAndDeleteHistoryTransform(esClient, definition, logger); + await stopAndDeleteLatestTransform(esClient, definition, logger); + await deleteHistoryIngestPipeline(esClient, definition, logger); + await deleteLatestIngestPipeline(esClient, definition, logger); + await deleteIndices(esClient, definition, logger); // Recreate everything - await createAndInstallIngestPipeline(esClient, definition, logger, spaceId); - await createAndInstallTransform(esClient, definition, logger); + await createAndInstallHistoryIngestPipeline(esClient, definition, logger, spaceId); + await createAndInstallLatestIngestPipeline(esClient, definition, logger, spaceId); + await createAndInstallHistoryTransform(esClient, definition, logger); + await createAndInstallLatestTransform(esClient, definition, logger); await startTransform(esClient, definition, logger); return res.ok({ body: { acknowledged: true } }); diff --git a/x-pack/plugins/observability_solution/asset_manager/server/saved_objects/entity_definition.ts b/x-pack/plugins/observability_solution/asset_manager/server/saved_objects/entity_definition.ts index 5a63444974ad7..392be5a0722be 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/saved_objects/entity_definition.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/saved_objects/entity_definition.ts @@ -24,7 +24,6 @@ export const entityDefinition: SavedObjectsType = { filter: { type: 'keyword' }, indexPatterns: { type: 'keyword' }, identityFields: { type: 'object' }, - categories: { type: 'keyword' }, metadata: { type: 'object' }, metrics: { type: 'object' }, staticFields: { type: 'object' }, diff --git a/x-pack/plugins/observability_solution/asset_manager/server/templates/components/entity.ts b/x-pack/plugins/observability_solution/asset_manager/server/templates/components/entity.ts index 01528453c74d4..56a0ea3333309 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/templates/components/entity.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/templates/components/entity.ts @@ -21,15 +21,23 @@ export const entitiesEntityComponentTemplateConfig: ClusterPutComponentTemplateR ignore_above: 1024, type: 'keyword', }, - indexPatterns: { - ignore_above: 1024, - type: 'keyword', + displayName: { + type: 'text', + fields: { + keyword: { + ignore_above: 1024, + type: 'keyword', + }, + }, }, definitionId: { ignore_above: 1024, type: 'keyword', }, - latestTimestamp: { + lastSeenTimestamp: { + type: 'date', + }, + firstSeenTimestamp: { type: 'date', }, }, diff --git a/x-pack/plugins/observability_solution/asset_manager/server/templates/entities_template.ts b/x-pack/plugins/observability_solution/asset_manager/server/templates/entities_template.ts index d3934b24ea82c..f7d66a0b2a731 100644 --- a/x-pack/plugins/observability_solution/asset_manager/server/templates/entities_template.ts +++ b/x-pack/plugins/observability_solution/asset_manager/server/templates/entities_template.ts @@ -29,6 +29,11 @@ export const entitiesIndexTemplateConfig: IndicesPutIndexTemplateRequest = { mapping: { ignore_above: 1024, type: 'keyword', + fields: { + text: { + type: 'text', + }, + }, }, match_mapping_type: 'string', }, @@ -41,7 +46,7 @@ export const entitiesIndexTemplateConfig: IndicesPutIndexTemplateRequest = { }, // @ts-expect-error this should work per: https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-templates.html#match-mapping-type match_mapping_type: ['long', 'double'], - path_match: 'entity.metric.*', + path_match: 'entity.metrics.*', }, }, ], From e4326522a2ab311a62dc0226510703afb166ec7d Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Wed, 5 Jun 2024 16:59:23 +0200 Subject: [PATCH 004/122] [CI] Add docs link to deployment secrets (#184779) ## Summary Adds some messaging to direct developers toward the prod-ci vault, plus CI docs links. Also, removes branching that were added for the duration of the migration. Since the PR build pipelines that are using these are migrated, only one branch was active. --- .../scripts/steps/cloud/build_and_deploy.sh | 31 ++++++------------- .buildkite/scripts/steps/serverless/deploy.sh | 22 +++---------- 2 files changed, 13 insertions(+), 40 deletions(-) diff --git a/.buildkite/scripts/steps/cloud/build_and_deploy.sh b/.buildkite/scripts/steps/cloud/build_and_deploy.sh index 8c5e0a0d2c635..1287d0f0328c3 100755 --- a/.buildkite/scripts/steps/cloud/build_and_deploy.sh +++ b/.buildkite/scripts/steps/cloud/build_and_deploy.sh @@ -82,16 +82,7 @@ if [ -z "${CLOUD_DEPLOYMENT_ID}" ] || [ "${CLOUD_DEPLOYMENT_ID}" = 'null' ]; the echo "Writing to vault..." - # TODO: remove after https://github.com/elastic/kibana-operations/issues/15 is done - if [[ "$IS_LEGACY_VAULT_ADDR" == "true" ]]; then - VAULT_ROLE_ID="$(get_vault_role_id)" - VAULT_SECRET_ID="$(get_vault_secret_id)" - VAULT_TOKEN=$(retry 5 30 vault write -field=token auth/approle/login role_id="$VAULT_ROLE_ID" secret_id="$VAULT_SECRET_ID") - retry 5 30 vault login -no-print "$VAULT_TOKEN" - vault_set "cloud-deploy/$CLOUD_DEPLOYMENT_NAME" username="$CLOUD_DEPLOYMENT_USERNAME" password="$CLOUD_DEPLOYMENT_PASSWORD" - else - vault_kv_set "cloud-deploy/$CLOUD_DEPLOYMENT_NAME" username="$CLOUD_DEPLOYMENT_USERNAME" password="$CLOUD_DEPLOYMENT_PASSWORD" - fi + vault_kv_set "cloud-deploy/$CLOUD_DEPLOYMENT_NAME" username="$CLOUD_DEPLOYMENT_USERNAME" password="$CLOUD_DEPLOYMENT_PASSWORD" echo "Enabling Stack Monitoring..." jq ' @@ -123,28 +114,24 @@ else ecctl deployment update "$CLOUD_DEPLOYMENT_ID" --track --output json --file /tmp/deploy.json > "$ECCTL_LOGS" fi -# TODO: remove after https://github.com/elastic/kibana-operations/issues/15 is done -if [[ "$IS_LEGACY_VAULT_ADDR" == "true" ]]; then - VAULT_READ_COMMAND="vault read $VAULT_PATH_PREFIX/cloud-deploy/$CLOUD_DEPLOYMENT_NAME" -else - VAULT_READ_COMMAND="vault kv get $VAULT_KV_PREFIX/cloud-deploy/$CLOUD_DEPLOYMENT_NAME" -fi CLOUD_DEPLOYMENT_KIBANA_URL=$(ecctl deployment show "$CLOUD_DEPLOYMENT_ID" | jq -r '.resources.kibana[0].info.metadata.aliased_url') CLOUD_DEPLOYMENT_ELASTICSEARCH_URL=$(ecctl deployment show "$CLOUD_DEPLOYMENT_ID" | jq -r '.resources.elasticsearch[0].info.metadata.aliased_url') cat << EOF | buildkite-agent annotate --style "info" --context cloud - ### Cloud Deployment +### Cloud Deployment + +Kibana: $CLOUD_DEPLOYMENT_KIBANA_URL - Kibana: $CLOUD_DEPLOYMENT_KIBANA_URL +Elasticsearch: $CLOUD_DEPLOYMENT_ELASTICSEARCH_URL - Elasticsearch: $CLOUD_DEPLOYMENT_ELASTICSEARCH_URL +Credentials: \`vault kv get $VAULT_KV_PREFIX/cloud-deploy/$CLOUD_DEPLOYMENT_NAME\` - Credentials: \`$VAULT_READ_COMMAND\` +(Stored in the production vault: VAULT_ADDR=https://vault-ci-prod.elastic.dev, more info: https://docs.elastic.dev/ci/using-secrets) - Kibana image: \`$KIBANA_CLOUD_IMAGE\` +Kibana image: \`$KIBANA_CLOUD_IMAGE\` - Elasticsearch image: \`$ELASTICSEARCH_CLOUD_IMAGE\` +Elasticsearch image: \`$ELASTICSEARCH_CLOUD_IMAGE\` EOF buildkite-agent meta-data set pr_comment:deploy_cloud:head "* [Cloud Deployment](${CLOUD_DEPLOYMENT_KIBANA_URL})" diff --git a/.buildkite/scripts/steps/serverless/deploy.sh b/.buildkite/scripts/steps/serverless/deploy.sh index 5accef8f53797..e67795fcbf65d 100644 --- a/.buildkite/scripts/steps/serverless/deploy.sh +++ b/.buildkite/scripts/steps/serverless/deploy.sh @@ -88,16 +88,7 @@ deploy() { echo "Write to vault..." - # TODO: remove after https://github.com/elastic/kibana-operations/issues/15 is done - if [[ "$IS_LEGACY_VAULT_ADDR" == "true" ]]; then - VAULT_ROLE_ID="$(get_vault_role_id)" - VAULT_SECRET_ID="$(get_vault_secret_id)" - VAULT_TOKEN=$(retry 5 30 vault write -field=token auth/approle/login role_id="$VAULT_ROLE_ID" secret_id="$VAULT_SECRET_ID") - retry 5 30 vault login -no-print "$VAULT_TOKEN" - vault_set "cloud-deploy/$VAULT_KEY_NAME" username="$PROJECT_USERNAME" password="$PROJECT_PASSWORD" id="$PROJECT_ID" - else - vault_kv_set "cloud-deploy/$VAULT_KEY_NAME" username="$PROJECT_USERNAME" password="$PROJECT_PASSWORD" id="$PROJECT_ID" - fi + vault_kv_set "cloud-deploy/$VAULT_KEY_NAME" username="$PROJECT_USERNAME" password="$PROJECT_PASSWORD" id="$PROJECT_ID" else echo "Updating project..." @@ -118,13 +109,6 @@ deploy() { PROJECT_KIBANA_LOGIN_URL="${PROJECT_KIBANA_URL}/login" PROJECT_ELASTICSEARCH_URL=$(jq -r '.endpoints.elasticsearch' $PROJECT_INFO_LOGS) - # TODO: remove after https://github.com/elastic/kibana-operations/issues/15 is done - if [[ "$IS_LEGACY_VAULT_ADDR" == "true" ]]; then - VAULT_READ_COMMAND="vault read $VAULT_PATH_PREFIX/cloud-deploy/$VAULT_KEY_NAME" - else - VAULT_READ_COMMAND="vault kv get $VAULT_KV_PREFIX/cloud-deploy/$VAULT_KEY_NAME" - fi - cat << EOF | buildkite-agent annotate --style "info" --context "project-$PROJECT_TYPE" ### $PROJECT_TYPE_LABEL Deployment @@ -132,7 +116,9 @@ Kibana: $PROJECT_KIBANA_LOGIN_URL Elasticsearch: $PROJECT_ELASTICSEARCH_URL -Credentials: \`$VAULT_READ_COMMAND\` +Credentials: \`vault kv get $VAULT_KV_PREFIX/cloud-deploy/$VAULT_KEY_NAME\` + +(Stored in the production vault: VAULT_ADDR=https://vault-ci-prod.elastic.dev, more info: https://docs.elastic.dev/ci/using-secrets) Kibana image: \`$KIBANA_IMAGE\` EOF From db3f866a0d77b168a90435daec9d8d4756a4a4c0 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 5 Jun 2024 16:06:18 +0100 Subject: [PATCH 005/122] skip flaky suite (#184619) --- .../monitoring_api_integration/apis/elasticsearch/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/monitoring_api_integration/apis/elasticsearch/index.ts b/x-pack/test/monitoring_api_integration/apis/elasticsearch/index.ts index cfcb7bf5570aa..2ed2b6c35bd26 100644 --- a/x-pack/test/monitoring_api_integration/apis/elasticsearch/index.ts +++ b/x-pack/test/monitoring_api_integration/apis/elasticsearch/index.ts @@ -9,7 +9,8 @@ import { FtrProviderContext } from '../../../api_integration/ftr_provider_contex import { installPackage } from '../../packages'; export default function ({ loadTestFile, getService }: FtrProviderContext) { - describe('Elasticsearch', () => { + // FLAKY: https://github.com/elastic/kibana/issues/184619 + describe.skip('Elasticsearch', () => { before(() => installPackage(getService('supertest'), 'elasticsearch')); loadTestFile(require.resolve('./ccr')); From ab6ecdb3a5f6ec1df45668982987cdd236441563 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Wed, 5 Jun 2024 17:10:00 +0200 Subject: [PATCH 006/122] [CI] Fix inverted DRY_RUN behaviour (#184841) ## Summary We added this check in https://github.com/elastic/kibana/pull/177736 but we haven't really tested it in action, it looks like we had the dry-run behaviour inverted. --- .../emergency_release/trigger_container_build.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.buildkite/scripts/serverless/emergency_release/trigger_container_build.ts b/.buildkite/scripts/serverless/emergency_release/trigger_container_build.ts index daf7c904ffd46..c45fb75b5823f 100644 --- a/.buildkite/scripts/serverless/emergency_release/trigger_container_build.ts +++ b/.buildkite/scripts/serverless/emergency_release/trigger_container_build.ts @@ -16,16 +16,16 @@ async function main() { const commitSha = process.env.OVERRIDE_COMMIT || process.env.BUILDKITE_COMMIT; if (!isCurrentHeadInMain(commitSha!)) { - if (!DRY_RUN) { + if (DRY_RUN) { console.log( `DRY_RUN: Commit ${commitSha} isn't in main, triggering container build :green_heart:` ); } else { console.log(`Commit ${commitSha} isn't in main, triggering container build :green_heart:`); - uploadTriggerBuildStep(); + uploadTriggerBuildStep(commitSha!); } } else { - if (!DRY_RUN) { + if (DRY_RUN) { console.log(`DRY_RUN: Commit ${commitSha} is in main, no build necessary :yellow_heart:`); } else { console.log(`Commit ${commitSha} is in main, no trigger necessary :yellow_heart:`); @@ -41,12 +41,14 @@ function isCurrentHeadInMain(commitSha: string) { return parseInt(containmentTest, 10) >= 1; } -function uploadTriggerBuildStep() { +function uploadTriggerBuildStep(commitSha: string) { const triggerStep: BuildkiteTriggerStep = { label: ':point_right: Trigger emergency commit container build', trigger: 'kibana-artifacts-container-image', build: { message: `Triggered by '${process.env.BUILDKITE_PIPELINE_NAME || 'unknown'}'`, + branch: process.env?.BUILDKITE_BRANCH || 'main', + commit: commitSha, env: {}, }, }; From 1836f6e63612bbe4a8a6f17c91e2ee115fbdfe14 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 5 Jun 2024 12:52:11 -0400 Subject: [PATCH 007/122] =?UTF-8?q?[Fleet]=20Write=20space=20aware=20.flee?= =?UTF-8?q?t-policies=20and=20.fleet-enrollment-token=E2=80=A6=20(#184676)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fleet/common/types/models/agent_policy.ts | 2 + .../server/routes/download_source/handler.ts | 10 +- .../server/routes/fleet_proxies/handler.ts | 16 +- .../routes/fleet_server_hosts/handler.ts | 6 +- .../fleet/server/routes/output/handler.ts | 6 +- .../fleet/server/routes/settings/index.ts | 2 +- .../fleet/server/saved_objects/index.ts | 2 +- .../agent_policies/full_agent_policy.ts | 5 +- .../server/services/agent_policies/utils.ts | 29 +- .../server/services/agent_policy.test.ts | 47 ++-- .../fleet/server/services/agent_policy.ts | 253 ++++++++++-------- .../server/services/agent_policy_update.ts | 13 +- .../api_keys/enrollment_api_key.test.ts | 34 +++ .../services/api_keys/enrollment_api_key.ts | 16 +- .../fleet/server/services/app_context.ts | 33 ++- .../plugins/fleet/server/services/output.ts | 2 +- .../server/services/preconfiguration.test.ts | 26 +- .../fleet/server/services/preconfiguration.ts | 3 +- .../preconfiguration/fleet_proxies.ts | 6 +- .../preconfiguration/fleet_server_host.ts | 4 +- .../services/preconfiguration/outputs.test.ts | 31 +-- .../services/preconfiguration/outputs.ts | 4 +- x-pack/plugins/fleet/tsconfig.json | 1 + .../apis/agent_policy/agent_policy.ts | 10 +- .../agent_policy_with_agents_setup.ts | 135 +++++++--- .../apis/outputs/crud.ts | 87 ++++++ 26 files changed, 513 insertions(+), 270 deletions(-) diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts index c697edae904b3..082296fd75e11 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -53,6 +53,7 @@ export interface GlobalDataTag { // SO definition for this type is declared in server/types/interfaces export interface AgentPolicy extends Omit { id: string; + space_id?: string | undefined; status: ValueOf; package_policies?: PackagePolicy[]; is_managed: boolean; // required for created policy @@ -120,6 +121,7 @@ export interface FullAgentPolicyMonitoring { export interface FullAgentPolicy { id: string; + namespaces?: string[]; outputs: { [key: string]: FullAgentPolicyOutput; }; diff --git a/x-pack/plugins/fleet/server/routes/download_source/handler.ts b/x-pack/plugins/fleet/server/routes/download_source/handler.ts index b82c3ad19de55..8807106de441e 100644 --- a/x-pack/plugins/fleet/server/routes/download_source/handler.ts +++ b/x-pack/plugins/fleet/server/routes/download_source/handler.ts @@ -77,13 +77,9 @@ export const putDownloadSourcesHandler: RequestHandler< await downloadSourceService.update(soClient, request.params.sourceId, request.body); const downloadSource = await downloadSourceService.get(soClient, request.params.sourceId); if (downloadSource.is_default) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } else { - await agentPolicyService.bumpAllAgentPoliciesForDownloadSource( - soClient, - esClient, - downloadSource.id - ); + await agentPolicyService.bumpAllAgentPoliciesForDownloadSource(esClient, downloadSource.id); } const body: PutDownloadSourceResponse = { @@ -114,7 +110,7 @@ export const postDownloadSourcesHandler: RequestHandler< const { id, ...data } = request.body; const downloadSource = await downloadSourceService.create(soClient, data, { id }); if (downloadSource.is_default) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } const body: GetOneDownloadSourceResponse = { diff --git a/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts b/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts index b636ebb53a9eb..a5905f406a6e7 100644 --- a/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts +++ b/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts @@ -44,11 +44,11 @@ async function bumpRelatedPolicies( fleetServerHosts.some((host) => host.is_default) || outputs.some((output) => output.is_default || output.is_default_monitoring) ) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } else { await pMap( outputs, - (output) => agentPolicyService.bumpAllAgentPoliciesForOutput(soClient, esClient, output.id), + (output) => agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, output.id), { concurrency: 20, } @@ -56,11 +56,7 @@ async function bumpRelatedPolicies( await pMap( fleetServerHosts, (fleetServerHost) => - agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts( - soClient, - esClient, - fleetServerHost.id - ), + agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts(esClient, fleetServerHost.id), { concurrency: 20, } @@ -69,11 +65,7 @@ async function bumpRelatedPolicies( await pMap( downloadSources, (downloadSource) => - agentPolicyService.bumpAllAgentPoliciesForDownloadSource( - soClient, - esClient, - downloadSource.id - ), + agentPolicyService.bumpAllAgentPoliciesForDownloadSource(esClient, downloadSource.id), { concurrency: 20, } diff --git a/x-pack/plugins/fleet/server/routes/fleet_server_hosts/handler.ts b/x-pack/plugins/fleet/server/routes/fleet_server_hosts/handler.ts index 3a67ac5758cc5..f7159e6b5f498 100644 --- a/x-pack/plugins/fleet/server/routes/fleet_server_hosts/handler.ts +++ b/x-pack/plugins/fleet/server/routes/fleet_server_hosts/handler.ts @@ -69,7 +69,7 @@ export const postFleetServerHost: RequestHandler< { id } ); if (FleetServerHost.is_default) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } const body = { @@ -150,9 +150,9 @@ export const putFleetServerHostHandler: RequestHandler< }; if (item.is_default) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } else { - await agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts(soClient, esClient, item.id); + await agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts(esClient, item.id); } return response.ok({ body }); diff --git a/x-pack/plugins/fleet/server/routes/output/handler.ts b/x-pack/plugins/fleet/server/routes/output/handler.ts index a1cb04b9026c0..b35158637d151 100644 --- a/x-pack/plugins/fleet/server/routes/output/handler.ts +++ b/x-pack/plugins/fleet/server/routes/output/handler.ts @@ -109,9 +109,9 @@ export const putOutputHandler: RequestHandler< await outputService.update(soClient, esClient, request.params.outputId, outputUpdate); const output = await outputService.get(soClient, request.params.outputId); if (output.is_default || output.is_default_monitoring) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } else { - await agentPolicyService.bumpAllAgentPoliciesForOutput(soClient, esClient, output.id); + await agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, output.id); } const body: GetOneOutputResponse = { @@ -144,7 +144,7 @@ export const postOutputHandler: RequestHandler< ensureNoDuplicateSecrets(newOutput); const output = await outputService.create(soClient, esClient, newOutput, { id }); if (output.is_default || output.is_default_monitoring) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } const body: GetOneOutputResponse = { diff --git a/x-pack/plugins/fleet/server/routes/settings/index.ts b/x-pack/plugins/fleet/server/routes/settings/index.ts index 6a814eae0f801..d8d8aee742c9a 100644 --- a/x-pack/plugins/fleet/server/routes/settings/index.ts +++ b/x-pack/plugins/fleet/server/routes/settings/index.ts @@ -53,7 +53,7 @@ export const putSettingsHandler: FleetRequestHandler< try { const settings = await settingsService.saveSettings(soClient, request.body); - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient, { + await agentPolicyService.bumpAllAgentPolicies(esClient, { user: user || undefined, }); const body = { diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index ad958bc986d00..fa8d8881f33d0 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -742,7 +742,7 @@ export const getSavedObjectTypes = ( name: DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, indexPattern: INGEST_SAVED_OBJECT_INDEX, hidden: false, - namespaceType: useSpaceAwareness ? 'single' : 'agnostic', + namespaceType: 'agnostic', management: { importableAndExportable: false, }, diff --git a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts index bcc6956711b64..b8e64be494651 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts @@ -85,7 +85,6 @@ export async function getFullAgentPolicy( downloadSourceUri, downloadSourceProxyUri, } = await fetchRelatedSavedObjects(soClient, agentPolicy); - // Build up an in-memory object for looking up Package Info, so we don't have // call `getPackageInfo` for every single policy, which incurs performance costs const packageInfoCache = new Map(); @@ -193,6 +192,10 @@ export async function getFullAgentPolicy( }, }; + if (agentPolicy.space_id) { + fullAgentPolicy.namespaces = [agentPolicy.space_id]; + } + const dataPermissions = (await storedPackagePoliciesToAgentPermissions( packageInfoCache, diff --git a/x-pack/plugins/fleet/server/services/agent_policies/utils.ts b/x-pack/plugins/fleet/server/services/agent_policies/utils.ts index 624b6815c05ab..dc69ab6ec013d 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/utils.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/utils.ts @@ -13,13 +13,12 @@ import type { AgentPolicySOAttributes } from '../../types'; export const mapAgentPolicySavedObjectToAgentPolicy = ({ /* eslint-disable @typescript-eslint/naming-convention */ id, - attributes: { - name, - namespace, + namespaces, + version, + attributes, +}: SavedObject): AgentPolicy => { + const { monitoring_enabled, - revision, - updated_at, - updated_by, agent_features, agents, data_output_id, @@ -30,26 +29,22 @@ export const mapAgentPolicySavedObjectToAgentPolicy = ({ inactivity_timeout, is_default, is_default_fleet_server, - is_managed, is_preconfigured, - is_protected, monitoring_output_id, overrides, package_policies, schema_version, - status, unenroll_timeout, - }, -}: SavedObject): AgentPolicy => { + } = attributes || {}; + return { id, - name, - namespace, + version, + space_id: namespaces?.[0] ? namespaces?.[0] : undefined, description, is_default, is_default_fleet_server, has_fleet_server, - is_managed, monitoring_enabled, unenroll_timeout, inactivity_timeout, @@ -60,13 +55,9 @@ export const mapAgentPolicySavedObjectToAgentPolicy = ({ fleet_server_host_id, schema_version, agent_features, - is_protected, overrides, - status, package_policies, agents, - revision, - updated_at, - updated_by, + ...attributes, }; }; diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index 690a4807b14af..d5d4813fdb7e0 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -543,22 +543,27 @@ describe('Agent policy', () => { monitoring_enabled: ['metrics'], }); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + mockedAppContextService.getInternalUserSOClientWithoutSpaceExtension.mockReturnValueOnce( + soClient + ); + await agentPolicyService.bumpAllAgentPolicies(esClient, undefined); - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient, undefined); - - expect(soClient.bulkUpdate).toHaveBeenCalledWith([ - { - attributes: expect.objectContaining({ - fleet_server_hosts: ['http://fleetserver:8220'], - revision: NaN, - updated_by: 'system', + expect(soClient.bulkUpdate).toHaveBeenCalledWith( + [ + expect.objectContaining({ + attributes: expect.objectContaining({ + fleet_server_hosts: ['http://fleetserver:8220'], + revision: NaN, + updated_by: 'system', + }), + id: '93f74c0-e876-11ea-b7d3-8b2acec6f75c', + type: 'ingest_manager_settings', }), - id: '93f74c0-e876-11ea-b7d3-8b2acec6f75c', - references: [], - score: 1, - type: 'ingest_manager_settings', - }, - ]); + ], + expect.objectContaining({ + namespace: 'default', + }) + ); expect(agentPolicyUpdateEventHandler).toHaveBeenCalledTimes(1); }); @@ -571,8 +576,10 @@ describe('Agent policy', () => { monitoring_enabled: ['metrics'], }); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - - await agentPolicyService.bumpAllAgentPoliciesForOutput(soClient, esClient, 'output-id-123'); + mockedAppContextService.getInternalUserSOClientWithoutSpaceExtension.mockReturnValueOnce( + soClient + ); + await agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, 'output-id-123'); expect(agentPolicyUpdateEventHandler).toHaveBeenCalledTimes(1); }); @@ -719,12 +726,10 @@ describe('Agent policy', () => { monitoring_enabled: ['metrics'], }); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - - await agentPolicyService.bumpAllAgentPoliciesForDownloadSource( - soClient, - esClient, - 'test-id-1' + mockedAppContextService.getInternalUserSOClientWithoutSpaceExtension.mockReturnValueOnce( + soClient ); + await agentPolicyService.bumpAllAgentPoliciesForDownloadSource(esClient, 'test-id-1'); expect(agentPolicyUpdateEventHandler).toHaveBeenCalledTimes(1); }); diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 6469479b77ef5..8108fca484019 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -12,8 +12,10 @@ import pMap from 'p-map'; import { lt } from 'semver'; import type { ElasticsearchClient, + SavedObjectsBulkUpdateObject, SavedObjectsBulkUpdateResponse, SavedObjectsClientContract, + SavedObjectsFindResult, SavedObjectsUpdateResponse, } from '@kbn/core/server'; import { SavedObjectsUtils } from '@kbn/core/server'; @@ -114,13 +116,12 @@ const KEY_EDITABLE_FOR_MANAGED_POLICIES = ['namespace']; class AgentPolicyService { private triggerAgentPolicyUpdatedEvent = async ( - soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, action: 'created' | 'updated' | 'deleted', agentPolicyId: string, - options?: { skipDeploy?: boolean } + options?: { skipDeploy?: boolean; spaceId?: string } ) => { - return agentPolicyUpdateEventHandler(soClient, esClient, action, agentPolicyId, options); + return agentPolicyUpdateEventHandler(esClient, action, agentPolicyId, options); }; private async _update( @@ -181,7 +182,9 @@ class AgentPolicyService { }); if (options.bumpRevision || options.removeProtection) { - await this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'updated', id); + await this.triggerAgentPolicyUpdatedEvent(esClient, 'updated', id, { + spaceId: soClient.getCurrentNamespace(), + }); } logger.debug( `Agent policy ${id} update completed, revision: ${ @@ -347,8 +350,9 @@ class AgentPolicyService { ); await appContextService.getUninstallTokenService()?.generateTokenForPolicyId(newSo.id); - await this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'created', newSo.id, { + await this.triggerAgentPolicyUpdatedEvent(esClient, 'created', newSo.id, { skipDeploy: options.skipDeploy, + spaceId: soClient.getCurrentNamespace(), }); logger.debug(`Created new agent policy with id ${newSo.id}`); return { id: newSo.id, ...newSo.attributes }; @@ -391,11 +395,7 @@ class AgentPolicyService { throw new FleetError(agentPolicySO.error.message); } - const agentPolicy = { - id: agentPolicySO.id, - version: agentPolicySO.version, - ...agentPolicySO.attributes, - }; + const agentPolicy = mapAgentPolicySavedObjectToAgentPolicy(agentPolicySO); if (withPackagePolicies) { agentPolicy.package_policies = @@ -432,10 +432,7 @@ class AgentPolicyService { } } - const agentPolicy = { - id: agentPolicySO.id, - ...agentPolicySO.attributes, - }; + const agentPolicy = mapAgentPolicySavedObjectToAgentPolicy(agentPolicySO); if (options.withPackagePolicies) { const agentPolicyWithPackagePolicies = await this.get( soClient, @@ -524,10 +521,7 @@ class AgentPolicyService { const agentPolicies = await pMap( agentPoliciesSO.saved_objects, async (agentPolicySO) => { - const agentPolicy = { - id: agentPolicySO.id, - ...agentPolicySO.attributes, - }; + const agentPolicy = mapAgentPolicySavedObjectToAgentPolicy(agentPolicySO); if (withPackagePolicies) { agentPolicy.package_policies = (await packagePolicyService.findAllForAgentPolicy(soClient, agentPolicySO.id)) || []; @@ -766,10 +760,7 @@ class AgentPolicyService { search: escapeSearchQueryPhrase(outputId), perPage: SO_SEARCH_LIMIT, }) - ).saved_objects.map((so) => ({ - id: so.id, - ...so.attributes, - })); + ).saved_objects.map(mapAgentPolicySavedObjectToAgentPolicy); if (agentPolicies.length > 0) { const getAgentPolicy = (agentPolicy: AgentPolicy) => ({ @@ -827,10 +818,7 @@ class AgentPolicyService { search: escapeSearchQueryPhrase(fleetServerHostId), perPage: SO_SEARCH_LIMIT, }) - ).saved_objects.map((so) => ({ - id: so.id, - ...so.attributes, - })); + ).saved_objects.map(mapAgentPolicySavedObjectToAgentPolicy); if (agentPolicies.length > 0) { await pMap( @@ -846,66 +834,112 @@ class AgentPolicyService { } } - public async bumpAllAgentPoliciesForOutput( - soClient: SavedObjectsClientContract, + private async _bumpPolicies( + internalSoClientWithoutSpaceExtension: SavedObjectsClientContract, esClient: ElasticsearchClient, - outputId: string, + savedObjectsResults: Array>, options?: { user?: AuthenticatedUser } ): Promise> { - const currentPolicies = await soClient.find({ - type: SAVED_OBJECT_TYPE, - fields: ['revision', 'data_output_id', 'monitoring_output_id'], - searchFields: ['data_output_id', 'monitoring_output_id'], - search: escapeSearchQueryPhrase(outputId), - perPage: SO_SEARCH_LIMIT, - }); - const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { - policy.attributes = { - ...policy.attributes, - revision: policy.attributes.revision + 1, - updated_at: new Date().toISOString(), - updated_by: options?.user ? options.user.username : 'system', - }; - return policy; - }); - const res = await soClient.bulkUpdate(bumpedPolicies); + const bumpedPolicies = savedObjectsResults.map( + (policy): SavedObjectsBulkUpdateObject => { + return { + id: policy.id, + type: policy.type, + attributes: { + ...policy.attributes, + revision: policy.attributes.revision + 1, + updated_at: new Date().toISOString(), + updated_by: options?.user ? options.user.username : 'system', + }, + version: policy.version, + namespace: policy.namespaces?.[0], + }; + } + ); + + const bumpedPoliciesBySpaceId = groupBy( + bumpedPolicies, + (policy) => policy.namespace || DEFAULT_SPACE_ID + ); + + const res = ( + await Promise.all( + Object.entries(bumpedPoliciesBySpaceId).map(([spaceId, policies]) => + internalSoClientWithoutSpaceExtension.bulkUpdate(policies, { + namespace: spaceId, + }) + ) + ) + ).reduce( + (acc, r) => { + if (r?.saved_objects) { + acc.saved_objects.push(...r.saved_objects); + } + return acc; + }, + { + saved_objects: [], + } + ); + await pMap( - currentPolicies.saved_objects, - (policy) => this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'updated', policy.id), + savedObjectsResults, + (policy) => + this.triggerAgentPolicyUpdatedEvent(esClient, 'updated', policy.id, { + spaceId: policy.namespaces?.[0], + }), { concurrency: 50 } ); return res; } - public async bumpAllAgentPolicies( - soClient: SavedObjectsClientContract, + public async bumpAllAgentPoliciesForOutput( esClient: ElasticsearchClient, + outputId: string, options?: { user?: AuthenticatedUser } ): Promise> { - const currentPolicies = await soClient.find({ - type: SAVED_OBJECT_TYPE, - fields: ['revision'], - perPage: SO_SEARCH_LIMIT, - }); - const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { - policy.attributes = { - ...policy.attributes, - revision: policy.attributes.revision + 1, - updated_at: new Date().toISOString(), - updated_by: options?.user ? options.user.username : 'system', - }; - return policy; - }); - const res = await soClient.bulkUpdate(bumpedPolicies); + const internalSoClientWithoutSpaceExtension = + appContextService.getInternalUserSOClientWithoutSpaceExtension(); - await pMap( + const currentPolicies = + await internalSoClientWithoutSpaceExtension.find({ + type: SAVED_OBJECT_TYPE, + fields: ['revision', 'data_output_id', 'monitoring_output_id', 'namespaces'], + searchFields: ['data_output_id', 'monitoring_output_id'], + search: escapeSearchQueryPhrase(outputId), + perPage: SO_SEARCH_LIMIT, + namespaces: ['*'], + }); + return this._bumpPolicies( + internalSoClientWithoutSpaceExtension, + esClient, currentPolicies.saved_objects, - (policy) => this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'updated', policy.id), - { concurrency: 50 } + options ); + } - return res; + public async bumpAllAgentPolicies( + esClient: ElasticsearchClient, + options?: { user?: AuthenticatedUser } + ): Promise> { + const internalSoClientWithoutSpaceExtension = + appContextService.getInternalUserSOClientWithoutSpaceExtension(); + + const currentPolicies = + await internalSoClientWithoutSpaceExtension.find({ + type: SAVED_OBJECT_TYPE, + fields: ['name', 'revision', 'namespaces'], + perPage: SO_SEARCH_LIMIT, + namespaces: ['*'], + }); + + return this._bumpPolicies( + internalSoClientWithoutSpaceExtension, + esClient, + currentPolicies.saved_objects, + options + ); } public async delete( @@ -975,7 +1009,9 @@ class AgentPolicyService { } await soClient.delete(SAVED_OBJECT_TYPE, id); - await this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'deleted', id); + await this.triggerAgentPolicyUpdatedEvent(esClient, 'deleted', id, { + spaceId: soClient.getCurrentNamespace(), + }); // cleanup .fleet-policies docs on delete await this.deleteFleetServerPoliciesForPolicyId(esClient, id); @@ -1260,67 +1296,52 @@ class AgentPolicyService { } public async bumpAllAgentPoliciesForDownloadSource( - soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, downloadSourceId: string, options?: { user?: AuthenticatedUser } ): Promise> { - const currentPolicies = await soClient.find({ - type: SAVED_OBJECT_TYPE, - fields: ['revision', 'download_source_id'], - searchFields: ['download_source_id'], - search: escapeSearchQueryPhrase(downloadSourceId), - perPage: SO_SEARCH_LIMIT, - }); - const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { - policy.attributes = { - ...policy.attributes, - revision: policy.attributes.revision + 1, - updated_at: new Date().toISOString(), - updated_by: options?.user ? options.user.username : 'system', - }; - return policy; - }); - const res = await soClient.bulkUpdate(bumpedPolicies); - await pMap( + const internalSoClientWithoutSpaceExtension = + appContextService.getInternalUserSOClientWithoutSpaceExtension(); + const currentPolicies = + await internalSoClientWithoutSpaceExtension.find({ + type: SAVED_OBJECT_TYPE, + fields: ['revision', 'download_source_id', 'namespaces'], + searchFields: ['download_source_id'], + search: escapeSearchQueryPhrase(downloadSourceId), + perPage: SO_SEARCH_LIMIT, + namespaces: ['*'], + }); + + return this._bumpPolicies( + internalSoClientWithoutSpaceExtension, + esClient, currentPolicies.saved_objects, - (policy) => this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'updated', policy.id), - { concurrency: 50 } + options ); - - return res; } public async bumpAllAgentPoliciesForFleetServerHosts( - soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, fleetServerHostId: string, options?: { user?: AuthenticatedUser } ): Promise> { - const currentPolicies = await soClient.find({ - type: SAVED_OBJECT_TYPE, - fields: ['revision', 'fleet_server_host_id'], - searchFields: ['fleet_server_host_id'], - search: escapeSearchQueryPhrase(fleetServerHostId), - perPage: SO_SEARCH_LIMIT, - }); - const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { - policy.attributes = { - ...policy.attributes, - revision: policy.attributes.revision + 1, - updated_at: new Date().toISOString(), - updated_by: options?.user ? options.user.username : 'system', - }; - return policy; - }); - const res = await soClient.bulkUpdate(bumpedPolicies); - await pMap( + const internalSoClientWithoutSpaceExtension = + appContextService.getInternalUserSOClientWithoutSpaceExtension(); + const currentPolicies = + await internalSoClientWithoutSpaceExtension.find({ + type: SAVED_OBJECT_TYPE, + fields: ['revision', 'fleet_server_host_id', 'namespaces'], + searchFields: ['fleet_server_host_id'], + search: escapeSearchQueryPhrase(fleetServerHostId), + perPage: SO_SEARCH_LIMIT, + }); + + return this._bumpPolicies( + internalSoClientWithoutSpaceExtension, + esClient, currentPolicies.saved_objects, - (policy) => this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'updated', policy.id), - { concurrency: 50 } + options ); - - return res; } public async getInactivityTimeouts( diff --git a/x-pack/plugins/fleet/server/services/agent_policy_update.ts b/x-pack/plugins/fleet/server/services/agent_policy_update.ts index 639cf21cb7833..54203900a7dc1 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy_update.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy_update.ts @@ -6,7 +6,7 @@ */ import type { KibanaRequest } from '@kbn/core/server'; -import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; +import type { ElasticsearchClient } from '@kbn/core/server'; import { generateEnrollmentAPIKey, deleteEnrollmentApiKeyForAgentPolicyId } from './api_keys'; import { unenrollForAgentPolicyId } from './agents'; @@ -29,18 +29,19 @@ const fakeRequest = { } as unknown as KibanaRequest; export async function agentPolicyUpdateEventHandler( - soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, action: string, agentPolicyId: string, - options?: { skipDeploy?: boolean } + options?: { skipDeploy?: boolean; spaceId?: string } ) { // `soClient` from ingest `appContextService` is used to create policy change actions // to ensure encrypted SOs are handled correctly - const internalSoClient = appContextService.getInternalUserSOClient(fakeRequest); + const internalSoClient = options?.spaceId + ? appContextService.getInternalUserSOClientForSpaceId(options?.spaceId) + : appContextService.getInternalUserSOClient(fakeRequest); if (action === 'created') { - await generateEnrollmentAPIKey(soClient, esClient, { + await generateEnrollmentAPIKey(internalSoClient, esClient, { name: 'Default', agentPolicyId, forceRecreate: true, @@ -55,7 +56,7 @@ export async function agentPolicyUpdateEventHandler( } if (action === 'deleted') { - await unenrollForAgentPolicyId(soClient, esClient, agentPolicyId); + await unenrollForAgentPolicyId(internalSoClient, esClient, agentPolicyId); await deleteEnrollmentApiKeyForAgentPolicyId(esClient, agentPolicyId); } } diff --git a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.test.ts b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.test.ts index 9200346961f15..ef2209c173510 100644 --- a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.test.ts +++ b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.test.ts @@ -78,6 +78,40 @@ describe('enrollment api keys', () => { 'User creating enrollment API key [name=test-api-key (mock-uuid)] [policy_id=test-agent-policy]', }); }); + + it('should set namespaces if agent policy specify a space ID', async () => { + const soClient = savedObjectsClientMock.create(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + + esClient.create.mockResolvedValue({ + _id: 'test-enrollment-api-key-id', + } as any); + + esClient.security.createApiKey.mockResolvedValue({ + api_key: 'test-api-key-value', + id: 'test-api-key-id', + } as any); + + mockedAgentPolicyService.get.mockResolvedValue({ + id: 'test-agent-policy', + space_id: 'test123', + } as any); + + await generateEnrollmentAPIKey(soClient, esClient, { + name: 'test-api-key', + expiration: '7d', + agentPolicyId: 'test-agent-policy', + forceRecreate: true, + }); + + expect(esClient.create).toHaveBeenCalledWith( + expect.objectContaining({ + body: expect.objectContaining({ + namespaces: ['test123'], + }), + }) + ); + }); }); describe('deleteEnrollmentApiKey', () => { diff --git a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts index 360723ebcf220..02e1e9e25e194 100644 --- a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts +++ b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts @@ -176,14 +176,11 @@ export async function generateEnrollmentAPIKey( } ): Promise { const id = uuidv4(); - const { name: providedKeyName, forceRecreate } = data; + const { name: providedKeyName, forceRecreate, agentPolicyId } = data; const logger = appContextService.getLogger(); logger.debug(`Creating enrollment API key ${data}`); - if (data.agentPolicyId) { - await validateAgentPolicyId(soClient, data.agentPolicyId); - } - const agentPolicyId = data.agentPolicyId; + const agentPolicy = await retrieveAgentPolicyId(soClient, agentPolicyId); if (providedKeyName && !forceRecreate) { let hasMore = true; @@ -276,6 +273,7 @@ export async function generateEnrollmentAPIKey( api_key: apiKey, name, policy_id: agentPolicyId, + namespaces: agentPolicy?.space_id ? [agentPolicy?.space_id] : undefined, created_at: new Date().toISOString(), }; @@ -354,10 +352,8 @@ export async function getEnrollmentAPIKeyById(esClient: ElasticsearchClient, api return enrollmentAPIKey; } -async function validateAgentPolicyId(soClient: SavedObjectsClientContract, agentPolicyId: string) { - try { - await agentPolicyService.get(soClient, agentPolicyId); - } catch (e) { +async function retrieveAgentPolicyId(soClient: SavedObjectsClientContract, agentPolicyId: string) { + return agentPolicyService.get(soClient, agentPolicyId).catch(async (e) => { if (e.isBoom && e.output.statusCode === 404) { throw Boom.badRequest( i18n.translate('xpack.fleet.serverError.agentPolicyDoesNotExist', { @@ -367,7 +363,7 @@ async function validateAgentPolicyId(soClient: SavedObjectsClientContract, agent ); } throw e; - } + }); } function esDocToEnrollmentApiKey(doc: { diff --git a/x-pack/plugins/fleet/server/services/app_context.ts b/x-pack/plugins/fleet/server/services/app_context.ts index 65a0fb6c08f35..533b57f6f7653 100644 --- a/x-pack/plugins/fleet/server/services/app_context.ts +++ b/x-pack/plugins/fleet/server/services/app_context.ts @@ -30,7 +30,7 @@ import type { CloudSetup } from '@kbn/cloud-plugin/server'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import type { SavedObjectTaggingStart } from '@kbn/saved-objects-tagging-plugin/server'; -import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server'; +import { SECURITY_EXTENSION_ID, SPACES_EXTENSION_ID } from '@kbn/core-saved-objects-server'; import type { FleetConfigType } from '../../common/types'; import type { ExperimentalFeatures } from '../../common/experimental_features'; @@ -194,13 +194,42 @@ class AppContextService { }); } - public getInternalUserSOClient(request: KibanaRequest) { + public getInternalUserSOClient(request?: KibanaRequest) { + if (!request) { + request = { + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { href: {} }, + raw: { req: { url: '/' } }, + isFakeRequest: true, + } as unknown as KibanaRequest; + } + // soClient as kibana internal users, be careful on how you use it, security is not enabled return appContextService.getSavedObjects().getScopedClient(request, { excludedExtensions: [SECURITY_EXTENSION_ID], }); } + public getInternalUserSOClientWithoutSpaceExtension() { + const fakeRequest = { + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { href: {} }, + raw: { req: { url: '/' } }, + isFakeRequest: true, + } as unknown as KibanaRequest; + + // soClient as kibana internal users, be careful on how you use it, security is not enabled + return appContextService.getSavedObjects().getScopedClient(fakeRequest, { + excludedExtensions: [SECURITY_EXTENSION_ID, SPACES_EXTENSION_ID], + }); + } + public getInternalUserESClient() { if (!this.esClient) { throw new Error('Elasticsearch start service not set.'); diff --git a/x-pack/plugins/fleet/server/services/output.ts b/x-pack/plugins/fleet/server/services/output.ts index 9a339fb33ec78..f42867f0686bb 100644 --- a/x-pack/plugins/fleet/server/services/output.ts +++ b/x-pack/plugins/fleet/server/services/output.ts @@ -1076,7 +1076,7 @@ class OutputService { { preset }, { fromPreconfiguration: true } ); - await agentPolicyService.bumpAllAgentPoliciesForOutput(soClient, esClient, output.id); + await agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, output.id); }, { concurrency: 5, diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts index f4e6eab5374c0..83a229263e7e6 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts @@ -327,6 +327,7 @@ describe('policy preconfiguration', () => { mockConfiguredPolicies.clear(); spyAgentPolicyServiceUpdate.mockClear(); spyAgentPolicyServicBumpAllAgentPoliciesForOutput.mockClear(); + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReset(); }); describe('with no bundled packages', () => { @@ -335,6 +336,7 @@ describe('policy preconfiguration', () => { it('should perform a no-op when passed no policies or packages', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -354,6 +356,7 @@ describe('policy preconfiguration', () => { it('should install packages successfully', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -373,6 +376,7 @@ describe('policy preconfiguration', () => { it('should install packages and configure agent policies successfully', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -405,6 +409,7 @@ describe('policy preconfiguration', () => { it('should install packages and configure agent policies successfully if using simplified package policy', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -471,6 +476,7 @@ describe('policy preconfiguration', () => { it('should install prerelease packages if needed', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -490,6 +496,7 @@ describe('policy preconfiguration', () => { it('should pass skipDatastreamRollover flag if configured', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -514,6 +521,7 @@ describe('policy preconfiguration', () => { it('should not add new package policy to existing non managed policies', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'test_package1' } as PackagePolicy, ]); @@ -564,6 +572,7 @@ describe('policy preconfiguration', () => { it('should add new package policy to existing managed policies', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'test_package1' } as PackagePolicy, ]); @@ -623,6 +632,7 @@ describe('policy preconfiguration', () => { it('should update keep_monitoring_enabled for existing managed policies', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'test_package1' } as PackagePolicy, ]); @@ -685,6 +695,7 @@ describe('policy preconfiguration', () => { it('should update keep_monitoring_enabled for existing managed policies (even is the SO is out-of-sync)', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'test_package1' } as PackagePolicy, ]); @@ -747,7 +758,7 @@ describe('policy preconfiguration', () => { it('should not try to recreate preconfigure package policy that has been renamed', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); mockedPackagePolicyService.findAllForAgentPolicy.mockResolvedValue([ { name: 'Renamed package policy', id: 'test_package1' } as PackagePolicy, ]); @@ -797,6 +808,7 @@ describe('policy preconfiguration', () => { it('should throw an error when trying to install duplicate packages', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); await expect( ensurePreconfiguredPackagesAndPolicies( @@ -819,6 +831,7 @@ describe('policy preconfiguration', () => { it('should not create a policy and throw an error if install fails for required package', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const policies: PreconfiguredAgentPolicy[] = [ { name: 'Test policy', @@ -852,6 +865,7 @@ describe('policy preconfiguration', () => { it('should not create a policy and throw an error if package is not installed for an unknown reason', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const policies: PreconfiguredAgentPolicy[] = [ { @@ -886,6 +900,7 @@ describe('policy preconfiguration', () => { it('should return a non fatal error if support_agentless is defined in stateful', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); jest.mocked(appContextService.getExperimentalFeatures).mockReturnValue({ agentless: true, } as any); @@ -922,6 +937,7 @@ describe('policy preconfiguration', () => { it('should not return an error if support_agentless is defined in serverless and agentless is enabled', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); jest.mocked(appContextService.getExperimentalFeatures).mockReturnValue({ agentless: true, } as any); @@ -957,6 +973,7 @@ describe('policy preconfiguration', () => { it('should return an error if agentless feature flag is disabled on serverless', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); jest.mocked(appContextService.getExperimentalFeatures).mockReturnValue({ agentless: false, } as any); @@ -993,6 +1010,7 @@ describe('policy preconfiguration', () => { it('should not attempt to recreate or modify an agent policy if its ID is unchanged', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies: policiesA, nonFatalErrors: nonFatalErrorsA } = await ensurePreconfiguredPackagesAndPolicies( @@ -1048,6 +1066,7 @@ describe('policy preconfiguration', () => { it('should update a managed policy if top level fields are changed', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); mockConfiguredPolicies.set('test-id', { name: 'Test policy', @@ -1101,6 +1120,7 @@ describe('policy preconfiguration', () => { it('should not update a managed policy if a top level field has not changed', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const policy: PreconfiguredAgentPolicy = { name: 'Test policy', namespace: 'default', @@ -1213,6 +1233,7 @@ describe('policy preconfiguration', () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest.mocked(appContextService).getInternalUserSOClientForSpaceId.mockReturnValue(soClient); const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -1251,6 +1272,9 @@ describe('policy preconfiguration', () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + jest + .mocked(appContextService) + .getInternalUserSOClientForSpaceId.mockReturnValue(soClient); // Install an older version of a test package mockInstalledPackages.set('test_package', { diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index 9d0e7bc2b151a..4ab0a9977a5a6 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -8,6 +8,7 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; import { groupBy, omit, pick, isEqual } from 'lodash'; +import { DEFAULT_NAMESPACE_STRING } from '@kbn/core-saved-objects-utils-server'; import apm from 'elastic-apm-node'; @@ -177,7 +178,7 @@ export async function ensurePreconfiguredPackagesAndPolicies( const namespacedSoClient = preconfiguredAgentPolicy.space_id ? appContextService.getInternalUserSOClientForSpaceId(preconfiguredAgentPolicy.space_id) - : defaultSoClient; + : appContextService.getInternalUserSOClientForSpaceId(DEFAULT_NAMESPACE_STRING); const { created, policy } = await agentPolicyService.ensurePreconfiguredAgentPolicy( namespacedSoClient, diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts index 6e2685fa8a097..03787b8e6be65 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts @@ -101,12 +101,11 @@ async function createOrUpdatePreconfiguredFleetProxies( fleetServerHosts.some((host) => host.is_default) || outputs.some((output) => output.is_default || output.is_default_monitoring) ) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } else { await pMap( outputs, - (output) => - agentPolicyService.bumpAllAgentPoliciesForOutput(soClient, esClient, output.id), + (output) => agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, output.id), { concurrency: 20, } @@ -115,7 +114,6 @@ async function createOrUpdatePreconfiguredFleetProxies( fleetServerHosts, (fleetServerHost) => agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts( - soClient, esClient, fleetServerHost.id ), diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts index 5959cc25288ce..aae140b5843b0 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts @@ -137,9 +137,9 @@ export async function createOrUpdatePreconfiguredFleetServerHosts( { fromPreconfiguration: true } ); if (data.is_default) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } else { - await agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts(soClient, esClient, id); + await agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts(esClient, id); } } }) diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.test.ts index d640f74f4b03b..f6feffd24df53 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.test.ts @@ -6,6 +6,7 @@ */ import { elasticsearchServiceMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { appContextService } from '..'; import type { PreconfiguredOutput } from '../../../common/types'; import type { Output } from '../../types'; @@ -29,6 +30,7 @@ const mockedOutputService = outputService as jest.Mocked; jest.mock('../app_context', () => ({ appContextService: { + getInternalUserSOClientWithoutSpaceExtension: jest.fn(), getLogger: () => new Proxy( {}, @@ -48,6 +50,16 @@ const spyAgentPolicyServicBumpAllAgentPoliciesForOutput = jest.spyOn( describe('output preconfiguration', () => { beforeEach(async () => { + const internalSoClientWithoutSpaceExtension = savedObjectsClientMock.create(); + jest + .mocked(appContextService.getInternalUserSOClientWithoutSpaceExtension) + .mockReturnValue(internalSoClientWithoutSpaceExtension); + internalSoClientWithoutSpaceExtension.find.mockResolvedValue({ + saved_objects: [], + page: 0, + per_page: 0, + total: 0, + }); mockedOutputService.create.mockReset(); mockedOutputService.update.mockReset(); mockedOutputService.delete.mockReset(); @@ -439,7 +451,6 @@ describe('output preconfiguration', () => { it('should update output if non preconfigured ES output with the same id exists', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); mockedOutputService.bulkGet.mockResolvedValue([ { id: 'existing-es-output-1', @@ -480,7 +491,6 @@ describe('output preconfiguration', () => { it('should update output if preconfigured ES output exists and changed', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-es-output-1', @@ -500,7 +510,6 @@ describe('output preconfiguration', () => { it('should update output if preconfigured output exists and changed to is_internal: true', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-es-output-1', @@ -521,7 +530,6 @@ describe('output preconfiguration', () => { it('should update output if a preconfigured logstash ouput exists and has changed', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-logstash-output-1', @@ -545,7 +553,6 @@ describe('output preconfiguration', () => { it('should update output if a preconfigured logstash ouput with secrets exists and has changed', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-logstash-output-with-secrets-1', @@ -569,7 +576,6 @@ describe('output preconfiguration', () => { it('should update output if preconfigured kafka output exists and changed', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-kafka-output-1', @@ -589,7 +595,6 @@ describe('output preconfiguration', () => { it('should update ouput if a preconfigured kafka with secrets exists and has changed', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-kafka-output-with-secrets-1', @@ -614,7 +619,6 @@ describe('output preconfiguration', () => { it('should update output if preconfigured remote ES output exists and changed', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-remote-es-output-1', @@ -635,7 +639,6 @@ describe('output preconfiguration', () => { it('should update ouput if a preconfigured remote ES with secrets exists and has changed', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-remote-es-output-with-secrets-1', @@ -658,7 +661,6 @@ describe('output preconfiguration', () => { it('should update output if a preconfigured logstash output with plain value secrets exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-logstash-output-with-secrets-2', @@ -683,7 +685,6 @@ describe('output preconfiguration', () => { it('should update output if a preconfigured kafka output with plain value secrets exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-kafka-output-with-secrets-2', @@ -709,7 +710,6 @@ describe('output preconfiguration', () => { it('should update output if a preconfigured remote ES output with plain value secrets exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-remote-es-output-with-secrets-2', @@ -734,7 +734,6 @@ describe('output preconfiguration', () => { it('should not update output if preconfigured ES output exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-es-output-1', @@ -754,7 +753,6 @@ describe('output preconfiguration', () => { it('should not update output if preconfigured logstash output exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-logstash-output-1', @@ -778,7 +776,6 @@ describe('output preconfiguration', () => { it('should not update output if preconfigured kafka output exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-kafka-output-1', @@ -802,7 +799,6 @@ describe('output preconfiguration', () => { it('should not update output if preconfigured remote ES output exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-remote-es-output-1', @@ -824,7 +820,6 @@ describe('output preconfiguration', () => { it('should not update output if a preconfigured logstash output with secrets exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-logstash-output-with-secrets-1', @@ -849,7 +844,6 @@ describe('output preconfiguration', () => { it('should not update output if a preconfigured kafka output with secrets exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-kafka-output-with-secrets-1', @@ -875,7 +869,6 @@ describe('output preconfiguration', () => { it('should not update output if a preconfigured remote ES output with secrets exists and did not change', async () => { const soClient = savedObjectsClientMock.create(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - soClient.find.mockResolvedValue({ saved_objects: [], page: 0, per_page: 0, total: 0 }); await createOrUpdatePreconfiguredOutputs(soClient, esClient, [ { id: 'existing-remote-es-output-with-secrets-1', diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts index a6e76fead7797..fa7103bebb3b4 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts @@ -129,9 +129,9 @@ export async function createOrUpdatePreconfiguredOutputs( }); // Bump revision of all policies using that output if (outputData.is_default || outputData.is_default_monitoring) { - await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + await agentPolicyService.bumpAllAgentPolicies(esClient); } else { - await agentPolicyService.bumpAllAgentPoliciesForOutput(soClient, esClient, id); + await agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, id); } } } diff --git a/x-pack/plugins/fleet/tsconfig.json b/x-pack/plugins/fleet/tsconfig.json index d4807a5ef53b2..8bee11fed5d0e 100644 --- a/x-pack/plugins/fleet/tsconfig.json +++ b/x-pack/plugins/fleet/tsconfig.json @@ -110,5 +110,6 @@ "@kbn/react-kibana-context-render", "@kbn/fields-metadata-plugin", "@kbn/test-jest-helpers", + "@kbn/core-saved-objects-utils-server", ] } diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts index 76fe6e6e340fd..11519523efb14 100644 --- a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts +++ b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts @@ -63,7 +63,7 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .expect(200); expect(body.items.length).to.eql(1); - const { id, updated_at: updatedAt, ...rest } = body.items[0]; + const { id, updated_at: updatedAt, version, ...rest } = body.items[0]; expectSnapshot(rest).toMatch(); }); @@ -1469,7 +1469,13 @@ export default function (providerContext: FtrProviderContext) { expect(items[0].package_policies.length).equal(1); expect(items[0].package_policies[0]).to.have.property('package'); expect(items[0].package_policies[0].package.name).equal('system'); - const { package_policies: packagePolicies, id, updated_at: updatedAt, ...rest } = items[0]; + const { + package_policies: packagePolicies, + id, + updated_at: updatedAt, + version: policyVersion, + ...rest + } = items[0]; expectSnapshot({ ...rest, package_policies: packagePolicies.map( diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts index 70066599547d4..72fd2d855130d 100644 --- a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts +++ b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts @@ -10,6 +10,7 @@ import { AGENT_POLICY_INDEX, AGENT_UPDATE_LAST_CHECKIN_INTERVAL_MS, } from '@kbn/fleet-plugin/common'; +import { ENROLLMENT_API_KEYS_INDEX } from '@kbn/fleet-plugin/common/constants'; import { skipIfNoDockerRegistry } from '../../helpers'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { setupFleetAndAgents } from '../agents/services'; @@ -19,6 +20,7 @@ export default function (providerContext: FtrProviderContext) { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); const esClient = getService('es'); + const kibanaServer = getService('kibanaServer'); async function getEnrollmentKeyForPolicyId(policyId: string) { const listRes = await supertest.get(`/api/fleet/enrollment_api_keys`).expect(200); @@ -34,7 +36,7 @@ export default function (providerContext: FtrProviderContext) { return res.body.item; } - async function hasFleetServerPoliciesForPolicy(policyId: string) { + async function assertFleetServerPoliciesForPolicy(policyId: string, spaceId?: string) { const res = await esClient.search({ index: AGENT_POLICY_INDEX, ignore_unavailable: true, @@ -49,8 +51,36 @@ export default function (providerContext: FtrProviderContext) { }, }); + if (spaceId) { + const docsSpaceId = res.hits.hits.flatMap((hit) => (hit._source as any).namespaces)?.[0]; + expect(docsSpaceId).to.eql(docsSpaceId); + } + + // @ts-expect-error TotalHit + expect(res.hits.total.value !== 0).to.be(true); + } + + async function assertHasFleetServerEnrollmentApiKeyForPolicy(policyId: string, spaceId?: string) { + const res = await esClient.search({ + index: ENROLLMENT_API_KEYS_INDEX, + ignore_unavailable: true, + body: { + query: { + term: { + policy_id: policyId, + }, + }, + size: 1, + }, + }); + + if (spaceId) { + const docsSpaceId = res.hits.hits.flatMap((hit) => (hit._source as any).namespaces)?.[0]; + expect(docsSpaceId).to.eql(docsSpaceId); + } + // @ts-expect-error TotalHit - return res.hits.total.value !== 0; + expect(res.hits.total.value !== 0).to.be(true); } // Test all the side effect that should occurs when we create|update an agent policy @@ -70,47 +100,80 @@ export default function (providerContext: FtrProviderContext) { setupFleetAndAgents(providerContext); - describe('POST /api/fleet/agent_policies', () => { - it('should create an enrollment key for the policy', async () => { - const name = `test-${Date.now()}`; + describe('In default space', () => { + describe('POST /api/fleet/agent_policies', () => { + it('should create an enrollment key for the policy', async () => { + const name = `test-${Date.now()}`; + + const res = await supertest + .post(`/s/test/api/fleet/agent_policies?sys_monitoring=true`) + .set('kbn-xsrf', 'xxxx') + .send({ + name, + namespace: 'default', + }) + .expect(200); + + const policyId = res.body.item.id; + const enrollmentKey = await getEnrollmentKeyForPolicyId(policyId); + expect(enrollmentKey).not.empty(); + + await assertFleetServerPoliciesForPolicy(policyId); + }); + }); - const res = await supertest - .post(`/api/fleet/agent_policies?sys_monitoring=true`) - .set('kbn-xsrf', 'xxxx') - .send({ - name, - namespace: 'default', - }) - .expect(200); + describe('POST /api/fleet/agent_policies/copy', () => { + const TEST_POLICY_ID = `policy1`; - const policyId = res.body.item.id; - const enrollmentKey = await getEnrollmentKeyForPolicyId(policyId); - expect(enrollmentKey).not.empty(); + it('should create an enrollment key for the policy', async () => { + const name = `test-${Date.now()}`; - expect(await hasFleetServerPoliciesForPolicy(policyId)).to.be(true); - }); - }); + const res = await supertest + .post(`/api/fleet/agent_policies/${TEST_POLICY_ID}/copy`) + .set('kbn-xsrf', 'xxxx') + .send({ + name, + description: 'Test', + }) + .expect(200); - describe('POST /api/fleet/agent_policies/copy', () => { - const TEST_POLICY_ID = `policy1`; + const policyId = res.body.item.id; + const enrollmentKey = await getEnrollmentKeyForPolicyId(policyId); + expect(enrollmentKey).not.empty(); - it('should create an enrollment key for the policy', async () => { - const name = `test-${Date.now()}`; + await assertFleetServerPoliciesForPolicy(policyId); + }); + }); + }); - const res = await supertest - .post(`/api/fleet/agent_policies/${TEST_POLICY_ID}/copy`) - .set('kbn-xsrf', 'xxxx') - .send({ - name, - description: 'Test', + describe('In a non default space', () => { + const SPACE_ID = 'test'; + before(async () => { + await kibanaServer.spaces + .create({ + id: SPACE_ID, + name: SPACE_ID, }) - .expect(200); - - const policyId = res.body.item.id; - const enrollmentKey = await getEnrollmentKeyForPolicyId(policyId); - expect(enrollmentKey).not.empty(); - - expect(await hasFleetServerPoliciesForPolicy(policyId)).to.be(true); + .catch((err) => {}); + }); + describe('POST /s/test/api/fleet/agent_policies', () => { + it('should create an .fleet-policy and .fleet-enrollment key for the policy', async () => { + const name = `test-${Date.now()}`; + + const res = await supertest + .post(`/s/${SPACE_ID}/api/fleet/agent_policies?sys_monitoring=true`) + .set('kbn-xsrf', 'xxxx') + .send({ + name, + namespace: 'default', + }) + .expect(200); + + const policyId = res.body.item.id; + + await assertHasFleetServerEnrollmentApiKeyForPolicy(policyId, SPACE_ID); + await assertFleetServerPoliciesForPolicy(policyId, SPACE_ID); + }); }); }); }); diff --git a/x-pack/test/fleet_api_integration/apis/outputs/crud.ts b/x-pack/test/fleet_api_integration/apis/outputs/crud.ts index efe17758ea53b..e635ad8eafae7 100644 --- a/x-pack/test/fleet_api_integration/apis/outputs/crud.ts +++ b/x-pack/test/fleet_api_integration/apis/outputs/crud.ts @@ -6,10 +6,12 @@ */ import expect from '@kbn/expect'; +import { CreateAgentPolicyResponse, GetOneAgentPolicyResponse } from '@kbn/fleet-plugin/common'; import { GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, OUTPUT_HEALTH_DATA_STREAM, } from '@kbn/fleet-plugin/common/constants'; +import { v4 as uuidV4 } from 'uuid'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; import { setupFleetAndAgents } from '../agents/services'; @@ -133,6 +135,51 @@ export default function (providerContext: FtrProviderContext) { } }; + const createAgentPolicy = async (spaceId?: string): Promise => { + const { body: testPolicyRes } = await supertest + .post(spaceId ? `/s/${spaceId}/api/fleet/agent_policies` : `/api/fleet/agent_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: `test ${uuidV4()}`, + description: '', + namespace: 'default', + }) + .expect(200); + + return testPolicyRes; + }; + + const deleteAgentPolicy = async (agentPolicyId: string, spaceId?: string) => { + await supertest + .post( + spaceId + ? `/s/${spaceId}/api/fleet/agent_policies/delete` + : `/api/fleet/agent_policies/delete` + ) + .send({ + agentPolicyId, + }) + .set('kbn-xsrf', 'xxxx') + .expect(200); + }; + + const getAgentPolicy = async ( + policyId: string, + spaceId?: string + ): Promise => { + const { body: testPolicyRes } = await supertest + .get( + spaceId + ? `/s/${spaceId}/api/fleet/agent_policies/${policyId}` + : `/api/fleet/agent_policies/${policyId}` + ) + .expect(200); + + return testPolicyRes; + }; + + const TEST_SPACE_ID = 'testspaceoutputs'; + describe('fleet_outputs_crud', async function () { skipIfNoDockerRegistry(providerContext); before(async () => { @@ -149,6 +196,12 @@ export default function (providerContext: FtrProviderContext) { before(async function () { await enableSecrets(); await enableOutputSecrets(); + await kibanaServer.spaces + .create({ + id: TEST_SPACE_ID, + name: TEST_SPACE_ID, + }) + .catch((err) => {}); // we must first force install the fleet_server package to override package verification error on policy create // https://github.com/elastic/kibana/issues/137450 const getPkRes = await supertest @@ -725,6 +778,40 @@ export default function (providerContext: FtrProviderContext) { // not found } }); + + it('should bump all policies in all spaces if updating the default output', async () => { + const [policy1, policy2, policy3] = await Promise.all([ + createAgentPolicy(), + createAgentPolicy(), + createAgentPolicy(TEST_SPACE_ID), + ]); + + await supertest + .put(`/api/fleet/outputs/${defaultOutputId}`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'Updated Default ES Output', + type: 'elasticsearch', + hosts: ['http://test.fr:443'], + }) + .expect(200); + + const [updatedPolicy1, updatedPolicy2, updatedPolicy3] = await Promise.all([ + getAgentPolicy(policy1.item.id), + getAgentPolicy(policy2.item.id), + getAgentPolicy(policy3.item.id, TEST_SPACE_ID), + ]); + expect(updatedPolicy1.item.revision).to.eql(policy1.item.revision + 1); + expect(updatedPolicy2.item.revision).to.eql(policy2.item.revision + 1); + expect(updatedPolicy3.item.revision).to.eql(policy3.item.revision + 1); + + // cleanup + await Promise.all([ + deleteAgentPolicy(policy1.item.id), + deleteAgentPolicy(policy2.item.id), + deleteAgentPolicy(policy3.item.id, TEST_SPACE_ID), + ]); + }); }); describe('POST /outputs', () => { From 67940a24255af47e8ba14843175ff4d06338691e Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 6 Jun 2024 02:56:03 +1000 Subject: [PATCH 008/122] [ES|QL] Update function definitions (#184626) This PR updates the function definitions based on the latest metadata from Elasticsearch. --------- Co-authored-by: Drew Tate --- .../package.json | 3 +- .../scripts/generate_function_definitions.ts | 125 +- .../generate_function_validation_tests.ts | 2 +- .../src/definitions/functions.ts | 1799 +++++++++-------- .../esql_validation_meta_tests.json | 692 +++++-- .../src/validation/validation.test.ts | 476 ++++- 6 files changed, 1958 insertions(+), 1139 deletions(-) diff --git a/packages/kbn-esql-validation-autocomplete/package.json b/packages/kbn-esql-validation-autocomplete/package.json index 892ffd6999656..51d2e86a26fd9 100644 --- a/packages/kbn-esql-validation-autocomplete/package.json +++ b/packages/kbn-esql-validation-autocomplete/package.json @@ -10,6 +10,7 @@ "make:defs": "ts-node --transpileOnly ./scripts/generate_function_definitions.ts", "postmake:defs": "yarn run lint:fix && yarn run i18n:fix", "lint:fix": "cd ../.. && node ./scripts/eslint --fix ./packages/kbn-esql-validation-autocomplete/src/**/*.ts", - "i18n:fix": "cd ../.. && node ./scripts/i18n_check.js --fix" + "i18n:fix": "cd ../.. && node ./scripts/i18n_check.js --fix", + "test:validation": "cd ../.. && yarn test:jest ./packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts" } } diff --git a/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts b/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts index 65e2c8fe38526..f50bf584efb0e 100644 --- a/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts +++ b/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts @@ -29,7 +29,9 @@ const evalSupportedCommandsAndOptions = { supportedOptions: ['by'], }; -const excludedFunctions = new Set(['bucket', 'case']); +// coalesce can be removed when a test is added for version type +// (https://github.com/elastic/elasticsearch/pull/109032#issuecomment-2150033350) +const excludedFunctions = new Set(['bucket', 'case', 'coalesce']); const extraFunctions: FunctionDefinition[] = [ { @@ -52,6 +54,48 @@ const extraFunctions: FunctionDefinition[] = [ `from index | eval type = case(languages <= 1, "monolingual", languages <= 2, "bilingual", "polyglot")`, ], }, + { + type: 'eval', + name: 'coalesce', + description: + 'Returns the first of its arguments that is not null. If all arguments are null, it returns `null`.', + alias: undefined, + signatures: supportedFieldTypes + .map((type) => [ + { + params: [ + { + name: 'first', + type, + optional: false, + }, + ], + returnType: type, + minParams: 1, + }, + { + params: [ + { + name: 'first', + type, + optional: false, + }, + { + name: 'rest', + type, + optional: true, + }, + ], + returnType: type, + minParams: 1, + }, + ]) + .flat(), + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: ['ROW a=null, b="b"\n| EVAL COALESCE(a, b)'], + }, ]; const elasticsearchToKibanaType = (elasticsearchType: string) => { @@ -214,40 +258,6 @@ const functionEnrichments: Record> }), }, // can be removed when https://github.com/elastic/elasticsearch/issues/108982 is complete - coalesce: { - signatures: supportedFieldTypes - .map((type) => [ - { - params: [ - { - name: 'first', - type, - optional: false, - }, - ], - returnType: type, - minParams: 1, - }, - { - params: [ - { - name: 'first', - type, - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: type, - minParams: 1, - }, - ]) - .flat(), - }, - // can be removed when https://github.com/elastic/elasticsearch/issues/108982 is complete mv_dedupe: { signatures: supportedFieldTypes.map((type) => ({ params: [ @@ -304,21 +314,53 @@ function getFunctionDefinition(ESFunctionDefinition: Record): Funct } function printGeneratedFunctionsFile(functionDefinitions: FunctionDefinition[]) { + /** + * Deals with asciidoc internal cross-references in the function descriptions + * + * Examples: + * <> -> `MV_MAX` + * <> -> `ST_INTERSECTS` + * <> -> multivalued fields + */ + const removeAsciiDocInternalCrossReferences = ( + asciidocString: string, + functionNames: string[] + ) => { + const internalCrossReferenceRegex = /<<(.+?)(,.+?)?>>/g; + + const extractPossibleFunctionName = (id: string) => id.replace('esql-', ''); + + return asciidocString.replace(internalCrossReferenceRegex, (_match, anchorId, linkText) => { + const ret = linkText ? linkText.slice(1) : anchorId; + + const matchingFunction = functionNames.find( + (name) => + extractPossibleFunctionName(ret) === name.toLowerCase() || + extractPossibleFunctionName(ret) === name.toUpperCase() + ); + return matchingFunction ? `\`${matchingFunction.toUpperCase()}\`` : ret; + }); + }; + const removeInlineAsciiDocLinks = (asciidocString: string) => { const inlineLinkRegex = /\{.+?\}\/.+?\[(.+?)\]/g; + return asciidocString.replace(inlineLinkRegex, '$1'); }; const getDefinitionName = (name: string) => _.camelCase(`${name}Definition`); - const printFunctionDefinition = (functionDefinition: FunctionDefinition) => { + const printFunctionDefinition = ( + functionDefinition: FunctionDefinition, + functionNames: string[] + ) => { const { type, name, description, alias, signatures } = functionDefinition; return `const ${getDefinitionName(name)}: FunctionDefinition = { type: '${type}', name: '${name}', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.${name}', { defaultMessage: ${JSON.stringify( - removeInlineAsciiDocLinks(description) + removeAsciiDocInternalCrossReferences(removeInlineAsciiDocLinks(description), functionNames) )} }), alias: ${alias ? `['${alias.join("', '")}']` : 'undefined'}, signatures: ${JSON.stringify(signatures, null, 2)}, @@ -340,7 +382,14 @@ import type { FunctionDefinition } from './types'; `; - const functionDefinitionsString = functionDefinitions.map(printFunctionDefinition).join('\n\n'); + const functionDefinitionsString = functionDefinitions + .map((def) => + printFunctionDefinition( + def, + functionDefinitions.map(({ name }) => name) + ) + ) + .join('\n\n'); const fileContents = `${fileHeader}${functionDefinitionsString} export const evalFunctionDefinitions = [${functionDefinitions diff --git a/packages/kbn-esql-validation-autocomplete/scripts/generate_function_validation_tests.ts b/packages/kbn-esql-validation-autocomplete/scripts/generate_function_validation_tests.ts index 3f3f4f42a07ce..b7cc5c4481e66 100644 --- a/packages/kbn-esql-validation-autocomplete/scripts/generate_function_validation_tests.ts +++ b/packages/kbn-esql-validation-autocomplete/scripts/generate_function_validation_tests.ts @@ -142,7 +142,7 @@ function generateImplicitDateCastingTestsForFunction( signature.params.some( (param, i) => param.type === 'date' && - !definition.signatures.some((def) => def.params[i].type === 'string') // don't count parameters that already accept a string + !definition.signatures.some((def) => getParamAtPosition(def, i)?.type === 'string') // don't count parameters that already accept a string ) ); diff --git a/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts b/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts index 6c704cd69cd48..930e8b0c30837 100644 --- a/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts +++ b/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts @@ -235,292 +235,6 @@ const cidrMatchDefinition: FunctionDefinition = { ], }; -const coalesceDefinition: FunctionDefinition = { - type: 'eval', - name: 'coalesce', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.coalesce', { - defaultMessage: - 'Returns the first of its arguments that is not null. If all arguments are null, it returns `null`.', - }), - alias: undefined, - signatures: [ - { - params: [ - { - name: 'first', - type: 'number', - optional: false, - }, - ], - returnType: 'number', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'number', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'number', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'date', - optional: false, - }, - ], - returnType: 'date', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'date', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'date', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'string', - optional: false, - }, - ], - returnType: 'string', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'string', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'string', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'boolean', - optional: false, - }, - ], - returnType: 'boolean', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'boolean', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'boolean', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'ip', - optional: false, - }, - ], - returnType: 'ip', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'ip', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'ip', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'cartesian_point', - optional: false, - }, - ], - returnType: 'cartesian_point', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'cartesian_point', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'cartesian_point', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'cartesian_shape', - optional: false, - }, - ], - returnType: 'cartesian_shape', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'cartesian_shape', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'cartesian_shape', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'geo_point', - optional: false, - }, - ], - returnType: 'geo_point', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'geo_point', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'geo_point', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'geo_shape', - optional: false, - }, - ], - returnType: 'geo_shape', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'geo_shape', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'geo_shape', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'version', - optional: false, - }, - ], - returnType: 'version', - minParams: 1, - }, - { - params: [ - { - name: 'first', - type: 'version', - optional: false, - }, - { - name: 'rest', - type: 'boolean', - optional: true, - }, - ], - returnType: 'version', - minParams: 1, - }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: ['ROW a=null, b="b"\n| EVAL COALESCE(a, b)'], -}; - const concatDefinition: FunctionDefinition = { type: 'eval', name: 'concat', @@ -953,8 +667,7 @@ const greatestDefinition: FunctionDefinition = { name: 'greatest', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.greatest', { defaultMessage: - 'Returns the maximum value from multiple columns. This is similar to <>\nexcept it is intended to run on multiple columns at once.', - ignoreTag: true, + 'Returns the maximum value from multiple columns. This is similar to `MV_MAX`\nexcept it is intended to run on multiple columns at once.', }), alias: undefined, signatures: [ @@ -1078,13 +791,49 @@ const greatestDefinition: FunctionDefinition = { examples: ['ROW a = 10, b = 20\n| EVAL g = GREATEST(a, b)'], }; +const ipPrefixDefinition: FunctionDefinition = { + type: 'eval', + name: 'ip_prefix', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.ip_prefix', { + defaultMessage: 'Truncates an IP to a given prefix length.', + }), + alias: undefined, + signatures: [ + { + params: [ + { + name: 'ip', + type: 'ip', + optional: false, + }, + { + name: 'prefixLengthV4', + type: 'number', + optional: false, + }, + { + name: 'prefixLengthV6', + type: 'number', + optional: false, + }, + ], + returnType: 'ip', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: [ + 'row ip4 = to_ip("1.2.3.4"), ip6 = to_ip("fe80::cae2:65ff:fece:feb9")\n| eval ip4_prefix = ip_prefix(ip4, 24, 0), ip6_prefix = ip_prefix(ip6, 0, 112);', + ], +}; + const leastDefinition: FunctionDefinition = { type: 'eval', name: 'least', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.least', { defaultMessage: - 'Returns the minimum value from multiple columns. This is similar to <> except it is intended to run on multiple columns at once.', - ignoreTag: true, + 'Returns the minimum value from multiple columns. This is similar to `MV_MIN` except it is intended to run on multiple columns at once.', }), alias: undefined, signatures: [ @@ -1444,20 +1193,185 @@ const ltrimDefinition: FunctionDefinition = { { params: [ { - name: 'string', - type: 'string', + name: 'string', + type: 'string', + optional: false, + }, + ], + returnType: 'string', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: [ + 'ROW message = " some text ", color = " red "\n| EVAL message = LTRIM(message)\n| EVAL color = LTRIM(color)\n| EVAL message = CONCAT("\'", message, "\'")\n| EVAL color = CONCAT("\'", color, "\'")', + ], +}; + +const mvAppendDefinition: FunctionDefinition = { + type: 'eval', + name: 'mv_append', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.mv_append', { + defaultMessage: 'Concatenates values of two multi-value fields.', + }), + alias: undefined, + signatures: [ + { + params: [ + { + name: 'field1', + type: 'boolean', + optional: false, + }, + { + name: 'field2', + type: 'boolean', + optional: false, + }, + ], + returnType: 'boolean', + }, + { + params: [ + { + name: 'field1', + type: 'cartesian_point', + optional: false, + }, + { + name: 'field2', + type: 'cartesian_point', + optional: false, + }, + ], + returnType: 'cartesian_point', + }, + { + params: [ + { + name: 'field1', + type: 'cartesian_shape', + optional: false, + }, + { + name: 'field2', + type: 'cartesian_shape', + optional: false, + }, + ], + returnType: 'cartesian_shape', + }, + { + params: [ + { + name: 'field1', + type: 'date', + optional: false, + }, + { + name: 'field2', + type: 'date', + optional: false, + }, + ], + returnType: 'date', + }, + { + params: [ + { + name: 'field1', + type: 'number', + optional: false, + }, + { + name: 'field2', + type: 'number', + optional: false, + }, + ], + returnType: 'number', + }, + { + params: [ + { + name: 'field1', + type: 'geo_point', + optional: false, + }, + { + name: 'field2', + type: 'geo_point', + optional: false, + }, + ], + returnType: 'geo_point', + }, + { + params: [ + { + name: 'field1', + type: 'geo_shape', + optional: false, + }, + { + name: 'field2', + type: 'geo_shape', + optional: false, + }, + ], + returnType: 'geo_shape', + }, + { + params: [ + { + name: 'field1', + type: 'ip', + optional: false, + }, + { + name: 'field2', + type: 'ip', + optional: false, + }, + ], + returnType: 'ip', + }, + { + params: [ + { + name: 'field1', + type: 'string', + optional: false, + }, + { + name: 'field2', + type: 'string', + optional: false, + }, + ], + returnType: 'string', + }, + { + params: [ + { + name: 'field1', + type: 'version', + optional: false, + }, + { + name: 'field2', + type: 'version', optional: false, }, ], - returnType: 'string', + returnType: 'version', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: [ - 'ROW message = " some text ", color = " red "\n| EVAL message = LTRIM(message)\n| EVAL color = LTRIM(color)\n| EVAL message = CONCAT("\'", message, "\'")\n| EVAL color = CONCAT("\'", color, "\'")', - ], + examples: [], }; const mvAvgDefinition: FunctionDefinition = { @@ -1756,8 +1670,7 @@ const mvFirstDefinition: FunctionDefinition = { name: 'mv_first', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.mv_first', { defaultMessage: - "Converts a multivalued expression into a single valued column containing the\nfirst value. This is most useful when reading from a function that emits\nmultivalued columns in a known order like <>.\n\nThe order that <> are read from\nunderlying storage is not guaranteed. It is *frequently* ascending, but don't\nrely on that. If you need the minimum value use <> instead of\n`MV_FIRST`. `MV_MIN` has optimizations for sorted values so there isn't a\nperformance benefit to `MV_FIRST`.", - ignoreTag: true, + "Converts a multivalued expression into a single valued column containing the\nfirst value. This is most useful when reading from a function that emits\nmultivalued columns in a known order like `SPLIT`.\n\nThe order that multivalued fields are read from\nunderlying storage is not guaranteed. It is *frequently* ascending, but don't\nrely on that. If you need the minimum value use `MV_MIN` instead of\n`MV_FIRST`. `MV_MIN` has optimizations for sorted values so there isn't a\nperformance benefit to `MV_FIRST`.", }), alias: undefined, signatures: [ @@ -1873,8 +1786,7 @@ const mvLastDefinition: FunctionDefinition = { name: 'mv_last', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.mv_last', { defaultMessage: - "Converts a multivalue expression into a single valued column containing the last\nvalue. This is most useful when reading from a function that emits multivalued\ncolumns in a known order like <>.\n\nThe order that <> are read from\nunderlying storage is not guaranteed. It is *frequently* ascending, but don't\nrely on that. If you need the maximum value use <> instead of\n`MV_LAST`. `MV_MAX` has optimizations for sorted values so there isn't a\nperformance benefit to `MV_LAST`.", - ignoreTag: true, + "Converts a multivalue expression into a single valued column containing the last\nvalue. This is most useful when reading from a function that emits multivalued\ncolumns in a known order like `SPLIT`.\n\nThe order that multivalued fields are read from\nunderlying storage is not guaranteed. It is *frequently* ascending, but don't\nrely on that. If you need the maximum value use `MV_MAX` instead of\n`MV_LAST`. `MV_MAX` has optimizations for sorted values so there isn't a\nperformance benefit to `MV_LAST`.", }), alias: undefined, signatures: [ @@ -2913,8 +2825,7 @@ const stContainsDefinition: FunctionDefinition = { name: 'st_contains', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_contains', { defaultMessage: - 'Returns whether the first geometry contains the second geometry.\nThis is the inverse of the <> function.', - ignoreTag: true, + 'Returns whether the first geometry contains the second geometry.\nThis is the inverse of the `ST_WITHIN` function.', }), alias: undefined, signatures: [ @@ -3052,8 +2963,7 @@ const stDisjointDefinition: FunctionDefinition = { name: 'st_disjoint', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_disjoint', { defaultMessage: - 'Returns whether the two geometries or geometry columns are disjoint.\nThis is the inverse of the <> function.\nIn mathematical terms: ST_Disjoint(A, B) ⇔ A ⋂ B = ∅', - ignoreTag: true, + 'Returns whether the two geometries or geometry columns are disjoint.\nThis is the inverse of the `ST_INTERSECTS` function.\nIn mathematical terms: ST_Disjoint(A, B) ⇔ A ⋂ B = ∅', }), alias: undefined, signatures: [ @@ -3191,8 +3101,7 @@ const stIntersectsDefinition: FunctionDefinition = { name: 'st_intersects', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_intersects', { defaultMessage: - 'Returns true if two geometries intersect.\nThey intersect if they have any point in common, including their interior points\n(points along lines or within polygons).\nThis is the inverse of the <> function.\nIn mathematical terms: ST_Intersects(A, B) ⇔ A ⋂ B ≠ ∅', - ignoreTag: true, + 'Returns true if two geometries intersect.\nThey intersect if they have any point in common, including their interior points\n(points along lines or within polygons).\nThis is the inverse of the `ST_DISJOINT` function.\nIn mathematical terms: ST_Intersects(A, B) ⇔ A ⋂ B ≠ ∅', }), alias: undefined, signatures: [ @@ -3330,8 +3239,7 @@ const stWithinDefinition: FunctionDefinition = { name: 'st_within', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_within', { defaultMessage: - 'Returns whether the first geometry is within the second geometry.\nThis is the inverse of the <> function.', - ignoreTag: true, + 'Returns whether the first geometry is within the second geometry.\nThis is the inverse of the `ST_CONTAINS` function.', }), alias: undefined, signatures: [ @@ -3373,53 +3281,352 @@ const stWithinDefinition: FunctionDefinition = { optional: false, }, { - name: 'geomB', - type: 'cartesian_point', + name: 'geomB', + type: 'cartesian_point', + optional: false, + }, + ], + returnType: 'boolean', + }, + { + params: [ + { + name: 'geomA', + type: 'cartesian_shape', + optional: false, + }, + { + name: 'geomB', + type: 'cartesian_shape', + optional: false, + }, + ], + returnType: 'boolean', + }, + { + params: [ + { + name: 'geomA', + type: 'geo_point', + optional: false, + }, + { + name: 'geomB', + type: 'geo_point', + optional: false, + }, + ], + returnType: 'boolean', + }, + { + params: [ + { + name: 'geomA', + type: 'geo_point', + optional: false, + }, + { + name: 'geomB', + type: 'geo_shape', + optional: false, + }, + ], + returnType: 'boolean', + }, + { + params: [ + { + name: 'geomA', + type: 'geo_shape', + optional: false, + }, + { + name: 'geomB', + type: 'geo_point', + optional: false, + }, + ], + returnType: 'boolean', + }, + { + params: [ + { + name: 'geomA', + type: 'geo_shape', + optional: false, + }, + { + name: 'geomB', + type: 'geo_shape', + optional: false, + }, + ], + returnType: 'boolean', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: [ + 'FROM airport_city_boundaries\n| WHERE ST_WITHIN(city_boundary, TO_GEOSHAPE("POLYGON((109.1 18.15, 109.6 18.15, 109.6 18.65, 109.1 18.65, 109.1 18.15))"))\n| KEEP abbrev, airport, region, city, city_location', + ], +}; + +const stXDefinition: FunctionDefinition = { + type: 'eval', + name: 'st_x', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_x', { + defaultMessage: + 'Extracts the `x` coordinate from the supplied point.\nIf the points is of type `geo_point` this is equivalent to extracting the `longitude` value.', + }), + alias: undefined, + signatures: [ + { + params: [ + { + name: 'point', + type: 'cartesian_point', + optional: false, + }, + ], + returnType: 'number', + }, + { + params: [ + { + name: 'point', + type: 'geo_point', + optional: false, + }, + ], + returnType: 'number', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: [ + 'ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)")\n| EVAL x = ST_X(point), y = ST_Y(point)', + ], +}; + +const stYDefinition: FunctionDefinition = { + type: 'eval', + name: 'st_y', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_y', { + defaultMessage: + 'Extracts the `y` coordinate from the supplied point.\nIf the points is of type `geo_point` this is equivalent to extracting the `latitude` value.', + }), + alias: undefined, + signatures: [ + { + params: [ + { + name: 'point', + type: 'cartesian_point', + optional: false, + }, + ], + returnType: 'number', + }, + { + params: [ + { + name: 'point', + type: 'geo_point', + optional: false, + }, + ], + returnType: 'number', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: [ + 'ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)")\n| EVAL x = ST_X(point), y = ST_Y(point)', + ], +}; + +const startsWithDefinition: FunctionDefinition = { + type: 'eval', + name: 'starts_with', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.starts_with', { + defaultMessage: + 'Returns a boolean that indicates whether a keyword string starts with another string.', + }), + alias: undefined, + signatures: [ + { + params: [ + { + name: 'str', + type: 'string', + optional: false, + }, + { + name: 'prefix', + type: 'string', + optional: false, + }, + ], + returnType: 'boolean', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: ['FROM employees\n| KEEP last_name\n| EVAL ln_S = STARTS_WITH(last_name, "B")'], +}; + +const substringDefinition: FunctionDefinition = { + type: 'eval', + name: 'substring', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.substring', { + defaultMessage: + 'Returns a substring of a string, specified by a start position and an optional length', + }), + alias: undefined, + signatures: [ + { + params: [ + { + name: 'string', + type: 'string', + optional: false, + }, + { + name: 'start', + type: 'number', + optional: false, + }, + { + name: 'length', + type: 'number', + optional: true, + }, + ], + returnType: 'string', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: [ + 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, 1, 3)', + 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, -3, 3)', + 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, 2)', + ], +}; + +const tanDefinition: FunctionDefinition = { + type: 'eval', + name: 'tan', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tan', { + defaultMessage: 'Returns the Tangent trigonometric function of an angle.', + }), + alias: undefined, + signatures: [ + { + params: [ + { + name: 'angle', + type: 'number', optional: false, }, ], - returnType: 'boolean', + returnType: 'number', }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: ['ROW a=1.8 \n| EVAL tan=TAN(a)'], +}; + +const tanhDefinition: FunctionDefinition = { + type: 'eval', + name: 'tanh', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tanh', { + defaultMessage: 'Returns the Tangent hyperbolic function of an angle.', + }), + alias: undefined, + signatures: [ { params: [ { - name: 'geomA', - type: 'cartesian_shape', - optional: false, - }, - { - name: 'geomB', - type: 'cartesian_shape', + name: 'angle', + type: 'number', optional: false, }, ], - returnType: 'boolean', + returnType: 'number', + }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: ['ROW a=1.8 \n| EVAL tanh=TANH(a)'], +}; + +const tauDefinition: FunctionDefinition = { + type: 'eval', + name: 'tau', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tau', { + defaultMessage: "Returns the ratio of a circle's circumference to its radius.", + }), + alias: undefined, + signatures: [ + { + params: [], + returnType: 'number', }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: ['ROW TAU()'], +}; + +const toBase64Definition: FunctionDefinition = { + type: 'eval', + name: 'to_base64', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_base64', { + defaultMessage: 'Encode a string to a base64 string.', + }), + alias: undefined, + signatures: [ { params: [ { - name: 'geomA', - type: 'geo_point', - optional: false, - }, - { - name: 'geomB', - type: 'geo_point', + name: 'string', + type: 'string', optional: false, }, ], - returnType: 'boolean', + returnType: 'string', }, + ], + supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], + supportedOptions: ['by'], + validate: undefined, + examples: ['row a = "elastic" \n| eval e = to_base64(a)'], +}; + +const toBooleanDefinition: FunctionDefinition = { + type: 'eval', + name: 'to_boolean', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_boolean', { + defaultMessage: + 'Converts an input value to a boolean value.\nA string value of *true* will be case-insensitive converted to the Boolean *true*.\nFor anything else, including the empty string, the function will return *false*.\nThe numerical value of *0* will be converted to *false*, anything else will be converted to *true*.', + }), + alias: ['to_bool'], + signatures: [ { params: [ { - name: 'geomA', - type: 'geo_point', - optional: false, - }, - { - name: 'geomB', - type: 'geo_shape', + name: 'field', + type: 'boolean', optional: false, }, ], @@ -3428,13 +3635,8 @@ const stWithinDefinition: FunctionDefinition = { { params: [ { - name: 'geomA', - type: 'geo_shape', - optional: false, - }, - { - name: 'geomB', - type: 'geo_point', + name: 'field', + type: 'number', optional: false, }, ], @@ -3443,13 +3645,8 @@ const stWithinDefinition: FunctionDefinition = { { params: [ { - name: 'geomA', - type: 'geo_shape', - optional: false, - }, - { - name: 'geomB', - type: 'geo_shape', + name: 'field', + type: 'string', optional: false, }, ], @@ -3459,170 +3656,162 @@ const stWithinDefinition: FunctionDefinition = { supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: [ - 'FROM airport_city_boundaries\n| WHERE ST_WITHIN(city_boundary, TO_GEOSHAPE("POLYGON((109.1 18.15, 109.6 18.15, 109.6 18.65, 109.1 18.65, 109.1 18.15))"))\n| KEEP abbrev, airport, region, city, city_location', - ], + examples: ['ROW str = ["true", "TRuE", "false", "", "yes", "1"]\n| EVAL bool = TO_BOOLEAN(str)'], }; -const stXDefinition: FunctionDefinition = { +const toCartesianpointDefinition: FunctionDefinition = { type: 'eval', - name: 'st_x', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_x', { - defaultMessage: - 'Extracts the `x` coordinate from the supplied point.\nIf the points is of type `geo_point` this is equivalent to extracting the `longitude` value.', - }), + name: 'to_cartesianpoint', + description: i18n.translate( + 'kbn-esql-validation-autocomplete.esql.definitions.to_cartesianpoint', + { + defaultMessage: + 'Converts an input value to a `cartesian_point` value.\nA string will only be successfully converted if it respects WKT Point format.', + } + ), alias: undefined, signatures: [ { params: [ { - name: 'point', + name: 'field', type: 'cartesian_point', optional: false, }, ], - returnType: 'number', + returnType: 'cartesian_point', }, { params: [ { - name: 'point', - type: 'geo_point', + name: 'field', + type: 'string', optional: false, }, ], - returnType: 'number', + returnType: 'cartesian_point', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, examples: [ - 'ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)")\n| EVAL x = ST_X(point), y = ST_Y(point)', + 'ROW wkt = ["POINT(4297.11 -1475.53)", "POINT(7580.93 2272.77)"]\n| MV_EXPAND wkt\n| EVAL pt = TO_CARTESIANPOINT(wkt)', ], }; -const stYDefinition: FunctionDefinition = { +const toCartesianshapeDefinition: FunctionDefinition = { type: 'eval', - name: 'st_y', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_y', { - defaultMessage: - 'Extracts the `y` coordinate from the supplied point.\nIf the points is of type `geo_point` this is equivalent to extracting the `latitude` value.', - }), + name: 'to_cartesianshape', + description: i18n.translate( + 'kbn-esql-validation-autocomplete.esql.definitions.to_cartesianshape', + { + defaultMessage: + 'Converts an input value to a `cartesian_shape` value.\nA string will only be successfully converted if it respects WKT format.', + } + ), alias: undefined, signatures: [ { params: [ { - name: 'point', + name: 'field', type: 'cartesian_point', optional: false, }, ], - returnType: 'number', + returnType: 'cartesian_shape', }, { params: [ { - name: 'point', - type: 'geo_point', + name: 'field', + type: 'cartesian_shape', optional: false, }, ], - returnType: 'number', + returnType: 'cartesian_shape', }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: [ - 'ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)")\n| EVAL x = ST_X(point), y = ST_Y(point)', - ], -}; - -const startsWithDefinition: FunctionDefinition = { - type: 'eval', - name: 'starts_with', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.starts_with', { - defaultMessage: - 'Returns a boolean that indicates whether a keyword string starts with another string.', - }), - alias: undefined, - signatures: [ { params: [ { - name: 'str', - type: 'string', - optional: false, - }, - { - name: 'prefix', + name: 'field', type: 'string', optional: false, }, ], - returnType: 'boolean', + returnType: 'cartesian_shape', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['FROM employees\n| KEEP last_name\n| EVAL ln_S = STARTS_WITH(last_name, "B")'], + examples: [ + 'ROW wkt = ["POINT(4297.11 -1475.53)", "POLYGON ((3339584.72 1118889.97, 4452779.63 4865942.27, 2226389.81 4865942.27, 1113194.90 2273030.92, 3339584.72 1118889.97))"]\n| MV_EXPAND wkt\n| EVAL geom = TO_CARTESIANSHAPE(wkt)', + ], }; -const substringDefinition: FunctionDefinition = { +const toDatetimeDefinition: FunctionDefinition = { type: 'eval', - name: 'substring', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.substring', { + name: 'to_datetime', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_datetime', { defaultMessage: - 'Returns a substring of a string, specified by a start position and an optional length', + "Converts an input value to a date value.\nA string will only be successfully converted if it's respecting the format `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`.\nTo convert dates in other formats, use `DATE_PARSE`.", }), - alias: undefined, + alias: ['to_dt'], signatures: [ { params: [ { - name: 'string', - type: 'string', + name: 'field', + type: 'date', optional: false, }, + ], + returnType: 'date', + }, + { + params: [ { - name: 'start', + name: 'field', type: 'number', optional: false, }, + ], + returnType: 'date', + }, + { + params: [ { - name: 'length', - type: 'number', - optional: true, + name: 'field', + type: 'string', + optional: false, }, ], - returnType: 'string', + returnType: 'date', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, examples: [ - 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, 1, 3)', - 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, -3, 3)', - 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, 2)', + 'ROW string = ["1953-09-02T00:00:00.000Z", "1964-06-02T00:00:00.000Z", "1964-06-02 00:00:00"]\n| EVAL datetime = TO_DATETIME(string)', + 'ROW int = [0, 1]\n| EVAL dt = TO_DATETIME(int)', ], }; -const tanDefinition: FunctionDefinition = { +const toDegreesDefinition: FunctionDefinition = { type: 'eval', - name: 'tan', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tan', { - defaultMessage: 'Returns the Tangent trigonometric function of an angle.', + name: 'to_degrees', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_degrees', { + defaultMessage: 'Converts a number in radians to degrees.', }), alias: undefined, signatures: [ { params: [ { - name: 'angle', + name: 'number', type: 'number', optional: false, }, @@ -3633,86 +3822,159 @@ const tanDefinition: FunctionDefinition = { supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW a=1.8 \n| EVAL tan=TAN(a)'], + examples: ['ROW rad = [1.57, 3.14, 4.71]\n| EVAL deg = TO_DEGREES(rad)'], }; -const tanhDefinition: FunctionDefinition = { +const toDoubleDefinition: FunctionDefinition = { type: 'eval', - name: 'tanh', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tanh', { - defaultMessage: 'Returns the Tangent hyperbolic function of an angle.', + name: 'to_double', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_double', { + defaultMessage: + 'Converts an input value to a double value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch,\nconverted to double. Boolean *true* will be converted to double *1.0*, *false* to *0.0*.', }), - alias: undefined, + alias: ['to_dbl'], signatures: [ { params: [ { - name: 'angle', + name: 'field', + type: 'boolean', + optional: false, + }, + ], + returnType: 'number', + }, + { + params: [ + { + name: 'field', type: 'number', optional: false, }, ], returnType: 'number', }, + { + params: [ + { + name: 'field', + type: 'date', + optional: false, + }, + ], + returnType: 'number', + }, + { + params: [ + { + name: 'field', + type: 'string', + optional: false, + }, + ], + returnType: 'number', + }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW a=1.8 \n| EVAL tanh=TANH(a)'], + examples: [ + 'ROW str1 = "5.20128E11", str2 = "foo"\n| EVAL dbl = TO_DOUBLE("520128000000"), dbl1 = TO_DOUBLE(str1), dbl2 = TO_DOUBLE(str2)', + ], }; -const tauDefinition: FunctionDefinition = { +const toGeopointDefinition: FunctionDefinition = { type: 'eval', - name: 'tau', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tau', { - defaultMessage: "Returns the ratio of a circle's circumference to its radius.", + name: 'to_geopoint', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_geopoint', { + defaultMessage: + 'Converts an input value to a `geo_point` value.\nA string will only be successfully converted if it respects WKT Point format.', }), alias: undefined, signatures: [ { - params: [], - returnType: 'number', + params: [ + { + name: 'field', + type: 'geo_point', + optional: false, + }, + ], + returnType: 'geo_point', + }, + { + params: [ + { + name: 'field', + type: 'string', + optional: false, + }, + ], + returnType: 'geo_point', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW TAU()'], + examples: ['ROW wkt = "POINT(42.97109630194 14.7552534413725)"\n| EVAL pt = TO_GEOPOINT(wkt)'], }; -const toBase64Definition: FunctionDefinition = { +const toGeoshapeDefinition: FunctionDefinition = { type: 'eval', - name: 'to_base64', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_base64', { - defaultMessage: 'Encode a string to a base64 string.', + name: 'to_geoshape', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_geoshape', { + defaultMessage: + 'Converts an input value to a `geo_shape` value.\nA string will only be successfully converted if it respects WKT format.', }), alias: undefined, signatures: [ { params: [ { - name: 'string', + name: 'field', + type: 'geo_point', + optional: false, + }, + ], + returnType: 'geo_shape', + }, + { + params: [ + { + name: 'field', + type: 'geo_shape', + optional: false, + }, + ], + returnType: 'geo_shape', + }, + { + params: [ + { + name: 'field', type: 'string', optional: false, }, ], - returnType: 'string', + returnType: 'geo_shape', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['row a = "elastic" \n| eval e = to_base64(a)'], + examples: [ + 'ROW wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"\n| EVAL geom = TO_GEOSHAPE(wkt)', + ], }; -const toBooleanDefinition: FunctionDefinition = { +const toIntegerDefinition: FunctionDefinition = { type: 'eval', - name: 'to_boolean', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_boolean', { + name: 'to_integer', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_integer', { defaultMessage: - 'Converts an input value to a boolean value.\nA string value of *true* will be case-insensitive converted to the Boolean *true*.\nFor anything else, including the empty string, the function will return *false*.\nThe numerical value of *0* will be converted to *false*, anything else will be converted to *true*.', + 'Converts an input value to an integer value.\nIf the input parameter is of a date type, its value will be interpreted as milliseconds\nsince the Unix epoch, converted to integer.\nBoolean *true* will be converted to integer *1*, *false* to *0*.', }), - alias: ['to_bool'], + alias: ['to_int'], signatures: [ { params: [ @@ -3722,7 +3984,7 @@ const toBooleanDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'boolean', + returnType: 'number', }, { params: [ @@ -3732,7 +3994,17 @@ const toBooleanDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'boolean', + returnType: 'number', + }, + { + params: [ + { + name: 'field', + type: 'date', + optional: false, + }, + ], + returnType: 'number', }, { params: [ @@ -3742,36 +4014,32 @@ const toBooleanDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'boolean', + returnType: 'number', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW str = ["true", "TRuE", "false", "", "yes", "1"]\n| EVAL bool = TO_BOOLEAN(str)'], + examples: ['ROW long = [5013792, 2147483647, 501379200000]\n| EVAL int = TO_INTEGER(long)'], }; -const toCartesianpointDefinition: FunctionDefinition = { +const toIpDefinition: FunctionDefinition = { type: 'eval', - name: 'to_cartesianpoint', - description: i18n.translate( - 'kbn-esql-validation-autocomplete.esql.definitions.to_cartesianpoint', - { - defaultMessage: - 'Converts an input value to a `cartesian_point` value.\nA string will only be successfully converted if it respects WKT Point format.', - } - ), + name: 'to_ip', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_ip', { + defaultMessage: 'Converts an input string to an IP value.', + }), alias: undefined, signatures: [ { params: [ { name: 'field', - type: 'cartesian_point', + type: 'ip', optional: false, }, ], - returnType: 'cartesian_point', + returnType: 'ip', }, { params: [ @@ -3781,48 +4049,55 @@ const toCartesianpointDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'cartesian_point', + returnType: 'ip', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, examples: [ - 'ROW wkt = ["POINT(4297.11 -1475.53)", "POINT(7580.93 2272.77)"]\n| MV_EXPAND wkt\n| EVAL pt = TO_CARTESIANPOINT(wkt)', + 'ROW str1 = "1.1.1.1", str2 = "foo"\n| EVAL ip1 = TO_IP(str1), ip2 = TO_IP(str2)\n| WHERE CIDR_MATCH(ip1, "1.0.0.0/8")', ], }; -const toCartesianshapeDefinition: FunctionDefinition = { +const toLongDefinition: FunctionDefinition = { type: 'eval', - name: 'to_cartesianshape', - description: i18n.translate( - 'kbn-esql-validation-autocomplete.esql.definitions.to_cartesianshape', - { - defaultMessage: - 'Converts an input value to a `cartesian_shape` value.\nA string will only be successfully converted if it respects WKT format.', - } - ), + name: 'to_long', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_long', { + defaultMessage: + 'Converts an input value to a long value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch, converted to long.\nBoolean *true* will be converted to long *1*, *false* to *0*.', + }), alias: undefined, signatures: [ { params: [ { name: 'field', - type: 'cartesian_point', + type: 'boolean', optional: false, }, ], - returnType: 'cartesian_shape', + returnType: 'number', }, { params: [ { name: 'field', - type: 'cartesian_shape', + type: 'number', optional: false, }, ], - returnType: 'cartesian_shape', + returnType: 'number', + }, + { + params: [ + { + name: 'field', + type: 'date', + optional: false, + }, + ], + returnType: 'number', }, { params: [ @@ -3832,72 +4107,47 @@ const toCartesianshapeDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'cartesian_shape', + returnType: 'number', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, examples: [ - 'ROW wkt = ["POINT(4297.11 -1475.53)", "POLYGON ((3339584.72 1118889.97, 4452779.63 4865942.27, 2226389.81 4865942.27, 1113194.90 2273030.92, 3339584.72 1118889.97))"]\n| MV_EXPAND wkt\n| EVAL geom = TO_CARTESIANSHAPE(wkt)', + 'ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo"\n| EVAL long1 = TO_LONG(str1), long2 = TO_LONG(str2), long3 = TO_LONG(str3)', ], }; -const toDatetimeDefinition: FunctionDefinition = { +const toLowerDefinition: FunctionDefinition = { type: 'eval', - name: 'to_datetime', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_datetime', { - defaultMessage: - "Converts an input value to a date value.\nA string will only be successfully converted if it's respecting the format `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`.\nTo convert dates in other formats, use <>.", - ignoreTag: true, + name: 'to_lower', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_lower', { + defaultMessage: 'Returns a new string representing the input string converted to lower case.', }), - alias: ['to_dt'], + alias: undefined, signatures: [ { params: [ { - name: 'field', - type: 'date', - optional: false, - }, - ], - returnType: 'date', - }, - { - params: [ - { - name: 'field', - type: 'number', - optional: false, - }, - ], - returnType: 'date', - }, - { - params: [ - { - name: 'field', + name: 'str', type: 'string', optional: false, }, ], - returnType: 'date', + returnType: 'string', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: [ - 'ROW string = ["1953-09-02T00:00:00.000Z", "1964-06-02T00:00:00.000Z", "1964-06-02 00:00:00"]\n| EVAL datetime = TO_DATETIME(string)', - 'ROW int = [0, 1]\n| EVAL dt = TO_DATETIME(int)', - ], + examples: ['ROW message = "Some Text"\n| EVAL message_lower = TO_LOWER(message)'], }; -const toDegreesDefinition: FunctionDefinition = { +const toRadiansDefinition: FunctionDefinition = { type: 'eval', - name: 'to_degrees', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_degrees', { - defaultMessage: 'Converts a number in radians to degrees.', + name: 'to_radians', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_radians', { + defaultMessage: 'Converts a number in degrees to radians.', }), alias: undefined, signatures: [ @@ -3915,17 +4165,16 @@ const toDegreesDefinition: FunctionDefinition = { supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW rad = [1.57, 3.14, 4.71]\n| EVAL deg = TO_DEGREES(rad)'], + examples: ['ROW deg = [90.0, 180.0, 270.0]\n| EVAL rad = TO_RADIANS(deg)'], }; -const toDoubleDefinition: FunctionDefinition = { +const toStringDefinition: FunctionDefinition = { type: 'eval', - name: 'to_double', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_double', { - defaultMessage: - 'Converts an input value to a double value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch,\nconverted to double. Boolean *true* will be converted to double *1.0*, *false* to *0.0*.', + name: 'to_string', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_string', { + defaultMessage: 'Converts an input value into a string.', }), - alias: ['to_dbl'], + alias: ['to_str'], signatures: [ { params: [ @@ -3935,17 +4184,27 @@ const toDoubleDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'number', + returnType: 'string', }, { params: [ { name: 'field', - type: 'number', + type: 'cartesian_point', optional: false, }, ], - returnType: 'number', + returnType: 'string', + }, + { + params: [ + { + name: 'field', + type: 'cartesian_shape', + optional: false, + }, + ], + returnType: 'string', }, { params: [ @@ -3955,36 +4214,18 @@ const toDoubleDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'number', + returnType: 'string', }, { params: [ { name: 'field', - type: 'string', + type: 'number', optional: false, }, ], - returnType: 'number', + returnType: 'string', }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: [ - 'ROW str1 = "5.20128E11", str2 = "foo"\n| EVAL dbl = TO_DOUBLE("520128000000"), dbl1 = TO_DOUBLE(str1), dbl2 = TO_DOUBLE(str2)', - ], -}; - -const toGeopointDefinition: FunctionDefinition = { - type: 'eval', - name: 'to_geopoint', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_geopoint', { - defaultMessage: - 'Converts an input value to a `geo_point` value.\nA string will only be successfully converted if it respects WKT Point format.', - }), - alias: undefined, - signatures: [ { params: [ { @@ -3993,81 +4234,66 @@ const toGeopointDefinition: FunctionDefinition = { optional: false, }, ], - returnType: 'geo_point', + returnType: 'string', }, { params: [ { name: 'field', - type: 'string', + type: 'geo_shape', optional: false, }, ], - returnType: 'geo_point', + returnType: 'string', }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: ['ROW wkt = "POINT(42.97109630194 14.7552534413725)"\n| EVAL pt = TO_GEOPOINT(wkt)'], -}; - -const toGeoshapeDefinition: FunctionDefinition = { - type: 'eval', - name: 'to_geoshape', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_geoshape', { - defaultMessage: - 'Converts an input value to a `geo_shape` value.\nA string will only be successfully converted if it respects WKT format.', - }), - alias: undefined, - signatures: [ { params: [ { name: 'field', - type: 'geo_point', + type: 'ip', optional: false, }, ], - returnType: 'geo_shape', + returnType: 'string', }, { params: [ { name: 'field', - type: 'geo_shape', + type: 'string', optional: false, }, ], - returnType: 'geo_shape', + returnType: 'string', }, { params: [ { name: 'field', - type: 'string', + type: 'version', optional: false, }, ], - returnType: 'geo_shape', + returnType: 'string', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: [ - 'ROW wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"\n| EVAL geom = TO_GEOSHAPE(wkt)', - ], + examples: ['ROW a=10\n| EVAL j = TO_STRING(a)', 'ROW a=[10, 9, 8]\n| EVAL j = TO_STRING(a)'], }; -const toIntegerDefinition: FunctionDefinition = { +const toUnsignedLongDefinition: FunctionDefinition = { type: 'eval', - name: 'to_integer', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_integer', { - defaultMessage: - 'Converts an input value to an integer value.\nIf the input parameter is of a date type, its value will be interpreted as milliseconds\nsince the Unix epoch, converted to integer.\nBoolean *true* will be converted to integer *1*, *false* to *0*.', - }), - alias: ['to_int'], + name: 'to_unsigned_long', + description: i18n.translate( + 'kbn-esql-validation-autocomplete.esql.definitions.to_unsigned_long', + { + defaultMessage: + 'Converts an input value to an unsigned long value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch, converted to unsigned long.\nBoolean *true* will be converted to unsigned long *1*, *false* to *0*.', + } + ), + alias: ['to_ul', 'to_ulong'], signatures: [ { params: [ @@ -4083,7 +4309,7 @@ const toIntegerDefinition: FunctionDefinition = { params: [ { name: 'field', - type: 'number', + type: 'date', optional: false, }, ], @@ -4093,7 +4319,7 @@ const toIntegerDefinition: FunctionDefinition = { params: [ { name: 'field', - type: 'date', + type: 'number', optional: false, }, ], @@ -4113,116 +4339,83 @@ const toIntegerDefinition: FunctionDefinition = { supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW long = [5013792, 2147483647, 501379200000]\n| EVAL int = TO_INTEGER(long)'], + examples: [ + 'ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo"\n| EVAL long1 = TO_UNSIGNED_LONG(str1), long2 = TO_ULONG(str2), long3 = TO_UL(str3)', + ], }; -const toIpDefinition: FunctionDefinition = { +const toUpperDefinition: FunctionDefinition = { type: 'eval', - name: 'to_ip', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_ip', { - defaultMessage: 'Converts an input string to an IP value.', + name: 'to_upper', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_upper', { + defaultMessage: 'Returns a new string representing the input string converted to upper case.', }), alias: undefined, signatures: [ { params: [ { - name: 'field', - type: 'ip', - optional: false, - }, - ], - returnType: 'ip', - }, - { - params: [ - { - name: 'field', + name: 'str', type: 'string', optional: false, }, ], - returnType: 'ip', + returnType: 'string', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: [ - 'ROW str1 = "1.1.1.1", str2 = "foo"\n| EVAL ip1 = TO_IP(str1), ip2 = TO_IP(str2)\n| WHERE CIDR_MATCH(ip1, "1.0.0.0/8")', - ], + examples: ['ROW message = "Some Text"\n| EVAL message_upper = TO_UPPER(message)'], }; -const toLongDefinition: FunctionDefinition = { +const toVersionDefinition: FunctionDefinition = { type: 'eval', - name: 'to_long', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_long', { - defaultMessage: - 'Converts an input value to a long value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch, converted to long.\nBoolean *true* will be converted to long *1*, *false* to *0*.', + name: 'to_version', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_version', { + defaultMessage: 'Converts an input string to a version value.', }), - alias: undefined, + alias: ['to_ver'], signatures: [ { params: [ { name: 'field', - type: 'boolean', - optional: false, - }, - ], - returnType: 'number', - }, - { - params: [ - { - name: 'field', - type: 'number', - optional: false, - }, - ], - returnType: 'number', - }, - { - params: [ - { - name: 'field', - type: 'date', + type: 'string', optional: false, }, ], - returnType: 'number', + returnType: 'version', }, { params: [ { name: 'field', - type: 'string', + type: 'version', optional: false, }, ], - returnType: 'number', + returnType: 'version', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: [ - 'ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo"\n| EVAL long1 = TO_LONG(str1), long2 = TO_LONG(str2), long3 = TO_LONG(str3)', - ], + examples: ['ROW v = TO_VERSION("1.2.3")'], }; -const toLowerDefinition: FunctionDefinition = { +const trimDefinition: FunctionDefinition = { type: 'eval', - name: 'to_lower', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_lower', { - defaultMessage: 'Returns a new string representing the input string converted to lower case.', + name: 'trim', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.trim', { + defaultMessage: 'Removes leading and trailing whitespaces from a string.', }), alias: undefined, signatures: [ { params: [ { - name: 'str', + name: 'string', type: 'string', optional: false, }, @@ -4233,327 +4426,327 @@ const toLowerDefinition: FunctionDefinition = { supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW message = "Some Text"\n| EVAL message_lower = TO_LOWER(message)'], + examples: [ + 'ROW message = " some text ", color = " red "\n| EVAL message = TRIM(message)\n| EVAL color = TRIM(color)', + ], }; -const toRadiansDefinition: FunctionDefinition = { +const caseDefinition: FunctionDefinition = { type: 'eval', - name: 'to_radians', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_radians', { - defaultMessage: 'Converts a number in degrees to radians.', + name: 'case', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.case', { + defaultMessage: + 'Accepts pairs of conditions and values. The function returns the value that belongs to the first condition that evaluates to `true`. If the number of arguments is odd, the last argument is the default value which is returned when no condition matches.', }), alias: undefined, signatures: [ { params: [ { - name: 'number', - type: 'number', - optional: false, + name: 'condition', + type: 'boolean', + }, + { + name: 'value', + type: 'any', }, ], - returnType: 'number', + minParams: 2, + returnType: 'any', }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW deg = [90.0, 180.0, 270.0]\n| EVAL rad = TO_RADIANS(deg)'], + examples: [ + 'from index | eval type = case(languages <= 1, "monolingual", languages <= 2, "bilingual", "polyglot")', + ], }; -const toStringDefinition: FunctionDefinition = { +const coalesceDefinition: FunctionDefinition = { type: 'eval', - name: 'to_string', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_string', { - defaultMessage: 'Converts an input value into a string.', + name: 'coalesce', + description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.coalesce', { + defaultMessage: + 'Returns the first of its arguments that is not null. If all arguments are null, it returns `null`.', }), - alias: ['to_str'], + alias: undefined, signatures: [ { params: [ { - name: 'field', - type: 'boolean', + name: 'first', + type: 'number', optional: false, }, ], - returnType: 'string', + returnType: 'number', + minParams: 1, }, { params: [ { - name: 'field', - type: 'cartesian_point', + name: 'first', + type: 'number', + optional: false, + }, + { + name: 'rest', + type: 'number', + optional: true, + }, + ], + returnType: 'number', + minParams: 1, + }, + { + params: [ + { + name: 'first', + type: 'date', optional: false, }, ], - returnType: 'string', + returnType: 'date', + minParams: 1, }, { params: [ { - name: 'field', - type: 'cartesian_shape', + name: 'first', + type: 'date', optional: false, }, + { + name: 'rest', + type: 'date', + optional: true, + }, ], - returnType: 'string', + returnType: 'date', + minParams: 1, }, { params: [ { - name: 'field', - type: 'date', + name: 'first', + type: 'string', optional: false, }, ], returnType: 'string', + minParams: 1, }, { params: [ { - name: 'field', - type: 'number', + name: 'first', + type: 'string', optional: false, }, + { + name: 'rest', + type: 'string', + optional: true, + }, ], returnType: 'string', + minParams: 1, }, { params: [ { - name: 'field', - type: 'geo_point', + name: 'first', + type: 'boolean', optional: false, }, ], - returnType: 'string', + returnType: 'boolean', + minParams: 1, }, { params: [ { - name: 'field', - type: 'geo_shape', + name: 'first', + type: 'boolean', optional: false, }, + { + name: 'rest', + type: 'boolean', + optional: true, + }, ], - returnType: 'string', + returnType: 'boolean', + minParams: 1, }, { params: [ { - name: 'field', + name: 'first', type: 'ip', optional: false, }, ], - returnType: 'string', + returnType: 'ip', + minParams: 1, }, { params: [ { - name: 'field', - type: 'string', + name: 'first', + type: 'ip', optional: false, }, + { + name: 'rest', + type: 'ip', + optional: true, + }, ], - returnType: 'string', + returnType: 'ip', + minParams: 1, }, { params: [ { - name: 'field', - type: 'version', + name: 'first', + type: 'cartesian_point', optional: false, }, ], - returnType: 'string', + returnType: 'cartesian_point', + minParams: 1, }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: ['ROW a=10\n| EVAL j = TO_STRING(a)', 'ROW a=[10, 9, 8]\n| EVAL j = TO_STRING(a)'], -}; - -const toUnsignedLongDefinition: FunctionDefinition = { - type: 'eval', - name: 'to_unsigned_long', - description: i18n.translate( - 'kbn-esql-validation-autocomplete.esql.definitions.to_unsigned_long', - { - defaultMessage: - 'Converts an input value to an unsigned long value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch, converted to unsigned long.\nBoolean *true* will be converted to unsigned long *1*, *false* to *0*.', - } - ), - alias: ['to_ul', 'to_ulong'], - signatures: [ { params: [ { - name: 'field', - type: 'boolean', + name: 'first', + type: 'cartesian_point', optional: false, }, + { + name: 'rest', + type: 'cartesian_point', + optional: true, + }, ], - returnType: 'number', + returnType: 'cartesian_point', + minParams: 1, }, { params: [ { - name: 'field', - type: 'date', + name: 'first', + type: 'cartesian_shape', optional: false, }, ], - returnType: 'number', + returnType: 'cartesian_shape', + minParams: 1, }, { params: [ { - name: 'field', - type: 'number', + name: 'first', + type: 'cartesian_shape', optional: false, }, + { + name: 'rest', + type: 'cartesian_shape', + optional: true, + }, ], - returnType: 'number', + returnType: 'cartesian_shape', + minParams: 1, }, { params: [ { - name: 'field', - type: 'string', + name: 'first', + type: 'geo_point', optional: false, }, ], - returnType: 'number', + returnType: 'geo_point', + minParams: 1, }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: [ - 'ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo"\n| EVAL long1 = TO_UNSIGNED_LONG(str1), long2 = TO_ULONG(str2), long3 = TO_UL(str3)', - ], -}; - -const toUpperDefinition: FunctionDefinition = { - type: 'eval', - name: 'to_upper', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_upper', { - defaultMessage: 'Returns a new string representing the input string converted to upper case.', - }), - alias: undefined, - signatures: [ { params: [ { - name: 'str', - type: 'string', + name: 'first', + type: 'geo_point', optional: false, }, + { + name: 'rest', + type: 'geo_point', + optional: true, + }, ], - returnType: 'string', + returnType: 'geo_point', + minParams: 1, }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: ['ROW message = "Some Text"\n| EVAL message_upper = TO_UPPER(message)'], -}; - -const toVersionDefinition: FunctionDefinition = { - type: 'eval', - name: 'to_version', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_version', { - defaultMessage: 'Converts an input string to a version value.', - }), - alias: ['to_ver'], - signatures: [ { params: [ { - name: 'field', - type: 'string', + name: 'first', + type: 'geo_shape', optional: false, }, ], - returnType: 'version', + returnType: 'geo_shape', + minParams: 1, }, { params: [ { - name: 'field', - type: 'version', + name: 'first', + type: 'geo_shape', optional: false, }, + { + name: 'rest', + type: 'geo_shape', + optional: true, + }, ], - returnType: 'version', + returnType: 'geo_shape', + minParams: 1, }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: ['ROW v = TO_VERSION("1.2.3")'], -}; - -const trimDefinition: FunctionDefinition = { - type: 'eval', - name: 'trim', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.trim', { - defaultMessage: 'Removes leading and trailing whitespaces from a string.', - }), - alias: undefined, - signatures: [ { params: [ { - name: 'string', - type: 'string', + name: 'first', + type: 'version', optional: false, }, ], - returnType: 'string', + returnType: 'version', + minParams: 1, }, - ], - supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], - supportedOptions: ['by'], - validate: undefined, - examples: [ - 'ROW message = " some text ", color = " red "\n| EVAL message = TRIM(message)\n| EVAL color = TRIM(color)', - ], -}; - -const caseDefinition: FunctionDefinition = { - type: 'eval', - name: 'case', - description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.case', { - defaultMessage: - 'Accepts pairs of conditions and values. The function returns the value that belongs to the first condition that evaluates to `true`. If the number of arguments is odd, the last argument is the default value which is returned when no condition matches.', - }), - alias: undefined, - signatures: [ { params: [ { - name: 'condition', - type: 'boolean', + name: 'first', + type: 'version', + optional: false, }, { - name: 'value', - type: 'any', + name: 'rest', + type: 'version', + optional: true, }, ], - minParams: 2, - returnType: 'any', + returnType: 'version', + minParams: 1, }, ], supportedCommands: ['stats', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: [ - 'from index | eval type = case(languages <= 1, "monolingual", languages <= 2, "bilingual", "polyglot")', - ], + examples: ['ROW a=null, b="b"\n| EVAL COALESCE(a, b)'], }; export const evalFunctionDefinitions = [ absDefinition, @@ -4564,7 +4757,6 @@ export const evalFunctionDefinitions = [ cbrtDefinition, ceilDefinition, cidrMatchDefinition, - coalesceDefinition, concatDefinition, cosDefinition, coshDefinition, @@ -4578,6 +4770,7 @@ export const evalFunctionDefinitions = [ floorDefinition, fromBase64Definition, greatestDefinition, + ipPrefixDefinition, leastDefinition, leftDefinition, lengthDefinition, @@ -4585,6 +4778,7 @@ export const evalFunctionDefinitions = [ logDefinition, log10Definition, ltrimDefinition, + mvAppendDefinition, mvAvgDefinition, mvConcatDefinition, mvCountDefinition, @@ -4641,4 +4835,5 @@ export const evalFunctionDefinitions = [ toVersionDefinition, trimDefinition, caseDefinition, + coalesceDefinition, ]; diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json b/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json index 08fcd159d2be5..3315ead65d9e9 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json +++ b/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json @@ -9886,61 +9886,6 @@ "error": [], "warning": [] }, - { - "query": "row var = coalesce(\"a\")", - "error": [], - "warning": [] - }, - { - "query": "row coalesce(\"a\")", - "error": [], - "warning": [] - }, - { - "query": "from a_index | eval var = coalesce(stringField)", - "error": [], - "warning": [] - }, - { - "query": "from a_index | eval coalesce(stringField)", - "error": [], - "warning": [] - }, - { - "query": "from a_index | sort coalesce(stringField)", - "error": [], - "warning": [] - }, - { - "query": "row var = coalesce(true)", - "error": [], - "warning": [] - }, - { - "query": "row coalesce(true)", - "error": [], - "warning": [] - }, - { - "query": "row var = coalesce(to_boolean(true))", - "error": [], - "warning": [] - }, - { - "query": "row var = coalesce(true, true)", - "error": [], - "warning": [] - }, - { - "query": "row coalesce(true, true)", - "error": [], - "warning": [] - }, - { - "query": "row var = coalesce(to_boolean(true), to_boolean(true))", - "error": [], - "warning": [] - }, { "query": "row var = coalesce(5)", "error": [], @@ -9972,437 +9917,412 @@ "warning": [] }, { - "query": "row var = coalesce(to_string(true))", - "error": [], - "warning": [] - }, - { - "query": "row var = coalesce(\"a\", \"a\")", - "error": [], - "warning": [] - }, - { - "query": "row coalesce(\"a\", \"a\")", - "error": [], - "warning": [] - }, - { - "query": "row var = coalesce(to_string(true), to_string(true))", - "error": [], - "warning": [] - }, - { - "query": "from a_index | where coalesce(numberField) > 0", + "query": "row var = coalesce(now())", "error": [], "warning": [] }, { - "query": "from a_index | where coalesce(numberField, numberField) > 0", + "query": "row coalesce(now())", "error": [], "warning": [] }, { - "query": "from a_index | where length(coalesce(stringField)) > 0", + "query": "row var = coalesce(to_datetime(now()))", "error": [], "warning": [] }, { - "query": "from a_index | where length(coalesce(stringField, stringField)) > 0", + "query": "row var = coalesce(now(), now())", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(booleanField)", + "query": "row coalesce(now(), now())", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(booleanField)", + "query": "row var = coalesce(to_datetime(now()), to_datetime(now()))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_boolean(booleanField))", + "query": "row var = coalesce(\"a\")", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(booleanField, booleanField)", + "query": "row coalesce(\"a\")", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(booleanField, booleanField)", + "query": "row var = coalesce(to_string(true))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_boolean(booleanField), to_boolean(booleanField))", + "query": "row var = coalesce(\"a\", \"a\")", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(numberField)", + "query": "row coalesce(\"a\", \"a\")", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(numberField)", + "query": "row var = coalesce(to_string(true), to_string(true))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_integer(booleanField))", + "query": "row var = coalesce(true)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(numberField, numberField)", + "query": "row coalesce(true)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(numberField, numberField)", + "query": "row var = coalesce(to_boolean(true))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_integer(booleanField), to_integer(booleanField))", + "query": "row var = coalesce(true, true)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_string(booleanField))", + "query": "row coalesce(true, true)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(stringField, stringField)", + "query": "row var = coalesce(to_boolean(true), to_boolean(true))", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(stringField, stringField)", + "query": "row var = coalesce(to_ip(\"127.0.0.1\"))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_string(booleanField), to_string(booleanField))", + "query": "row coalesce(to_ip(\"127.0.0.1\"))", "error": [], "warning": [] }, { - "query": "from a_index | sort coalesce(booleanField)", + "query": "row var = coalesce(to_ip(to_ip(\"127.0.0.1\")))", "error": [], "warning": [] }, { - "query": "row var = coalesce(5, true)", + "query": "row var = coalesce(to_ip(\"127.0.0.1\"), to_ip(\"127.0.0.1\"))", "error": [], "warning": [] }, { - "query": "row coalesce(5, true)", + "query": "row coalesce(to_ip(\"127.0.0.1\"), to_ip(\"127.0.0.1\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_integer(true), to_boolean(true))", + "query": "row var = coalesce(to_ip(to_ip(\"127.0.0.1\")), to_ip(to_ip(\"127.0.0.1\")))", "error": [], "warning": [] }, { - "query": "row var = coalesce(now())", + "query": "row var = coalesce(to_cartesianpoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row coalesce(now())", + "query": "row coalesce(to_cartesianpoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_datetime(now()))", + "query": "row var = coalesce(to_cartesianpoint(to_cartesianpoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row var = coalesce(now(), true)", + "query": "row var = coalesce(to_cartesianpoint(\"POINT (30 10)\"), to_cartesianpoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row coalesce(now(), true)", + "query": "row coalesce(to_cartesianpoint(\"POINT (30 10)\"), to_cartesianpoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_datetime(now()), to_boolean(true))", + "query": "row var = coalesce(to_cartesianpoint(to_cartesianpoint(\"POINT (30 10)\")), to_cartesianpoint(to_cartesianpoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row var = coalesce(\"a\", true)", + "query": "row var = coalesce(to_cartesianshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row coalesce(\"a\", true)", + "query": "row coalesce(to_cartesianshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_string(true), to_boolean(true))", + "query": "row var = coalesce(to_cartesianshape(to_cartesianpoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_ip(\"127.0.0.1\"))", + "query": "row var = coalesce(to_cartesianshape(\"POINT (30 10)\"), to_cartesianshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row coalesce(to_ip(\"127.0.0.1\"))", + "query": "row coalesce(to_cartesianshape(\"POINT (30 10)\"), to_cartesianshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_ip(to_ip(\"127.0.0.1\")))", + "query": "row var = coalesce(to_cartesianshape(to_cartesianpoint(\"POINT (30 10)\")), to_cartesianshape(to_cartesianpoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_ip(\"127.0.0.1\"), true)", - "error": [], - "warning": [] - }, - { - "query": "row coalesce(to_ip(\"127.0.0.1\"), true)", + "query": "row var = coalesce(to_geopoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_ip(to_ip(\"127.0.0.1\")), to_boolean(true))", + "query": "row coalesce(to_geopoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianpoint(\"POINT (30 10)\"))", + "query": "row var = coalesce(to_geopoint(to_geopoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row coalesce(to_cartesianpoint(\"POINT (30 10)\"))", + "query": "row var = coalesce(to_geopoint(\"POINT (30 10)\"), to_geopoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianpoint(to_cartesianpoint(\"POINT (30 10)\")))", + "query": "row coalesce(to_geopoint(\"POINT (30 10)\"), to_geopoint(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianpoint(\"POINT (30 10)\"), true)", + "query": "row var = coalesce(to_geopoint(to_geopoint(\"POINT (30 10)\")), to_geopoint(to_geopoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row coalesce(to_cartesianpoint(\"POINT (30 10)\"), true)", + "query": "row var = coalesce(to_geoshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianpoint(to_cartesianpoint(\"POINT (30 10)\")), to_boolean(true))", + "query": "row coalesce(to_geoshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianshape(\"POINT (30 10)\"))", + "query": "row var = coalesce(to_geoshape(to_geopoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row coalesce(to_cartesianshape(\"POINT (30 10)\"))", + "query": "row var = coalesce(to_geoshape(\"POINT (30 10)\"), to_geoshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianshape(to_cartesianpoint(\"POINT (30 10)\")))", + "query": "row coalesce(to_geoshape(\"POINT (30 10)\"), to_geoshape(\"POINT (30 10)\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianshape(\"POINT (30 10)\"), true)", + "query": "row var = coalesce(to_geoshape(to_geopoint(\"POINT (30 10)\")), to_geoshape(to_geopoint(\"POINT (30 10)\")))", "error": [], "warning": [] }, { - "query": "row coalesce(to_cartesianshape(\"POINT (30 10)\"), true)", + "query": "row var = coalesce(to_version(\"1.0.0\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_cartesianshape(to_cartesianpoint(\"POINT (30 10)\")), to_boolean(true))", + "query": "row coalesce(to_version(\"1.0.0\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geopoint(\"POINT (30 10)\"))", + "query": "row var = coalesce(to_version(\"a\"))", "error": [], "warning": [] }, { - "query": "row coalesce(to_geopoint(\"POINT (30 10)\"))", + "query": "row var = coalesce(to_version(\"1.0.0\"), to_version(\"1.0.0\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geopoint(to_geopoint(\"POINT (30 10)\")))", + "query": "row coalesce(to_version(\"1.0.0\"), to_version(\"1.0.0\"))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geopoint(\"POINT (30 10)\"), true)", + "query": "row var = coalesce(to_version(\"a\"), to_version(\"a\"))", "error": [], "warning": [] }, { - "query": "row coalesce(to_geopoint(\"POINT (30 10)\"), true)", + "query": "from a_index | where coalesce(numberField) > 0", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geopoint(to_geopoint(\"POINT (30 10)\")), to_boolean(true))", + "query": "from a_index | where coalesce(numberField, numberField) > 0", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geoshape(\"POINT (30 10)\"))", + "query": "from a_index | where length(coalesce(stringField)) > 0", "error": [], "warning": [] }, { - "query": "row coalesce(to_geoshape(\"POINT (30 10)\"))", + "query": "from a_index | where length(coalesce(stringField, stringField)) > 0", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geoshape(to_geopoint(\"POINT (30 10)\")))", + "query": "from a_index | eval var = coalesce(numberField)", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geoshape(\"POINT (30 10)\"), true)", + "query": "from a_index | eval coalesce(numberField)", "error": [], "warning": [] }, { - "query": "row coalesce(to_geoshape(\"POINT (30 10)\"), true)", + "query": "from a_index | eval var = coalesce(to_integer(booleanField))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_geoshape(to_geopoint(\"POINT (30 10)\")), to_boolean(true))", + "query": "from a_index | eval var = coalesce(numberField, numberField)", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_version(\"1.0.0\"))", + "query": "from a_index | eval coalesce(numberField, numberField)", "error": [], "warning": [] }, { - "query": "row coalesce(to_version(\"1.0.0\"))", + "query": "from a_index | eval var = coalesce(to_integer(booleanField), to_integer(booleanField))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_version(\"a\"))", + "query": "from a_index | eval var = coalesce(dateField)", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_version(\"1.0.0\"), true)", + "query": "from a_index | eval coalesce(dateField)", "error": [], "warning": [] }, { - "query": "row coalesce(to_version(\"1.0.0\"), true)", + "query": "from a_index | eval var = coalesce(to_datetime(dateField))", "error": [], "warning": [] }, { - "query": "row var = coalesce(to_version(\"a\"), to_boolean(true))", + "query": "from a_index | eval var = coalesce(dateField, dateField)", "error": [], "warning": [] }, { - "query": "from a_index | where coalesce(numberField, booleanField) > 0", + "query": "from a_index | eval coalesce(dateField, dateField)", "error": [], "warning": [] }, { - "query": "from a_index | where length(coalesce(stringField, booleanField)) > 0", + "query": "from a_index | eval var = coalesce(to_datetime(dateField), to_datetime(dateField))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(numberField, booleanField)", + "query": "from a_index | eval var = coalesce(stringField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(numberField, booleanField)", + "query": "from a_index | eval coalesce(stringField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_integer(booleanField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_string(booleanField))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(dateField)", + "query": "from a_index | eval var = coalesce(stringField, stringField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(dateField)", + "query": "from a_index | eval coalesce(stringField, stringField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_datetime(dateField))", + "query": "from a_index | eval var = coalesce(to_string(booleanField), to_string(booleanField))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(dateField, booleanField)", + "query": "from a_index | eval var = coalesce(booleanField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(dateField, booleanField)", + "query": "from a_index | eval coalesce(booleanField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_datetime(dateField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_boolean(booleanField))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(stringField, booleanField)", + "query": "from a_index | eval var = coalesce(booleanField, booleanField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(stringField, booleanField)", + "query": "from a_index | eval coalesce(booleanField, booleanField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_string(booleanField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_boolean(booleanField), to_boolean(booleanField))", "error": [], "warning": [] }, @@ -10422,17 +10342,17 @@ "warning": [] }, { - "query": "from a_index | eval var = coalesce(ipField, booleanField)", + "query": "from a_index | eval var = coalesce(ipField, ipField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(ipField, booleanField)", + "query": "from a_index | eval coalesce(ipField, ipField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_ip(ipField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_ip(ipField), to_ip(ipField))", "error": [], "warning": [] }, @@ -10441,23 +10361,28 @@ "error": [], "warning": [] }, + { + "query": "from a_index | eval coalesce(cartesianPointField)", + "error": [], + "warning": [] + }, { "query": "from a_index | eval var = coalesce(to_cartesianpoint(cartesianPointField))", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(cartesianPointField, booleanField)", + "query": "from a_index | eval var = coalesce(cartesianPointField, cartesianPointField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(cartesianPointField, booleanField)", + "query": "from a_index | eval coalesce(cartesianPointField, cartesianPointField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_cartesianpoint(cartesianPointField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_cartesianpoint(cartesianPointField), to_cartesianpoint(cartesianPointField))", "error": [], "warning": [] }, @@ -10477,17 +10402,17 @@ "warning": [] }, { - "query": "from a_index | eval var = coalesce(cartesianShapeField, booleanField)", + "query": "from a_index | eval var = coalesce(cartesianShapeField, cartesianShapeField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(cartesianShapeField, booleanField)", + "query": "from a_index | eval coalesce(cartesianShapeField, cartesianShapeField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_cartesianshape(cartesianPointField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_cartesianshape(cartesianPointField), to_cartesianshape(cartesianPointField))", "error": [], "warning": [] }, @@ -10507,17 +10432,17 @@ "warning": [] }, { - "query": "from a_index | eval var = coalesce(geoPointField, booleanField)", + "query": "from a_index | eval var = coalesce(geoPointField, geoPointField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(geoPointField, booleanField)", + "query": "from a_index | eval coalesce(geoPointField, geoPointField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_geopoint(geoPointField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_geopoint(geoPointField), to_geopoint(geoPointField))", "error": [], "warning": [] }, @@ -10537,17 +10462,17 @@ "warning": [] }, { - "query": "from a_index | eval var = coalesce(geoShapeField, booleanField)", + "query": "from a_index | eval var = coalesce(geoShapeField, geoShapeField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(geoShapeField, booleanField)", + "query": "from a_index | eval coalesce(geoShapeField, geoShapeField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_geoshape(geoPointField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_geoshape(geoPointField), to_geoshape(geoPointField))", "error": [], "warning": [] }, @@ -10567,17 +10492,17 @@ "warning": [] }, { - "query": "from a_index | eval var = coalesce(versionField, booleanField)", + "query": "from a_index | eval var = coalesce(versionField, versionField)", "error": [], "warning": [] }, { - "query": "from a_index | eval coalesce(versionField, booleanField)", + "query": "from a_index | eval coalesce(versionField, versionField)", "error": [], "warning": [] }, { - "query": "from a_index | eval var = coalesce(to_version(stringField), to_boolean(booleanField))", + "query": "from a_index | eval var = coalesce(to_version(stringField), to_version(stringField))", "error": [], "warning": [] }, @@ -10586,11 +10511,6 @@ "error": [], "warning": [] }, - { - "query": "from a_index | eval coalesce(cartesianPointField)", - "error": [], - "warning": [] - }, { "query": "from a_index | eval coalesce(null)", "error": [], @@ -25322,6 +25242,408 @@ "query": "row nullVar = null | eval to_base64(nullVar)", "error": [], "warning": [] + }, + { + "query": "row var = ip_prefix(to_ip(\"127.0.0.1\"), 5, 5)", + "error": [], + "warning": [] + }, + { + "query": "row ip_prefix(to_ip(\"127.0.0.1\"), 5, 5)", + "error": [], + "warning": [] + }, + { + "query": "row var = ip_prefix(to_ip(to_ip(\"127.0.0.1\")), to_integer(true), to_integer(true))", + "error": [], + "warning": [] + }, + { + "query": "row var = ip_prefix(true, true, true)", + "error": [ + "Argument of [ip_prefix] must be [ip], found value [true] type [boolean]", + "Argument of [ip_prefix] must be [number], found value [true] type [boolean]", + "Argument of [ip_prefix] must be [number], found value [true] type [boolean]" + ], + "warning": [] + }, + { + "query": "from a_index | eval var = ip_prefix(ipField, numberField, numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval ip_prefix(ipField, numberField, numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = ip_prefix(to_ip(ipField), to_integer(booleanField), to_integer(booleanField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval ip_prefix(booleanField, booleanField, booleanField)", + "error": [ + "Argument of [ip_prefix] must be [ip], found value [booleanField] type [boolean]", + "Argument of [ip_prefix] must be [number], found value [booleanField] type [boolean]", + "Argument of [ip_prefix] must be [number], found value [booleanField] type [boolean]" + ], + "warning": [] + }, + { + "query": "from a_index | eval ip_prefix(ipField, numberField, numberField, extraArg)", + "error": [ + "Error: [ip_prefix] function expects exactly 3 arguments, got 4." + ], + "warning": [] + }, + { + "query": "from a_index | sort ip_prefix(ipField, numberField, numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval ip_prefix(null, null, null)", + "error": [], + "warning": [] + }, + { + "query": "row nullVar = null | eval ip_prefix(nullVar, nullVar, nullVar)", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(true, true)", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(true, true)", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_boolean(true), to_boolean(true))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_cartesianpoint(\"POINT (30 10)\"), to_cartesianpoint(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(to_cartesianpoint(\"POINT (30 10)\"), to_cartesianpoint(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_cartesianpoint(to_cartesianpoint(\"POINT (30 10)\")), to_cartesianpoint(to_cartesianpoint(\"POINT (30 10)\")))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_cartesianshape(\"POINT (30 10)\"), to_cartesianshape(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(to_cartesianshape(\"POINT (30 10)\"), to_cartesianshape(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_cartesianshape(to_cartesianpoint(\"POINT (30 10)\")), to_cartesianshape(to_cartesianpoint(\"POINT (30 10)\")))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(now(), now())", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(now(), now())", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_datetime(now()), to_datetime(now()))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(5, 5)", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(5, 5)", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_integer(true), to_integer(true))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_geopoint(\"POINT (30 10)\"), to_geopoint(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(to_geopoint(\"POINT (30 10)\"), to_geopoint(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_geopoint(to_geopoint(\"POINT (30 10)\")), to_geopoint(to_geopoint(\"POINT (30 10)\")))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_geoshape(\"POINT (30 10)\"), to_geoshape(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(to_geoshape(\"POINT (30 10)\"), to_geoshape(\"POINT (30 10)\"))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_geoshape(to_geopoint(\"POINT (30 10)\")), to_geoshape(to_geopoint(\"POINT (30 10)\")))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_ip(\"127.0.0.1\"), to_ip(\"127.0.0.1\"))", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(to_ip(\"127.0.0.1\"), to_ip(\"127.0.0.1\"))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_ip(to_ip(\"127.0.0.1\")), to_ip(to_ip(\"127.0.0.1\")))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(\"a\", \"a\")", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(\"a\", \"a\")", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_string(true), to_string(true))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_version(\"1.0.0\"), to_version(\"1.0.0\"))", + "error": [], + "warning": [] + }, + { + "query": "row mv_append(to_version(\"1.0.0\"), to_version(\"1.0.0\"))", + "error": [], + "warning": [] + }, + { + "query": "row var = mv_append(to_version(\"a\"), to_version(\"a\"))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | where mv_append(numberField, numberField) > 0", + "error": [], + "warning": [] + }, + { + "query": "from a_index | where length(mv_append(stringField, stringField)) > 0", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(booleanField, booleanField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(booleanField, booleanField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_boolean(booleanField), to_boolean(booleanField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(cartesianPointField, cartesianPointField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(cartesianPointField, cartesianPointField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_cartesianpoint(cartesianPointField), to_cartesianpoint(cartesianPointField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(cartesianShapeField, cartesianShapeField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(cartesianShapeField, cartesianShapeField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_cartesianshape(cartesianPointField), to_cartesianshape(cartesianPointField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(dateField, dateField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(dateField, dateField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_datetime(dateField), to_datetime(dateField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(numberField, numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(numberField, numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_integer(booleanField), to_integer(booleanField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(geoPointField, geoPointField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(geoPointField, geoPointField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_geopoint(geoPointField), to_geopoint(geoPointField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(geoShapeField, geoShapeField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(geoShapeField, geoShapeField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_geoshape(geoPointField), to_geoshape(geoPointField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(ipField, ipField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(ipField, ipField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_ip(ipField), to_ip(ipField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(stringField, stringField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(stringField, stringField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_string(booleanField), to_string(booleanField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(versionField, versionField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(versionField, versionField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = mv_append(to_version(stringField), to_version(stringField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(booleanField, booleanField, extraArg)", + "error": [ + "Error: [mv_append] function expects exactly 2 arguments, got 3." + ], + "warning": [] + }, + { + "query": "from a_index | sort mv_append(booleanField, booleanField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval mv_append(null, null)", + "error": [], + "warning": [] + }, + { + "query": "row nullVar = null | eval mv_append(nullVar, nullVar)", + "error": [], + "warning": [] } ] } \ No newline at end of file diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts b/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts index 2ec3e2b5bbb6f..88e84aa66f2c8 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts @@ -2417,197 +2417,193 @@ describe('validation logic', () => { }); describe('coalesce', () => { - testErrorsAndWarnings('row var = coalesce("a")', []); - testErrorsAndWarnings('row coalesce("a")', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(stringField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(stringField)', []); - testErrorsAndWarnings('from a_index | sort coalesce(stringField)', []); - testErrorsAndWarnings('row var = coalesce(true)', []); - testErrorsAndWarnings('row coalesce(true)', []); - testErrorsAndWarnings('row var = coalesce(to_boolean(true))', []); - testErrorsAndWarnings('row var = coalesce(true, true)', []); - testErrorsAndWarnings('row coalesce(true, true)', []); - testErrorsAndWarnings('row var = coalesce(to_boolean(true), to_boolean(true))', []); testErrorsAndWarnings('row var = coalesce(5)', []); testErrorsAndWarnings('row coalesce(5)', []); testErrorsAndWarnings('row var = coalesce(to_integer(true))', []); testErrorsAndWarnings('row var = coalesce(5, 5)', []); testErrorsAndWarnings('row coalesce(5, 5)', []); testErrorsAndWarnings('row var = coalesce(to_integer(true), to_integer(true))', []); + testErrorsAndWarnings('row var = coalesce(now())', []); + testErrorsAndWarnings('row coalesce(now())', []); + testErrorsAndWarnings('row var = coalesce(to_datetime(now()))', []); + testErrorsAndWarnings('row var = coalesce(now(), now())', []); + testErrorsAndWarnings('row coalesce(now(), now())', []); + testErrorsAndWarnings('row var = coalesce(to_datetime(now()), to_datetime(now()))', []); + testErrorsAndWarnings('row var = coalesce("a")', []); + testErrorsAndWarnings('row coalesce("a")', []); testErrorsAndWarnings('row var = coalesce(to_string(true))', []); testErrorsAndWarnings('row var = coalesce("a", "a")', []); testErrorsAndWarnings('row coalesce("a", "a")', []); testErrorsAndWarnings('row var = coalesce(to_string(true), to_string(true))', []); - - testErrorsAndWarnings('from a_index | where coalesce(numberField) > 0', []); - - testErrorsAndWarnings('from a_index | where coalesce(numberField, numberField) > 0', []); - - testErrorsAndWarnings('from a_index | where length(coalesce(stringField)) > 0', []); + testErrorsAndWarnings('row var = coalesce(true)', []); + testErrorsAndWarnings('row coalesce(true)', []); + testErrorsAndWarnings('row var = coalesce(to_boolean(true))', []); + testErrorsAndWarnings('row var = coalesce(true, true)', []); + testErrorsAndWarnings('row coalesce(true, true)', []); + testErrorsAndWarnings('row var = coalesce(to_boolean(true), to_boolean(true))', []); + testErrorsAndWarnings('row var = coalesce(to_ip("127.0.0.1"))', []); + testErrorsAndWarnings('row coalesce(to_ip("127.0.0.1"))', []); + testErrorsAndWarnings('row var = coalesce(to_ip(to_ip("127.0.0.1")))', []); + testErrorsAndWarnings('row var = coalesce(to_ip("127.0.0.1"), to_ip("127.0.0.1"))', []); + testErrorsAndWarnings('row coalesce(to_ip("127.0.0.1"), to_ip("127.0.0.1"))', []); testErrorsAndWarnings( - 'from a_index | where length(coalesce(stringField, stringField)) > 0', + 'row var = coalesce(to_ip(to_ip("127.0.0.1")), to_ip(to_ip("127.0.0.1")))', [] ); - testErrorsAndWarnings('from a_index | eval var = coalesce(booleanField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(booleanField)', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(to_boolean(booleanField))', []); - - testErrorsAndWarnings('from a_index | eval var = coalesce(booleanField, booleanField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(booleanField, booleanField)', []); + testErrorsAndWarnings('row var = coalesce(to_cartesianpoint("POINT (30 10)"))', []); + testErrorsAndWarnings('row coalesce(to_cartesianpoint("POINT (30 10)"))', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_boolean(booleanField), to_boolean(booleanField))', + 'row var = coalesce(to_cartesianpoint(to_cartesianpoint("POINT (30 10)")))', [] ); - testErrorsAndWarnings('from a_index | eval var = coalesce(numberField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(numberField)', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(to_integer(booleanField))', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(numberField, numberField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(numberField, numberField)', []); - testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_integer(booleanField), to_integer(booleanField))', + 'row var = coalesce(to_cartesianpoint("POINT (30 10)"), to_cartesianpoint("POINT (30 10)"))', [] ); - testErrorsAndWarnings('from a_index | eval var = coalesce(to_string(booleanField))', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(stringField, stringField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(stringField, stringField)', []); - testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_string(booleanField), to_string(booleanField))', + 'row coalesce(to_cartesianpoint("POINT (30 10)"), to_cartesianpoint("POINT (30 10)"))', [] ); - testErrorsAndWarnings('from a_index | sort coalesce(booleanField)', []); - testErrorsAndWarnings('row var = coalesce(5, true)', []); - testErrorsAndWarnings('row coalesce(5, true)', []); - testErrorsAndWarnings('row var = coalesce(to_integer(true), to_boolean(true))', []); - testErrorsAndWarnings('row var = coalesce(now())', []); - testErrorsAndWarnings('row coalesce(now())', []); - testErrorsAndWarnings('row var = coalesce(to_datetime(now()))', []); - testErrorsAndWarnings('row var = coalesce(now(), true)', []); - testErrorsAndWarnings('row coalesce(now(), true)', []); - testErrorsAndWarnings('row var = coalesce(to_datetime(now()), to_boolean(true))', []); - testErrorsAndWarnings('row var = coalesce("a", true)', []); - testErrorsAndWarnings('row coalesce("a", true)', []); - testErrorsAndWarnings('row var = coalesce(to_string(true), to_boolean(true))', []); - testErrorsAndWarnings('row var = coalesce(to_ip("127.0.0.1"))', []); - testErrorsAndWarnings('row coalesce(to_ip("127.0.0.1"))', []); - testErrorsAndWarnings('row var = coalesce(to_ip(to_ip("127.0.0.1")))', []); - testErrorsAndWarnings('row var = coalesce(to_ip("127.0.0.1"), true)', []); - testErrorsAndWarnings('row coalesce(to_ip("127.0.0.1"), true)', []); testErrorsAndWarnings( - 'row var = coalesce(to_ip(to_ip("127.0.0.1")), to_boolean(true))', + 'row var = coalesce(to_cartesianpoint(to_cartesianpoint("POINT (30 10)")), to_cartesianpoint(to_cartesianpoint("POINT (30 10)")))', [] ); - testErrorsAndWarnings('row var = coalesce(to_cartesianpoint("POINT (30 10)"))', []); - testErrorsAndWarnings('row coalesce(to_cartesianpoint("POINT (30 10)"))', []); + + testErrorsAndWarnings('row var = coalesce(to_cartesianshape("POINT (30 10)"))', []); + testErrorsAndWarnings('row coalesce(to_cartesianshape("POINT (30 10)"))', []); testErrorsAndWarnings( - 'row var = coalesce(to_cartesianpoint(to_cartesianpoint("POINT (30 10)")))', + 'row var = coalesce(to_cartesianshape(to_cartesianpoint("POINT (30 10)")))', [] ); - testErrorsAndWarnings('row var = coalesce(to_cartesianpoint("POINT (30 10)"), true)', []); - testErrorsAndWarnings('row coalesce(to_cartesianpoint("POINT (30 10)"), true)', []); - testErrorsAndWarnings( - 'row var = coalesce(to_cartesianpoint(to_cartesianpoint("POINT (30 10)")), to_boolean(true))', + 'row var = coalesce(to_cartesianshape("POINT (30 10)"), to_cartesianshape("POINT (30 10)"))', [] ); - testErrorsAndWarnings('row var = coalesce(to_cartesianshape("POINT (30 10)"))', []); - testErrorsAndWarnings('row coalesce(to_cartesianshape("POINT (30 10)"))', []); - testErrorsAndWarnings( - 'row var = coalesce(to_cartesianshape(to_cartesianpoint("POINT (30 10)")))', + 'row coalesce(to_cartesianshape("POINT (30 10)"), to_cartesianshape("POINT (30 10)"))', [] ); - testErrorsAndWarnings('row var = coalesce(to_cartesianshape("POINT (30 10)"), true)', []); - testErrorsAndWarnings('row coalesce(to_cartesianshape("POINT (30 10)"), true)', []); - testErrorsAndWarnings( - 'row var = coalesce(to_cartesianshape(to_cartesianpoint("POINT (30 10)")), to_boolean(true))', + 'row var = coalesce(to_cartesianshape(to_cartesianpoint("POINT (30 10)")), to_cartesianshape(to_cartesianpoint("POINT (30 10)")))', [] ); testErrorsAndWarnings('row var = coalesce(to_geopoint("POINT (30 10)"))', []); testErrorsAndWarnings('row coalesce(to_geopoint("POINT (30 10)"))', []); testErrorsAndWarnings('row var = coalesce(to_geopoint(to_geopoint("POINT (30 10)")))', []); - testErrorsAndWarnings('row var = coalesce(to_geopoint("POINT (30 10)"), true)', []); - testErrorsAndWarnings('row coalesce(to_geopoint("POINT (30 10)"), true)', []); testErrorsAndWarnings( - 'row var = coalesce(to_geopoint(to_geopoint("POINT (30 10)")), to_boolean(true))', + 'row var = coalesce(to_geopoint("POINT (30 10)"), to_geopoint("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row coalesce(to_geopoint("POINT (30 10)"), to_geopoint("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row var = coalesce(to_geopoint(to_geopoint("POINT (30 10)")), to_geopoint(to_geopoint("POINT (30 10)")))', [] ); testErrorsAndWarnings('row var = coalesce(to_geoshape("POINT (30 10)"))', []); testErrorsAndWarnings('row coalesce(to_geoshape("POINT (30 10)"))', []); testErrorsAndWarnings('row var = coalesce(to_geoshape(to_geopoint("POINT (30 10)")))', []); - testErrorsAndWarnings('row var = coalesce(to_geoshape("POINT (30 10)"), true)', []); - testErrorsAndWarnings('row coalesce(to_geoshape("POINT (30 10)"), true)', []); testErrorsAndWarnings( - 'row var = coalesce(to_geoshape(to_geopoint("POINT (30 10)")), to_boolean(true))', + 'row var = coalesce(to_geoshape("POINT (30 10)"), to_geoshape("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row coalesce(to_geoshape("POINT (30 10)"), to_geoshape("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row var = coalesce(to_geoshape(to_geopoint("POINT (30 10)")), to_geoshape(to_geopoint("POINT (30 10)")))', [] ); testErrorsAndWarnings('row var = coalesce(to_version("1.0.0"))', []); testErrorsAndWarnings('row coalesce(to_version("1.0.0"))', []); testErrorsAndWarnings('row var = coalesce(to_version("a"))', []); - testErrorsAndWarnings('row var = coalesce(to_version("1.0.0"), true)', []); - testErrorsAndWarnings('row coalesce(to_version("1.0.0"), true)', []); - testErrorsAndWarnings('row var = coalesce(to_version("a"), to_boolean(true))', []); - testErrorsAndWarnings('from a_index | where coalesce(numberField, booleanField) > 0', []); + testErrorsAndWarnings('row var = coalesce(to_version("1.0.0"), to_version("1.0.0"))', []); + testErrorsAndWarnings('row coalesce(to_version("1.0.0"), to_version("1.0.0"))', []); + testErrorsAndWarnings('row var = coalesce(to_version("a"), to_version("a"))', []); + testErrorsAndWarnings('from a_index | where coalesce(numberField) > 0', []); + testErrorsAndWarnings('from a_index | where coalesce(numberField, numberField) > 0', []); + testErrorsAndWarnings('from a_index | where length(coalesce(stringField)) > 0', []); testErrorsAndWarnings( - 'from a_index | where length(coalesce(stringField, booleanField)) > 0', + 'from a_index | where length(coalesce(stringField, stringField)) > 0', [] ); - testErrorsAndWarnings('from a_index | eval var = coalesce(numberField, booleanField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(numberField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(numberField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(numberField)', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(to_integer(booleanField))', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(numberField, numberField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(numberField, numberField)', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_integer(booleanField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_integer(booleanField), to_integer(booleanField))', [] ); testErrorsAndWarnings('from a_index | eval var = coalesce(dateField)', []); testErrorsAndWarnings('from a_index | eval coalesce(dateField)', []); testErrorsAndWarnings('from a_index | eval var = coalesce(to_datetime(dateField))', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(dateField, booleanField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(dateField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(dateField, dateField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(dateField, dateField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = coalesce(to_datetime(dateField), to_datetime(dateField))', + [] + ); + + testErrorsAndWarnings('from a_index | eval var = coalesce(stringField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(stringField)', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(to_string(booleanField))', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(stringField, stringField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(stringField, stringField)', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_datetime(dateField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_string(booleanField), to_string(booleanField))', [] ); - testErrorsAndWarnings('from a_index | eval var = coalesce(stringField, booleanField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(stringField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(booleanField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(booleanField)', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(to_boolean(booleanField))', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(booleanField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(booleanField, booleanField)', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_string(booleanField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_boolean(booleanField), to_boolean(booleanField))', [] ); testErrorsAndWarnings('from a_index | eval var = coalesce(ipField)', []); testErrorsAndWarnings('from a_index | eval coalesce(ipField)', []); testErrorsAndWarnings('from a_index | eval var = coalesce(to_ip(ipField))', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(ipField, booleanField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(ipField, booleanField)', []); - + testErrorsAndWarnings('from a_index | eval var = coalesce(ipField, ipField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(ipField, ipField)', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_ip(ipField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_ip(ipField), to_ip(ipField))', [] ); - testErrorsAndWarnings('from a_index | eval var = coalesce(cartesianPointField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(cartesianPointField)', []); testErrorsAndWarnings( 'from a_index | eval var = coalesce(to_cartesianpoint(cartesianPointField))', @@ -2615,17 +2611,17 @@ describe('validation logic', () => { ); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(cartesianPointField, booleanField)', + 'from a_index | eval var = coalesce(cartesianPointField, cartesianPointField)', [] ); testErrorsAndWarnings( - 'from a_index | eval coalesce(cartesianPointField, booleanField)', + 'from a_index | eval coalesce(cartesianPointField, cartesianPointField)', [] ); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_cartesianpoint(cartesianPointField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_cartesianpoint(cartesianPointField), to_cartesianpoint(cartesianPointField))', [] ); @@ -2638,17 +2634,17 @@ describe('validation logic', () => { ); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(cartesianShapeField, booleanField)', + 'from a_index | eval var = coalesce(cartesianShapeField, cartesianShapeField)', [] ); testErrorsAndWarnings( - 'from a_index | eval coalesce(cartesianShapeField, booleanField)', + 'from a_index | eval coalesce(cartesianShapeField, cartesianShapeField)', [] ); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_cartesianshape(cartesianPointField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_cartesianshape(cartesianPointField), to_cartesianshape(cartesianPointField))', [] ); @@ -2656,13 +2652,13 @@ describe('validation logic', () => { testErrorsAndWarnings('from a_index | eval coalesce(geoPointField)', []); testErrorsAndWarnings('from a_index | eval var = coalesce(to_geopoint(geoPointField))', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(geoPointField, booleanField)', + 'from a_index | eval var = coalesce(geoPointField, geoPointField)', [] ); - testErrorsAndWarnings('from a_index | eval coalesce(geoPointField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(geoPointField, geoPointField)', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_geopoint(geoPointField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_geopoint(geoPointField), to_geopoint(geoPointField))', [] ); @@ -2670,29 +2666,28 @@ describe('validation logic', () => { testErrorsAndWarnings('from a_index | eval coalesce(geoShapeField)', []); testErrorsAndWarnings('from a_index | eval var = coalesce(to_geoshape(geoPointField))', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(geoShapeField, booleanField)', + 'from a_index | eval var = coalesce(geoShapeField, geoShapeField)', [] ); - testErrorsAndWarnings('from a_index | eval coalesce(geoShapeField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(geoShapeField, geoShapeField)', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_geoshape(geoPointField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_geoshape(geoPointField), to_geoshape(geoPointField))', [] ); testErrorsAndWarnings('from a_index | eval var = coalesce(versionField)', []); testErrorsAndWarnings('from a_index | eval coalesce(versionField)', []); testErrorsAndWarnings('from a_index | eval var = coalesce(to_version(stringField))', []); - testErrorsAndWarnings('from a_index | eval var = coalesce(versionField, booleanField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(versionField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval var = coalesce(versionField, versionField)', []); + testErrorsAndWarnings('from a_index | eval coalesce(versionField, versionField)', []); testErrorsAndWarnings( - 'from a_index | eval var = coalesce(to_version(stringField), to_boolean(booleanField))', + 'from a_index | eval var = coalesce(to_version(stringField), to_version(stringField))', [] ); testErrorsAndWarnings('from a_index | sort coalesce(numberField)', []); - testErrorsAndWarnings('from a_index | eval coalesce(cartesianPointField)', []); testErrorsAndWarnings('from a_index | eval coalesce(null)', []); testErrorsAndWarnings('row nullVar = null | eval coalesce(nullVar)', []); }); @@ -10082,6 +10077,263 @@ describe('validation logic', () => { testErrorsAndWarnings('from a_index | eval to_base64(null)', []); testErrorsAndWarnings('row nullVar = null | eval to_base64(nullVar)', []); }); + + describe('ip_prefix', () => { + testErrorsAndWarnings('row var = ip_prefix(to_ip("127.0.0.1"), 5, 5)', []); + testErrorsAndWarnings('row ip_prefix(to_ip("127.0.0.1"), 5, 5)', []); + + testErrorsAndWarnings( + 'row var = ip_prefix(to_ip(to_ip("127.0.0.1")), to_integer(true), to_integer(true))', + [] + ); + + testErrorsAndWarnings('row var = ip_prefix(true, true, true)', [ + 'Argument of [ip_prefix] must be [ip], found value [true] type [boolean]', + 'Argument of [ip_prefix] must be [number], found value [true] type [boolean]', + 'Argument of [ip_prefix] must be [number], found value [true] type [boolean]', + ]); + + testErrorsAndWarnings( + 'from a_index | eval var = ip_prefix(ipField, numberField, numberField)', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval ip_prefix(ipField, numberField, numberField)', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = ip_prefix(to_ip(ipField), to_integer(booleanField), to_integer(booleanField))', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval ip_prefix(booleanField, booleanField, booleanField)', + [ + 'Argument of [ip_prefix] must be [ip], found value [booleanField] type [boolean]', + 'Argument of [ip_prefix] must be [number], found value [booleanField] type [boolean]', + 'Argument of [ip_prefix] must be [number], found value [booleanField] type [boolean]', + ] + ); + + testErrorsAndWarnings( + 'from a_index | eval ip_prefix(ipField, numberField, numberField, extraArg)', + ['Error: [ip_prefix] function expects exactly 3 arguments, got 4.'] + ); + + testErrorsAndWarnings( + 'from a_index | sort ip_prefix(ipField, numberField, numberField)', + [] + ); + testErrorsAndWarnings('from a_index | eval ip_prefix(null, null, null)', []); + testErrorsAndWarnings('row nullVar = null | eval ip_prefix(nullVar, nullVar, nullVar)', []); + }); + + describe('mv_append', () => { + testErrorsAndWarnings('row var = mv_append(true, true)', []); + testErrorsAndWarnings('row mv_append(true, true)', []); + testErrorsAndWarnings('row var = mv_append(to_boolean(true), to_boolean(true))', []); + + testErrorsAndWarnings( + 'row var = mv_append(to_cartesianpoint("POINT (30 10)"), to_cartesianpoint("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row mv_append(to_cartesianpoint("POINT (30 10)"), to_cartesianpoint("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row var = mv_append(to_cartesianpoint(to_cartesianpoint("POINT (30 10)")), to_cartesianpoint(to_cartesianpoint("POINT (30 10)")))', + [] + ); + + testErrorsAndWarnings( + 'row var = mv_append(to_cartesianshape("POINT (30 10)"), to_cartesianshape("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row mv_append(to_cartesianshape("POINT (30 10)"), to_cartesianshape("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row var = mv_append(to_cartesianshape(to_cartesianpoint("POINT (30 10)")), to_cartesianshape(to_cartesianpoint("POINT (30 10)")))', + [] + ); + + testErrorsAndWarnings('row var = mv_append(now(), now())', []); + testErrorsAndWarnings('row mv_append(now(), now())', []); + testErrorsAndWarnings('row var = mv_append(to_datetime(now()), to_datetime(now()))', []); + testErrorsAndWarnings('row var = mv_append(5, 5)', []); + testErrorsAndWarnings('row mv_append(5, 5)', []); + testErrorsAndWarnings('row var = mv_append(to_integer(true), to_integer(true))', []); + + testErrorsAndWarnings( + 'row var = mv_append(to_geopoint("POINT (30 10)"), to_geopoint("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row mv_append(to_geopoint("POINT (30 10)"), to_geopoint("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row var = mv_append(to_geopoint(to_geopoint("POINT (30 10)")), to_geopoint(to_geopoint("POINT (30 10)")))', + [] + ); + + testErrorsAndWarnings( + 'row var = mv_append(to_geoshape("POINT (30 10)"), to_geoshape("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row mv_append(to_geoshape("POINT (30 10)"), to_geoshape("POINT (30 10)"))', + [] + ); + + testErrorsAndWarnings( + 'row var = mv_append(to_geoshape(to_geopoint("POINT (30 10)")), to_geoshape(to_geopoint("POINT (30 10)")))', + [] + ); + + testErrorsAndWarnings('row var = mv_append(to_ip("127.0.0.1"), to_ip("127.0.0.1"))', []); + testErrorsAndWarnings('row mv_append(to_ip("127.0.0.1"), to_ip("127.0.0.1"))', []); + + testErrorsAndWarnings( + 'row var = mv_append(to_ip(to_ip("127.0.0.1")), to_ip(to_ip("127.0.0.1")))', + [] + ); + + testErrorsAndWarnings('row var = mv_append("a", "a")', []); + testErrorsAndWarnings('row mv_append("a", "a")', []); + testErrorsAndWarnings('row var = mv_append(to_string(true), to_string(true))', []); + testErrorsAndWarnings('row var = mv_append(to_version("1.0.0"), to_version("1.0.0"))', []); + testErrorsAndWarnings('row mv_append(to_version("1.0.0"), to_version("1.0.0"))', []); + testErrorsAndWarnings('row var = mv_append(to_version("a"), to_version("a"))', []); + testErrorsAndWarnings('from a_index | where mv_append(numberField, numberField) > 0', []); + testErrorsAndWarnings( + 'from a_index | where length(mv_append(stringField, stringField)) > 0', + [] + ); + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(booleanField, booleanField)', + [] + ); + testErrorsAndWarnings('from a_index | eval mv_append(booleanField, booleanField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_boolean(booleanField), to_boolean(booleanField))', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(cartesianPointField, cartesianPointField)', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval mv_append(cartesianPointField, cartesianPointField)', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_cartesianpoint(cartesianPointField), to_cartesianpoint(cartesianPointField))', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(cartesianShapeField, cartesianShapeField)', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval mv_append(cartesianShapeField, cartesianShapeField)', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_cartesianshape(cartesianPointField), to_cartesianshape(cartesianPointField))', + [] + ); + + testErrorsAndWarnings('from a_index | eval var = mv_append(dateField, dateField)', []); + testErrorsAndWarnings('from a_index | eval mv_append(dateField, dateField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_datetime(dateField), to_datetime(dateField))', + [] + ); + + testErrorsAndWarnings('from a_index | eval var = mv_append(numberField, numberField)', []); + testErrorsAndWarnings('from a_index | eval mv_append(numberField, numberField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_integer(booleanField), to_integer(booleanField))', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(geoPointField, geoPointField)', + [] + ); + testErrorsAndWarnings('from a_index | eval mv_append(geoPointField, geoPointField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_geopoint(geoPointField), to_geopoint(geoPointField))', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(geoShapeField, geoShapeField)', + [] + ); + testErrorsAndWarnings('from a_index | eval mv_append(geoShapeField, geoShapeField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_geoshape(geoPointField), to_geoshape(geoPointField))', + [] + ); + + testErrorsAndWarnings('from a_index | eval var = mv_append(ipField, ipField)', []); + testErrorsAndWarnings('from a_index | eval mv_append(ipField, ipField)', []); + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_ip(ipField), to_ip(ipField))', + [] + ); + testErrorsAndWarnings('from a_index | eval var = mv_append(stringField, stringField)', []); + testErrorsAndWarnings('from a_index | eval mv_append(stringField, stringField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_string(booleanField), to_string(booleanField))', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(versionField, versionField)', + [] + ); + testErrorsAndWarnings('from a_index | eval mv_append(versionField, versionField)', []); + + testErrorsAndWarnings( + 'from a_index | eval var = mv_append(to_version(stringField), to_version(stringField))', + [] + ); + + testErrorsAndWarnings( + 'from a_index | eval mv_append(booleanField, booleanField, extraArg)', + ['Error: [mv_append] function expects exactly 2 arguments, got 3.'] + ); + + testErrorsAndWarnings('from a_index | sort mv_append(booleanField, booleanField)', []); + testErrorsAndWarnings('from a_index | eval mv_append(null, null)', []); + testErrorsAndWarnings('row nullVar = null | eval mv_append(nullVar, nullVar)', []); + }); }); }); From c4dbcf822a6beb608a5b7c370e039ede996200d9 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 6 Jun 2024 03:18:00 +1000 Subject: [PATCH 009/122] skip failing test suite (#184853) From 74d143030520abc0464df8bea6eb90a33f2c3157 Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Wed, 5 Jun 2024 13:40:00 -0400 Subject: [PATCH 010/122] Revert "[Response Ops][Task Manager] Emitting metrics when metrics are reset (#184846) ## Summary Reverted https://github.com/elastic/kibana/commit/557633456ce89757b2c472bdcd0ccf2bfa601ce7 from deploy@1717401777 as part of emergency release. This PR is following the emergency release guidelines to: `In a separate PR, the fix should be "frontported" to main by manually cherry-picking the commit.` --- .../server/metrics/create_aggregator.test.ts | 316 +++++++----------- .../server/metrics/create_aggregator.ts | 24 +- .../test_suites/task_manager/metrics_route.ts | 13 +- 3 files changed, 130 insertions(+), 223 deletions(-) diff --git a/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts b/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts index 1db164e38d992..309617a8e4cc3 100644 --- a/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts +++ b/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts @@ -7,7 +7,7 @@ import sinon from 'sinon'; import { Subject } from 'rxjs'; -import { take, bufferCount } from 'rxjs'; +import { take, bufferCount, skip } from 'rxjs'; import { loggingSystemMock } from '@kbn/core/server/mocks'; import { isTaskManagerMetricEvent, @@ -109,7 +109,13 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskClaimAggregator - .pipe(take(events.length), bufferCount(events.length)) + .pipe( + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events.length), + bufferCount(events.length) + ) .subscribe((metrics: Array>) => { expect(metrics[0]).toEqual({ key: 'task_claim', @@ -262,8 +268,11 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskClaimAggregator .pipe( - take(events1.length + events2.length + 1), - bufferCount(events1.length + events2.length + 1) + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events1.length + events2.length), + bufferCount(events1.length + events2.length) ) .subscribe((metrics: Array>) => { expect(metrics[0]).toEqual({ @@ -328,16 +337,6 @@ describe('createAggregator', () => { }); // reset event should have been received here expect(metrics[6]).toEqual({ - key: 'task_claim', - value: { - success: 0, - total: 0, - total_errors: 0, - duration: { counts: [], values: [] }, - duration_values: [], - }, - }); - expect(metrics[7]).toEqual({ key: 'task_claim', value: { success: 1, @@ -347,7 +346,7 @@ describe('createAggregator', () => { duration_values: [10], }, }); - expect(metrics[8]).toEqual({ + expect(metrics[7]).toEqual({ key: 'task_claim', value: { success: 1, @@ -357,7 +356,7 @@ describe('createAggregator', () => { duration_values: [10], }, }); - expect(metrics[9]).toEqual({ + expect(metrics[8]).toEqual({ key: 'task_claim', value: { success: 1, @@ -367,7 +366,7 @@ describe('createAggregator', () => { duration_values: [10], }, }); - expect(metrics[10]).toEqual({ + expect(metrics[9]).toEqual({ key: 'task_claim', value: { success: 2, @@ -377,7 +376,7 @@ describe('createAggregator', () => { duration_values: [10, 10], }, }); - expect(metrics[11]).toEqual({ + expect(metrics[10]).toEqual({ key: 'task_claim', value: { success: 3, @@ -436,8 +435,11 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskClaimAggregator .pipe( - take(events1.length + events2.length + 1), - bufferCount(events1.length + events2.length + 1) + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events1.length + events2.length), + bufferCount(events1.length + events2.length) ) .subscribe((metrics: Array>) => { expect(metrics[0]).toEqual({ @@ -502,16 +504,6 @@ describe('createAggregator', () => { }); // reset interval should have fired here expect(metrics[6]).toEqual({ - key: 'task_claim', - value: { - success: 0, - total: 0, - total_errors: 0, - duration: { counts: [], values: [] }, - duration_values: [], - }, - }); - expect(metrics[7]).toEqual({ key: 'task_claim', value: { success: 1, @@ -521,7 +513,7 @@ describe('createAggregator', () => { duration_values: [10], }, }); - expect(metrics[8]).toEqual({ + expect(metrics[7]).toEqual({ key: 'task_claim', value: { success: 1, @@ -531,7 +523,7 @@ describe('createAggregator', () => { duration_values: [10], }, }); - expect(metrics[9]).toEqual({ + expect(metrics[8]).toEqual({ key: 'task_claim', value: { success: 1, @@ -541,7 +533,7 @@ describe('createAggregator', () => { duration_values: [10], }, }); - expect(metrics[10]).toEqual({ + expect(metrics[9]).toEqual({ key: 'task_claim', value: { success: 2, @@ -551,7 +543,7 @@ describe('createAggregator', () => { duration_values: [10, 10], }, }); - expect(metrics[11]).toEqual({ + expect(metrics[10]).toEqual({ key: 'task_claim', value: { success: 3, @@ -613,22 +605,14 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskClaimAggregator .pipe( - take(events1.length + events2.length + 3), - bufferCount(events1.length + events2.length + 3) + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events1.length + events2.length + 1), + bufferCount(events1.length + events2.length + 1) ) .subscribe((metrics: Array>) => { - // reset event expect(metrics[0]).toEqual({ - key: 'task_claim', - value: { - success: 0, - total: 0, - total_errors: 0, - duration: { counts: [], values: [] }, - duration_values: [], - }, - }); - expect(metrics[1]).toEqual({ key: 'task_claim', value: { success: 1, @@ -638,7 +622,7 @@ describe('createAggregator', () => { duration_values: [10], }, }); - expect(metrics[2]).toEqual({ + expect(metrics[1]).toEqual({ key: 'task_claim', value: { success: 2, @@ -648,7 +632,7 @@ describe('createAggregator', () => { duration_values: [10, 10], }, }); - expect(metrics[3]).toEqual({ + expect(metrics[2]).toEqual({ key: 'task_claim', value: { success: 3, @@ -658,7 +642,7 @@ describe('createAggregator', () => { duration_values: [10, 10, 10], }, }); - expect(metrics[4]).toEqual({ + expect(metrics[3]).toEqual({ key: 'task_claim', value: { success: 4, @@ -668,7 +652,7 @@ describe('createAggregator', () => { duration_values: [10, 10, 10, 10], }, }); - expect(metrics[5]).toEqual({ + expect(metrics[4]).toEqual({ key: 'task_claim', value: { success: 4, @@ -678,7 +662,7 @@ describe('createAggregator', () => { duration_values: [10, 10, 10, 10], }, }); - expect(metrics[6]).toEqual({ + expect(metrics[5]).toEqual({ key: 'task_claim', value: { success: 5, @@ -689,7 +673,7 @@ describe('createAggregator', () => { }, }); // reset interval fired here but stats should not clear - expect(metrics[7]).toEqual({ + expect(metrics[6]).toEqual({ key: 'task_claim', value: { success: 6, @@ -699,7 +683,7 @@ describe('createAggregator', () => { duration_values: [10, 10, 10, 10, 10, 10], }, }); - expect(metrics[8]).toEqual({ + expect(metrics[7]).toEqual({ key: 'task_claim', value: { success: 6, @@ -709,7 +693,7 @@ describe('createAggregator', () => { duration_values: [10, 10, 10, 10, 10, 10], }, }); - expect(metrics[9]).toEqual({ + expect(metrics[8]).toEqual({ key: 'task_claim', value: { success: 6, @@ -719,7 +703,7 @@ describe('createAggregator', () => { duration_values: [10, 10, 10, 10, 10, 10], }, }); - expect(metrics[10]).toEqual({ + expect(metrics[9]).toEqual({ key: 'task_claim', value: { success: 7, @@ -729,7 +713,7 @@ describe('createAggregator', () => { duration_values: [10, 10, 10, 10, 10, 10, 10], }, }); - expect(metrics[11]).toEqual({ + expect(metrics[10]).toEqual({ key: 'task_claim', value: { success: 8, @@ -740,17 +724,7 @@ describe('createAggregator', () => { }, }); // reset interval fired here and stats should have cleared - expect(metrics[12]).toEqual({ - key: 'task_claim', - value: { - success: 0, - total: 0, - total_errors: 0, - duration: { counts: [], values: [] }, - duration_values: [], - }, - }); - expect(metrics[13]).toEqual({ + expect(metrics[11]).toEqual({ key: 'task_claim', value: { success: 1, @@ -821,7 +795,13 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskRunAggregator - .pipe(take(taskRunEvents.length), bufferCount(taskRunEvents.length)) + .pipe( + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(taskRunEvents.length), + bufferCount(taskRunEvents.length) + ) .subscribe((metrics: Array>) => { expect(metrics[0]).toEqual({ key: 'task_run', @@ -1844,8 +1824,11 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskRunAggregator .pipe( - take(taskRunEvents1.length + taskRunEvents2.length + 1), - bufferCount(taskRunEvents1.length + taskRunEvents2.length + 1) + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(taskRunEvents1.length + taskRunEvents2.length), + bufferCount(taskRunEvents1.length + taskRunEvents2.length) ) .subscribe((metrics: Array>) => { expect(metrics[0]).toEqual({ @@ -2242,55 +2225,6 @@ describe('createAggregator', () => { }); // reset event should have been received here expect(metrics[10]).toEqual({ - key: 'task_run', - value: { - overall: { - success: 0, - not_timed_out: 0, - total: 0, - delay: { counts: [], values: [] }, - delay_values: [], - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - by_type: { - alerting: { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - 'alerting:example': { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - report: { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - telemetry: { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - }, - }, - }); - expect(metrics[11]).toEqual({ key: 'task_run', value: { overall: { @@ -2339,7 +2273,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[12]).toEqual({ + expect(metrics[11]).toEqual({ key: 'task_run', value: { overall: { @@ -2388,7 +2322,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[13]).toEqual({ + expect(metrics[12]).toEqual({ key: 'task_run', value: { overall: { @@ -2437,7 +2371,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[14]).toEqual({ + expect(metrics[13]).toEqual({ key: 'task_run', value: { overall: { @@ -2486,7 +2420,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[15]).toEqual({ + expect(metrics[14]).toEqual({ key: 'task_run', value: { overall: { @@ -2535,7 +2469,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[16]).toEqual({ + expect(metrics[15]).toEqual({ key: 'task_run', value: { overall: { @@ -2584,7 +2518,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[17]).toEqual({ + expect(metrics[16]).toEqual({ key: 'task_run', value: { overall: { @@ -2633,7 +2567,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[18]).toEqual({ + expect(metrics[17]).toEqual({ key: 'task_run', value: { overall: { @@ -2682,7 +2616,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[19]).toEqual({ + expect(metrics[18]).toEqual({ key: 'task_run', value: { overall: { @@ -2731,7 +2665,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[20]).toEqual({ + expect(metrics[19]).toEqual({ key: 'task_run', value: { overall: { @@ -2855,8 +2789,11 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskRunAggregator .pipe( - take(taskRunEvents1.length + taskRunEvents2.length + 1), - bufferCount(taskRunEvents1.length + taskRunEvents2.length + 1) + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(taskRunEvents1.length + taskRunEvents2.length), + bufferCount(taskRunEvents1.length + taskRunEvents2.length) ) .subscribe((metrics: Array>) => { expect(metrics[0]).toEqual({ @@ -3253,55 +3190,6 @@ describe('createAggregator', () => { }); // reset event should have been received here expect(metrics[10]).toEqual({ - key: 'task_run', - value: { - overall: { - success: 0, - not_timed_out: 0, - total: 0, - delay: { counts: [], values: [] }, - delay_values: [], - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - by_type: { - alerting: { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - 'alerting:example': { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - report: { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - telemetry: { - success: 0, - not_timed_out: 0, - total: 0, - framework_errors: 0, - user_errors: 0, - total_errors: 0, - }, - }, - }, - }); - expect(metrics[11]).toEqual({ key: 'task_run', value: { overall: { @@ -3350,7 +3238,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[12]).toEqual({ + expect(metrics[11]).toEqual({ key: 'task_run', value: { overall: { @@ -3399,7 +3287,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[13]).toEqual({ + expect(metrics[12]).toEqual({ key: 'task_run', value: { overall: { @@ -3448,7 +3336,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[14]).toEqual({ + expect(metrics[13]).toEqual({ key: 'task_run', value: { overall: { @@ -3497,7 +3385,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[15]).toEqual({ + expect(metrics[14]).toEqual({ key: 'task_run', value: { overall: { @@ -3546,7 +3434,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[16]).toEqual({ + expect(metrics[15]).toEqual({ key: 'task_run', value: { overall: { @@ -3595,7 +3483,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[17]).toEqual({ + expect(metrics[16]).toEqual({ key: 'task_run', value: { overall: { @@ -3644,7 +3532,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[18]).toEqual({ + expect(metrics[17]).toEqual({ key: 'task_run', value: { overall: { @@ -3693,7 +3581,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[19]).toEqual({ + expect(metrics[18]).toEqual({ key: 'task_run', value: { overall: { @@ -3742,7 +3630,7 @@ describe('createAggregator', () => { }, }, }); - expect(metrics[20]).toEqual({ + expect(metrics[19]).toEqual({ key: 'task_run', value: { overall: { @@ -3883,7 +3771,13 @@ describe('createAggregator', () => { return new Promise((resolve) => { taskOverdueAggregator - .pipe(take(events.length), bufferCount(events.length)) + .pipe( + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events.length), + bufferCount(events.length) + ) .subscribe((metrics: Array>) => { expect(metrics[0]).toEqual({ key: 'task_overdue', @@ -4039,9 +3933,17 @@ describe('createAggregator', () => { }); return new Promise((resolve) => { - aggregator.pipe(take(events.length), bufferCount(events.length)).subscribe(() => { - resolve(); - }); + aggregator + .pipe( + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events.length), + bufferCount(events.length) + ) + .subscribe(() => { + resolve(); + }); for (const event of events) { events$.next(event); @@ -4082,9 +3984,17 @@ describe('createAggregator', () => { }); return new Promise((resolve) => { - aggregator.pipe(take(events.length), bufferCount(events.length)).subscribe(() => { - resolve(); - }); + aggregator + .pipe( + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events.length), + bufferCount(events.length) + ) + .subscribe(() => { + resolve(); + }); for (const event of events) { events$.next(event); @@ -4130,9 +4040,17 @@ describe('createAggregator', () => { }); return new Promise((resolve) => { - aggregator.pipe(take(events.length + 1), bufferCount(events.length + 1)).subscribe(() => { - resolve(); - }); + aggregator + .pipe( + // skip initial metric which is just initialized data which + // ensures we don't stall on combineLatest + skip(1), + take(events.length), + bufferCount(events.length) + ) + .subscribe(() => { + resolve(); + }); for (const event of events) { events$.next(event); diff --git a/x-pack/plugins/task_manager/server/metrics/create_aggregator.ts b/x-pack/plugins/task_manager/server/metrics/create_aggregator.ts index 3b2bb8726a5ec..a06278dd12ef7 100644 --- a/x-pack/plugins/task_manager/server/metrics/create_aggregator.ts +++ b/x-pack/plugins/task_manager/server/metrics/create_aggregator.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { filter, interval, map, merge, Observable } from 'rxjs'; +import { combineLatest, filter, interval, map, merge, Observable, startWith } from 'rxjs'; import { JsonValue } from '@kbn/utility-types'; import { Logger } from '@kbn/core/server'; import { AggregatedStat, AggregatedStatProvider } from '../lib/runtime_statistics_aggregator'; @@ -32,12 +32,11 @@ export function createAggregator({ eventFilter, metricsAggregator, }: CreateMetricsAggregatorOpts): AggregatedStatProvider { - let taskResetEvent$: Observable | undefined; if (reset$) { let lastResetTime: Date = new Date(); // Resets the aggregators either when the reset interval has passed or // a reset$ event is received - taskResetEvent$ = merge( + merge( interval(config.metrics_reset_interval).pipe( map(() => { if (intervalHasPassedSince(lastResetTime, config.metrics_reset_interval)) { @@ -63,13 +62,11 @@ export function createAggregator({ return true; }) ) - ).pipe( - filter((shouldReset: boolean) => shouldReset), - map(() => { + ).subscribe((shouldReset: boolean) => { + if (shouldReset) { metricsAggregator.reset(); - return metricsAggregator.collect(); - }) - ); + } + }); } const taskEvents$: Observable = events$.pipe( @@ -80,13 +77,8 @@ export function createAggregator({ }) ); - const observablesToMerge: Array> = [taskEvents$]; - if (taskResetEvent$) { - observablesToMerge.push(taskResetEvent$); - } - - return merge(...observablesToMerge).pipe( - map((value: T) => { + return combineLatest([taskEvents$.pipe(startWith(metricsAggregator.initialMetric()))]).pipe( + map(([value]: [T]) => { return { key, value, diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/metrics_route.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/metrics_route.ts index 8d79b4250de60..fb8ee402fcc88 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/metrics_route.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/metrics_route.ts @@ -133,8 +133,8 @@ export default function ({ getService }: FtrProviderContext) { expect(metrics?.task_claim).not.to.be(null); expect(metrics?.task_claim?.value).not.to.be(null); - expect(metrics?.task_claim?.value.success).to.equal(0); - expect(metrics?.task_claim?.value.total).to.equal(0); + expect(metrics?.task_claim?.value.success).to.equal(1); + expect(metrics?.task_claim?.value.total).to.equal(1); previousTaskClaimTimestamp = metrics?.task_claim?.timestamp!; @@ -264,10 +264,7 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const metrics = ( - await getMetrics( - false, - (m) => m?.metrics?.task_run?.value.overall.framework_errors! === 1 - ) + await getMetrics(true, (m) => m?.metrics?.task_run?.value.overall.framework_errors! === 1) ).metrics; const total = metrics?.task_run?.value.overall.total || 0; @@ -305,13 +302,13 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const metrics = ( - await getMetrics(false, (m) => m?.metrics?.task_run?.value.overall.user_errors! === 1) + await getMetrics(true, (m) => m?.metrics?.task_run?.value.overall.user_errors! === 1) ).metrics; const total = metrics?.task_run?.value.overall.total || 0; const success = metrics?.task_run?.value.overall.success || 0; - expect(total - success).to.be(2); + expect(total - success).to.be(1); }); }); From eaed27c14bbfc047326005bcf3ba037a2d7f3c85 Mon Sep 17 00:00:00 2001 From: Nick Partridge Date: Wed, 5 Jun 2024 10:57:53 -0700 Subject: [PATCH 011/122] Update renovate config (#184785) - Replace the `extends` config from the deprecated `config:base` to `config:recommended`. - Removes global defaults from top-level group and applies the `prCreation` and `stabilityDays` options only to non-elastic dependency groups. - Replaces deprecated `stabilityDays` option with new [`minimumReleaseAge`](https://docs.renovatebot.com/configuration-options/#minimumreleaseage). - Replaces all `matchPackage*` options to `matchDep*` options. - Format entire config file with prettier. --- renovate.json | 773 +++++++++++++++----------------------------------- 1 file changed, 222 insertions(+), 551 deletions(-) diff --git a/renovate.json b/renovate.json index db3141fb3d3bd..d7ac439ca0691 100644 --- a/renovate.json +++ b/renovate.json @@ -1,19 +1,9 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:base" - ], - "ignorePaths": [ - "**/__fixtures__/**", - "**/fixtures/**" - ], - "enabledManagers": [ - "npm" - ], - "baseBranches": [ - "main", - "7.17" - ], + "extends": ["config:recommended"], + "ignorePaths": ["**/__fixtures__/**", "**/fixtures/**"], + "enabledManagers": ["npm"], + "baseBranches": ["main", "7.17"], "prConcurrentLimit": 0, "prHourlyLimit": 0, "separateMajorMinor": false, @@ -27,307 +17,156 @@ }, "packageRules": [ { - "matchPackagePatterns": [ - ".*" - ], - "enabled": false, - "prCreation": "not-pending", - "stabilityDays": 7 + "matchDepPatterns": [".*"], + "enabled": false }, { "groupName": "@elastic/charts", - "matchPackageNames": [ - "@elastic/charts" - ], - "reviewers": [ - "team:visualizations", - "markov00", - "nickofthyme" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:skip", - "Team:Visualizations" - ], - "draftPR": true, - "enabled": true, - "assignAutomerge": true, - "prCreation": "immediate" + "matchDepNames": ["@elastic/charts"], + "reviewers": ["team:visualizations", "markov00", "nickofthyme"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip", "Team:Visualizations"], + "enabled": true }, { "groupName": "@elastic/elasticsearch", - "matchPackageNames": [ - "@elastic/elasticsearch" - ], - "reviewers": [ - "team:kibana-operations", - "team:kibana-core" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:skip", - "Team:Operations", - "Team:Core" - ], + "matchDepNames": ["@elastic/elasticsearch"], + "reviewers": ["team:kibana-operations", "team:kibana-core"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip", "Team:Operations", "Team:Core"], "enabled": true }, { "groupName": "@elastic/elasticsearch", - "matchPackageNames": [ - "@elastic/elasticsearch" - ], - "reviewers": [ - "team:kibana-operations", - "team:kibana-core" - ], - "matchBaseBranches": [ - "7.17" - ], - "labels": [ - "release_note:skip", - "Team:Operations", - "Team:Core", - "backport:skip" - ], + "matchDepNames": ["@elastic/elasticsearch"], + "reviewers": ["team:kibana-operations", "team:kibana-core"], + "matchBaseBranches": ["7.17"], + "labels": ["release_note:skip", "Team:Operations", "Team:Core", "backport:skip"], "enabled": true }, { "groupName": "LaunchDarkly", - "matchPackageNames": [ - "launchdarkly-js-client-sdk", - "launchdarkly-node-server-sdk" - ], - "reviewers": [ - "team:kibana-security", - "team:kibana-core" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "Team:Security", - "Team:Core", - "backport:prev-minor" - ], + "matchDepNames": ["launchdarkly-js-client-sdk", "launchdarkly-node-server-sdk"], + "reviewers": ["team:kibana-security", "team:kibana-core"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "Team:Security", "Team:Core", "backport:prev-minor"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "APM", - "matchPackageNames": [ - "elastic-apm-node", - "@elastic/apm-rum", - "@elastic/apm-rum-react" - ], - "reviewers": [ - "team:kibana-core" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "Team:Core", - "backport:skip" - ], - "enabled": true, - "prCreation": "immediate" + "matchDepNames": ["elastic-apm-node", "@elastic/apm-rum", "@elastic/apm-rum-react"], + "reviewers": ["team:kibana-core"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "Team:Core", "backport:skip"], + "enabled": true }, { "groupName": "ansi-regex", - "matchPackageNames": [ - "ansi-regex" - ], - "reviewers": [ - "team:kibana-core" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "Team:Core", - "backport:skip" - ], + "matchDepNames": ["ansi-regex"], + "reviewers": ["team:kibana-core"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "Team:Core", "backport:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "OpenAPI Spec", - "matchPackageNames": [ - "@redocly/cli" - ], - "reviewers": [ - "team:kibana-core" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "Team:Core", - "backport:all-open" - ], + "matchDepNames": ["@redocly/cli"], + "reviewers": ["team:kibana-core"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "Team:Core", "backport:all-open"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "babel", - "matchPackageNames": [ - "@types/babel__core" - ], - "matchPackagePatterns": [ - "^@babel", - "^babel-plugin" - ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "matchDepNames": ["@types/babel__core"], + "matchDepPatterns": ["^@babel", "^babel-plugin"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "typescript", - "matchPackageNames": [ - "typescript", - "prettier", - "@types/jsdom" - ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "matchDepNames": ["typescript", "prettier", "@types/jsdom"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "typescript-eslint", - "matchPackagePatterns": [ - "^@typescript-eslint" - ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "matchDepPatterns": ["^@typescript-eslint"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "polyfills", - "matchPackageNames": [ - "core-js" - ], - "matchPackagePatterns": [ - "polyfill" - ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "matchDepNames": ["core-js"], + "matchDepPatterns": ["polyfill"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "CLI tooling", - "matchPackageNames": [ - "listr2" - ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "backport:all-open", - "release_note:skip" - ], + "matchDepNames": ["listr2"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "backport:all-open", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "vega related modules", - "matchPackageNames": [ - "vega", - "vega-lite", - "vega-schema-url-parser", - "vega-tooltip" - ], - "reviewers": [ - "team:kibana-visualizations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Feature:Vega", - "Team:Visualizations" - ], + "matchDepNames": ["vega", "vega-lite", "vega-schema-url-parser", "vega-tooltip"], + "reviewers": ["team:kibana-visualizations"], + "matchBaseBranches": ["main"], + "labels": ["Feature:Vega", "Team:Visualizations"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "cypress", - "matchPackagePatterns": [ - "cypress" - ], - "reviewers": [ - "Team:apm", - "Team: SecuritySolution" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "buildkite-ci", - "ci:all-cypress-suites" - ], + "matchDepPatterns": ["cypress"], + "reviewers": ["Team:apm", "Team: SecuritySolution"], + "matchBaseBranches": ["main"], + "labels": ["buildkite-ci", "ci:all-cypress-suites"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "security solution modules", - "matchPackageNames": [ - "zod", - "langchain" - ], - "reviewers": [ - "Team: SecuritySolution" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team: SecuritySolution" - ], + "matchDepNames": ["zod", "langchain"], + "reviewers": ["Team: SecuritySolution"], + "matchBaseBranches": ["main"], + "labels": ["Team: SecuritySolution"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "platform security modules", - "matchPackageNames": [ + "matchDepNames": [ "css.escape", "node-forge", "formik", @@ -339,22 +178,16 @@ "@types/xml-crypto", "@kayahr/text-encoding" ], - "reviewers": [ - "team:kibana-security" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Security", - "release_note:skip", - "backport:all-open" - ], + "reviewers": ["team:kibana-security"], + "matchBaseBranches": ["main"], + "labels": ["Team:Security", "release_note:skip", "backport:all-open"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "ftr", - "packageNames": [ + "matchDepNames": [ "@types/chromedriver", "@types/selenium-webdriver", "chromedriver", @@ -362,57 +195,36 @@ "ms-chromium-edge-driver", "selenium-webdriver" ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "scss", - "packageNames": [ - "sass-embedded" - ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip", - "backport:all-open" - ], + "matchDepNames": ["sass-embedded"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip", "backport:all-open"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "minify", - "packageNames": [ - "gulp-terser", - "terser" - ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "matchDepNames": ["gulp-terser", "terser"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "@testing-library", - "packageNames": [ + "matchDepNames": [ "@testing-library/dom", "@testing-library/jest-dom", "@testing-library/react", @@ -420,21 +232,16 @@ "@testing-library/user-event", "@types/testing-library__jest-dom" ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "jest", - "packageNames": [ + "matchDepNames": [ "@jest/console", "@jest/reporters", "@jest/types", @@ -450,67 +257,39 @@ "jest-runtime", "jest-snapshot" ], - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Operations", - "release_note:skip" - ], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "@storybook", - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "matchPackagePatterns": [ - "^@storybook" - ], - "excludePackageNames": [ - "@storybook/testing-react" - ], - "labels": [ - "Team:Operations", - "release_note:skip", - "ci:build-storybooks", - "backport:skip" - ], - "enabled": true, - "allowedVersions": "<7.0" + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "matchDepPatterns": ["^@storybook"], + "excludeDepNames": ["@storybook/testing-react"], + "labels": ["Team:Operations", "release_note:skip", "ci:build-storybooks", "backport:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", + "allowedVersions": "<7.0", + "enabled": true }, { "groupName": "@storybook/testing-react", - "reviewers": [ - "team:kibana-operations" - ], - "matchBaseBranches": [ - "main" - ], - "matchPackageNames": [ - "@storybook/testing-react" - ], - "labels": [ - "Team:Operations", - "release_note:skip", - "ci:build-storybooks", - "backport:skip" - ], - "enabled": true, - "allowedVersions": "<2.0" + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "matchDepNames": ["@storybook/testing-react"], + "labels": ["Team:Operations", "release_note:skip", "ci:build-storybooks", "backport:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", + "allowedVersions": "<2.0", + "enabled": true }, { "groupName": "react-query", - "packageNames": [ - "@tanstack/react-query", - "@tanstack/react-query-devtools" - ], + "matchDepNames": ["@tanstack/react-query", "@tanstack/react-query-devtools"], "reviewers": [ "team:response-ops", "team:kibana-cloud-security-posture", @@ -519,41 +298,25 @@ "team:awp-platform", "team:security-onboarding-and-lifecycle-mgt" ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:skip", - "ci:all-cypress-suites" - ], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip", "ci:all-cypress-suites"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "react-hook-form", - "packageNames": [ - "react-hook-form" - ], - "reviewers": [ - "team:security-asset-management", - "team:uptime" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:skip", - "ci:all-cypress-suites" - ], + "matchDepNames": ["react-hook-form"], + "reviewers": ["team:security-asset-management", "team:uptime"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip", "ci:all-cypress-suites"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "redux", - "packageNames": [ - "redux", - "react-redux" - ], + "matchDepNames": ["redux", "react-redux"], "reviewers": [ "team:search-kibana", "team:kibana-presentation", @@ -562,199 +325,107 @@ "team:kibana-gis", "team:security-solution" ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:skip", - "ci:all-cypress-suites" - ], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip", "ci:all-cypress-suites"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "Profiling", - "matchPackageNames": [ - "peggy", - "@types/dagre" - ], - "reviewers": [ - "team:profiling-ui" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:skip" - ], - "enabled": true, - "prCreation": "immediate" + "matchDepNames": ["peggy", "@types/dagre"], + "reviewers": ["team:profiling-ui"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip"], + "minimumReleaseAge": "7 days", + "enabled": true }, { "groupName": "TTY Output", - "matchPackageNames": [ - "xterm", - "byte-size", - "@types/byte-size" - ], - "reviewers": [ - "team:sec-cloudnative-integrations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team: AWP: Visualization", - "release_note:skip", - "backport:skip" - ], - "enabled": true, - "prCreation": "immediate" + "matchDepNames": ["xterm", "byte-size", "@types/byte-size"], + "reviewers": ["team:sec-cloudnative-integrations"], + "matchBaseBranches": ["main"], + "labels": ["Team: AWP: Visualization", "release_note:skip", "backport:skip"], + "minimumReleaseAge": "7 days", + "enabled": true }, { "groupName": "Cloud Defend", - "matchPackageNames": [ - "monaco-yaml" - ], - "reviewers": [ - "team:sec-cloudnative-integrations" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team: Cloud Native Integrations", - "release_note:skip", - "backport:skip" - ], - "enabled": true, - "prCreation": "immediate" + "matchDepNames": ["monaco-yaml"], + "reviewers": ["team:sec-cloudnative-integrations"], + "matchBaseBranches": ["main"], + "labels": ["Team: Cloud Native Integrations", "release_note:skip", "backport:skip"], + "minimumReleaseAge": "7 days", + "enabled": true }, { "groupName": "JSON Web Token", - "matchPackageNames": [ - "jsonwebtoken" - ], - "reviewers": [ - "team:response-ops", - "team:kibana-core" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:all-open" - ], + "matchDepNames": ["jsonwebtoken"], + "reviewers": ["team:response-ops", "team:kibana-core"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:all-open"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "XState", - "matchPackageNames": [ - "xstate" - ], - "matchPackagePrefixes": [ - "@xstate/" - ], - "reviewers": [ - "team:obs-ux-logs" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Obs UX Logs", - "release_note:skip" - ], - "enabled": true, - "prCreation": "immediate" + "matchDepNames": ["xstate"], + "matchDepPrefixes": ["@xstate/"], + "reviewers": ["team:obs-ux-logs"], + "matchBaseBranches": ["main"], + "labels": ["Team:Obs UX Logs", "release_note:skip"], + "minimumReleaseAge": "7 days", + "enabled": true }, { "groupName": "OpenTelemetry modules", - "matchPackagePrefixes": [ - "@opentelemetry/" - ], - "reviewers": [ - "team:monitoring" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:Monitoring" - ], + "matchDepPrefixes": ["@opentelemetry/"], + "reviewers": ["team:monitoring"], + "matchBaseBranches": ["main"], + "labels": ["Team:Monitoring"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "csp", - "packageNames": [ - "content-security-policy-parser" - ], - "reviewers": [ - "team:kibana-security", - "team:kibana-core" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:skip", - "ci:serverless-test-all" - ], + "matchDepNames": ["content-security-policy-parser"], + "reviewers": ["team:kibana-security", "team:kibana-core"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:skip", "ci:serverless-test-all"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "AlertingEmails", - "matchPackageNames": [ - "nodemailer" - ], - "reviewers": [ - "team:response-ops" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "release_note:skip", - "backport:prev-minor" - ], + "matchDepNames": ["nodemailer"], + "reviewers": ["team:response-ops"], + "matchBaseBranches": ["main"], + "labels": ["release_note:skip", "backport:prev-minor"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "machine learning modules", - "matchPackageNames": [ - "apidoc-markdown" - ], - "reviewers": [ - "team:ml-ui" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:ML", - "release_note:skip", - "backport:all-open" - ], + "matchDepNames": ["apidoc-markdown"], + "reviewers": ["team:ml-ui"], + "matchBaseBranches": ["main"], + "labels": ["Team:ML", "release_note:skip", "backport:all-open"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true }, { "groupName": "Kibana ES|QL Team", - "matchPackageNames": [ - "recast" - ], - "reviewers": [ - "team:kibana-esql" - ], - "matchBaseBranches": [ - "main" - ], - "labels": [ - "Team:ESQL", - "release_note:skip" - ], + "matchDepNames": ["recast"], + "reviewers": ["team:kibana-esql"], + "matchBaseBranches": ["main"], + "labels": ["Team:ESQL", "release_note:skip"], + "prCreation": "not-pending", + "minimumReleaseAge": "7 days", "enabled": true } ] From 5860259222bbb93acab34775c48fd712c47bd3d0 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 5 Jun 2024 20:20:20 +0200 Subject: [PATCH 012/122] [ES|QL] Render a Discover-like table in the assistant instead of a Lens chart (#184106) ## Summary This PR does 2 things: - Creates a new plugin that is a wrapper of the unified datatable and is only for rendering as a table ES|QL results. The UnifiedDatatable package is good but the consumers need to know all the properties to understand how to use it and the necessity of displaying in a table the results of an ES|QL query comes a lot lately. This plugin has only 3 required properties (rows, columns, query) which make it very easy for the consumers to use it. It also integrates the Row Viewer flyout - It changes the implementation of the obs ai assistant to render a Discover like table instead of a Lens table. The Discover-like table is much better on rendering a table with thousands of columns and is going to be much more helpful for our users. The same plugin can be used later for the inline ediitng flyout too in a dashboard if we want to also display the results of an ES|QL query. Some screenshots of the new possibilities in the assistant: - I can see the results of an ES|QL query in a visualization ![meow](https://github.com/elastic/kibana/assets/17003240/27f77ca3-633b-45f2-b935-42c62c184a04) - I can render my results as a Document view image image image ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 1 + .i18nrc.json | 1 + docs/developer/plugin-list.asciidoc | 4 + package.json | 1 + packages/kbn-optimizer/limits.yml | 1 + packages/kbn-unified-data-table/index.ts | 2 +- .../src/components/data_table.tsx | 31 +-- src/plugins/esql_datagrid/.i18nrc.json | 6 + src/plugins/esql_datagrid/README.md | 47 ++++ src/plugins/esql_datagrid/jest.config.js | 19 ++ src/plugins/esql_datagrid/kibana.jsonc | 21 ++ src/plugins/esql_datagrid/package.json | 6 + .../esql_datagrid/public/create_datagrid.tsx | 58 +++++ .../esql_datagrid/public/data_grid.tsx | 156 ++++++++++++ src/plugins/esql_datagrid/public/index.ts | 14 ++ .../esql_datagrid/public/kibana_services.ts | 50 ++++ src/plugins/esql_datagrid/public/plugin.ts | 30 +++ .../esql_datagrid/public/row_viewer.test.tsx | 119 +++++++++ .../esql_datagrid/public/row_viewer.tsx | 235 ++++++++++++++++++ .../esql_datagrid/public/row_viewer_lazy.tsx | 13 + src/plugins/esql_datagrid/tsconfig.json | 33 +++ tsconfig.base.json | 2 + .../kibana.jsonc | 4 +- .../public/functions/visualize_esql.test.tsx | 59 ++++- .../public/functions/visualize_esql.tsx | 219 +++++++++++----- .../server/functions/query/index.ts | 17 +- .../functions/query/validate_esql_query.ts | 12 +- .../server/functions/visualize_esql.ts | 5 +- .../tsconfig.json | 1 + yarn.lock | 4 + 30 files changed, 1066 insertions(+), 105 deletions(-) create mode 100755 src/plugins/esql_datagrid/.i18nrc.json create mode 100644 src/plugins/esql_datagrid/README.md create mode 100644 src/plugins/esql_datagrid/jest.config.js create mode 100644 src/plugins/esql_datagrid/kibana.jsonc create mode 100644 src/plugins/esql_datagrid/package.json create mode 100644 src/plugins/esql_datagrid/public/create_datagrid.tsx create mode 100644 src/plugins/esql_datagrid/public/data_grid.tsx create mode 100644 src/plugins/esql_datagrid/public/index.ts create mode 100644 src/plugins/esql_datagrid/public/kibana_services.ts create mode 100755 src/plugins/esql_datagrid/public/plugin.ts create mode 100644 src/plugins/esql_datagrid/public/row_viewer.test.tsx create mode 100644 src/plugins/esql_datagrid/public/row_viewer.tsx create mode 100644 src/plugins/esql_datagrid/public/row_viewer_lazy.tsx create mode 100644 src/plugins/esql_datagrid/tsconfig.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9d65857bb5d90..d9a9f60eef539 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -411,6 +411,7 @@ examples/eso_model_version_example @elastic/kibana-security x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin @elastic/kibana-security packages/kbn-esql-ast @elastic/kibana-esql examples/esql_ast_inspector @elastic/kibana-esql +src/plugins/esql_datagrid @elastic/kibana-esql packages/kbn-esql-utils @elastic/kibana-esql packages/kbn-esql-validation-autocomplete @elastic/kibana-esql examples/esql_validation_example @elastic/kibana-esql diff --git a/.i18nrc.json b/.i18nrc.json index 7854a7855351c..4d71e47159e1b 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -116,6 +116,7 @@ "coloring": "packages/kbn-coloring/src", "languageDocumentationPopover": "packages/kbn-language-documentation-popover/src", "textBasedLanguages": "src/plugins/text_based_languages", + "esqlDataGrid": "src/plugins/esql_datagrid", "statusPage": "src/legacy/core_plugins/status_page", "telemetry": ["src/plugins/telemetry", "src/plugins/telemetry_management_section"], "timelion": ["src/plugins/vis_types/timelion"], diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index d861a4e72c572..e6b980a459f15 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -102,6 +102,10 @@ This API doesn't support angular, for registering angular dev tools, bootstrap a |Embeddables are React components that manage their own state, can be serialized and deserialized, and return an API that can be used to interact with them imperatively. +|{kib-repo}blob/{branch}/src/plugins/esql_datagrid/README.md[esqlDataGrid] +|Contains a Discover-like table specifically for ES|QL queries: + + |{kib-repo}blob/{branch}/src/plugins/es_ui_shared/README.md[esUiShared] |This plugin contains reusable code in the form of self-contained modules (or libraries). Each of these modules exports a set of functionality relevant to the domain of the module. diff --git a/package.json b/package.json index 4188137c88ce0..dab6cc9b57d74 100644 --- a/package.json +++ b/package.json @@ -457,6 +457,7 @@ "@kbn/eso-plugin": "link:x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin", "@kbn/esql-ast": "link:packages/kbn-esql-ast", "@kbn/esql-ast-inspector-plugin": "link:examples/esql_ast_inspector", + "@kbn/esql-datagrid": "link:src/plugins/esql_datagrid", "@kbn/esql-utils": "link:packages/kbn-esql-utils", "@kbn/esql-validation-autocomplete": "link:packages/kbn-esql-validation-autocomplete", "@kbn/esql-validation-example-plugin": "link:examples/esql_validation_example", diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index c3616140cabe8..29de4a26abcc9 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -42,6 +42,7 @@ pageLoadAssetSize: embeddable: 87309 embeddableEnhanced: 22107 enterpriseSearch: 50858 + esqlDataGrid: 24598 esUiShared: 326654 eventAnnotation: 30000 eventAnnotationListing: 25841 diff --git a/packages/kbn-unified-data-table/index.ts b/packages/kbn-unified-data-table/index.ts index 26095d948cb8a..0929c33208fa0 100644 --- a/packages/kbn-unified-data-table/index.ts +++ b/packages/kbn-unified-data-table/index.ts @@ -7,7 +7,7 @@ */ export { UnifiedDataTable, DataLoadingState } from './src/components/data_table'; -export type { UnifiedDataTableProps } from './src/components/data_table'; +export type { UnifiedDataTableProps, SortOrder } from './src/components/data_table'; export { RowHeightSettings, type RowHeightSettingsProps, diff --git a/packages/kbn-unified-data-table/src/components/data_table.tsx b/packages/kbn-unified-data-table/src/components/data_table.tsx index a6496151521ec..3a64947fe39ca 100644 --- a/packages/kbn-unified-data-table/src/components/data_table.tsx +++ b/packages/kbn-unified-data-table/src/components/data_table.tsx @@ -267,7 +267,7 @@ export interface UnifiedDataTableProps { theme: ThemeServiceStart; fieldFormats: FieldFormatsStart; uiSettings: IUiSettingsClient; - dataViewFieldEditor: DataViewFieldEditorStart; + dataViewFieldEditor?: DataViewFieldEditorStart; toastNotifications: ToastsStart; storage: Storage; data: DataPublicPluginStart; @@ -611,7 +611,7 @@ export const UnifiedDataTable = ({ useNewFieldsApi, shouldShowFieldHandler, closePopover: () => dataGridRef.current?.closeCellPopover(), - fieldFormats: services.fieldFormats, + fieldFormats, maxEntries: maxDocFieldsDisplayed, externalCustomRenderers, isPlainRecord, @@ -622,7 +622,7 @@ export const UnifiedDataTable = ({ useNewFieldsApi, shouldShowFieldHandler, maxDocFieldsDisplayed, - services.fieldFormats, + fieldFormats, externalCustomRenderers, isPlainRecord, ] @@ -651,18 +651,20 @@ export const UnifiedDataTable = ({ () => onFieldEdited ? (fieldName: string) => { - closeFieldEditor.current = services.dataViewFieldEditor.openEditor({ - ctx: { - dataView, - }, - fieldName, - onSave: async () => { - await onFieldEdited(); - }, - }); + closeFieldEditor.current = + onFieldEdited && + services?.dataViewFieldEditor?.openEditor({ + ctx: { + dataView, + }, + fieldName, + onSave: async () => { + await onFieldEdited(); + }, + }); } : undefined, - [dataView, onFieldEdited, services.dataViewFieldEditor] + [dataView, onFieldEdited, services?.dataViewFieldEditor] ); const timeFieldName = dataView.timeFieldName; @@ -756,7 +758,8 @@ export const UnifiedDataTable = ({ uiSettings, toastNotifications, }, - hasEditDataViewPermission: () => dataViewFieldEditor.userPermissions.editIndexPattern(), + hasEditDataViewPermission: () => + Boolean(dataViewFieldEditor?.userPermissions?.editIndexPattern()), valueToStringConverter, onFilter, editField, diff --git a/src/plugins/esql_datagrid/.i18nrc.json b/src/plugins/esql_datagrid/.i18nrc.json new file mode 100755 index 0000000000000..b56ac6e79d88c --- /dev/null +++ b/src/plugins/esql_datagrid/.i18nrc.json @@ -0,0 +1,6 @@ +{ + "prefix": "esqlDataGrid", + "paths": { + "esqlDataGrid": "." + } +} diff --git a/src/plugins/esql_datagrid/README.md b/src/plugins/esql_datagrid/README.md new file mode 100644 index 0000000000000..89848b34b5f4d --- /dev/null +++ b/src/plugins/esql_datagrid/README.md @@ -0,0 +1,47 @@ +# @kbn/esql-datagrid + +Contains a Discover-like table specifically for ES|QL queries: + - You have to run the esql query on your application, this is just a UI component + - You pass the columns and rows of the _query response to the table + - The table operates in both Document view and table view mode, define this with the `isTableView` property + - The table offers a built in Row Viewer flyout + - The table offers a rows comparison mode, exactly as Discover + +--- + +### Properties + * rows: ESQLRow[], is the array of values returned by the _query api + * columns: DatatableColumn[], is the array of columns in a kibana compatible format. You can sue the `formatESQLColumns` helper function from the `@kbn/esql-utils` package + * query: AggregateQuery, the ES|QL query in the format of + ```json + { + esql: + } + ``` + * flyoutType?: "overlay" | "push", defines the type of flyout for the Row Viewer + * isTableView?: boolean, defines if the table will render as a Document Viewer or a Table View + + +### How to use it +```tsx +import { getIndexPatternFromESQLQuery, getESQLAdHocDataview, formatESQLColumns } from '@kbn/esql-utils'; +import { ESQLDataGrid } from '@kbn/esql-datagrid/public'; + +/** + Run the _query api to get the datatable with the ES|QL query you want. + This will return a response with columns and values +**/ + +const indexPattern = getIndexPatternFromESQLQuery(query); +const adHocDataView = getESQLAdHocDataview(indexPattern, dataViewService); +const formattedColumns = formatESQLColumns(columns); + + +``` diff --git a/src/plugins/esql_datagrid/jest.config.js b/src/plugins/esql_datagrid/jest.config.js new file mode 100644 index 0000000000000..6def95236d27c --- /dev/null +++ b/src/plugins/esql_datagrid/jest.config.js @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../..', + roots: ['/src/plugins/esql_datagrid'], + coverageDirectory: '/target/kibana-coverage/jest/src/plugins/esql_datagrid', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/src/plugins/esql_datagrid/{common,public,server}/**/*.{js,ts,tsx}', + ], + setupFiles: ['jest-canvas-mock'], +}; diff --git a/src/plugins/esql_datagrid/kibana.jsonc b/src/plugins/esql_datagrid/kibana.jsonc new file mode 100644 index 0000000000000..ed589432578f3 --- /dev/null +++ b/src/plugins/esql_datagrid/kibana.jsonc @@ -0,0 +1,21 @@ +{ + "type": "plugin", + "id": "@kbn/esql-datagrid", + "owner": "@elastic/kibana-esql", + "plugin": { + "id": "esqlDataGrid", + "server": false, + "browser": true, + "requiredPlugins": [ + "data", + "uiActions", + "fieldFormats" + ], + "requiredBundles": [ + "kibanaReact", + "kibanaUtils", + "dataViews", + "unifiedDocViewer" + ] + } +} diff --git a/src/plugins/esql_datagrid/package.json b/src/plugins/esql_datagrid/package.json new file mode 100644 index 0000000000000..3c5482db0f13f --- /dev/null +++ b/src/plugins/esql_datagrid/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/esql-datagrid", + "private": true, + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/src/plugins/esql_datagrid/public/create_datagrid.tsx b/src/plugins/esql_datagrid/public/create_datagrid.tsx new file mode 100644 index 0000000000000..04e5693c96c38 --- /dev/null +++ b/src/plugins/esql_datagrid/public/create_datagrid.tsx @@ -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 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 React, { lazy } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; +import type { ESQLRow } from '@kbn/es-types'; +import type { AggregateQuery } from '@kbn/es-query'; +import { withSuspense } from '@kbn/shared-ux-utility'; +import useAsync from 'react-use/lib/useAsync'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { DatatableColumn } from '@kbn/expressions-plugin/common'; +import { CellActionsProvider } from '@kbn/cell-actions'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { untilPluginStartServicesReady } from './kibana_services'; + +interface ESQLDataGridProps { + rows: ESQLRow[]; + dataView: DataView; + columns: DatatableColumn[]; + query: AggregateQuery; + flyoutType?: 'overlay' | 'push'; + isTableView?: boolean; +} + +const DataGridLazy = withSuspense(lazy(() => import('./data_grid'))); + +export const ESQLDataGrid = (props: ESQLDataGridProps) => { + const { loading, value } = useAsync(() => { + const startServicesPromise = untilPluginStartServicesReady(); + return Promise.all([startServicesPromise]); + }, []); + + const deps = value?.[0]; + if (loading || !deps) return ; + + return ( + + +
+ +
+
+
+ ); +}; diff --git a/src/plugins/esql_datagrid/public/data_grid.tsx b/src/plugins/esql_datagrid/public/data_grid.tsx new file mode 100644 index 0000000000000..00d1ef2f541b6 --- /dev/null +++ b/src/plugins/esql_datagrid/public/data_grid.tsx @@ -0,0 +1,156 @@ +/* + * 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 React, { useState, useCallback, useMemo } from 'react'; +import { zipObject } from 'lodash'; +import { UnifiedDataTable, DataLoadingState, type SortOrder } from '@kbn/unified-data-table'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; +import type { ESQLRow } from '@kbn/es-types'; +import type { DatatableColumn, DatatableColumnMeta } from '@kbn/expressions-plugin/common'; +import type { AggregateQuery } from '@kbn/es-query'; +import type { DataTableRecord } from '@kbn/discover-utils/types'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { CoreStart } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import { RowViewer } from './row_viewer_lazy'; + +interface ESQLDataGridProps { + core: CoreStart; + data: DataPublicPluginStart; + fieldFormats: FieldFormatsStart; + rows: ESQLRow[]; + dataView: DataView; + columns: DatatableColumn[]; + query: AggregateQuery; + flyoutType?: 'overlay' | 'push'; + isTableView?: boolean; +} +type DataTableColumnsMeta = Record< + string, + { + type: DatatableColumnMeta['type']; + esType?: DatatableColumnMeta['esType']; + } +>; + +const sortOrder: SortOrder[] = []; + +const DataGrid: React.FC = (props) => { + const [expandedDoc, setExpandedDoc] = useState(undefined); + const [activeColumns, setActiveColumns] = useState( + props.isTableView ? props.columns.map((c) => c.name) : [] + ); + const [rowHeight, setRowHeight] = useState(5); + + const onSetColumns = useCallback((columns) => { + setActiveColumns(columns); + }, []); + + const renderDocumentView = useCallback( + ( + hit: DataTableRecord, + displayedRows: DataTableRecord[], + displayedColumns: string[], + customColumnsMeta?: DataTableColumnsMeta + ) => ( + { + setActiveColumns(activeColumns.filter((c) => c !== column)); + }} + onAddColumn={(column) => { + setActiveColumns([...activeColumns, column]); + }} + onClose={() => setExpandedDoc(undefined)} + setExpandedDoc={setExpandedDoc} + /> + ), + [activeColumns, props.core.notifications, props.dataView, props.flyoutType] + ); + + const columnsMeta = useMemo(() => { + return props.columns.reduce((acc, column) => { + acc[column.id] = { + type: column.meta?.type, + esType: column.meta?.esType ?? column.meta?.type, + }; + return acc; + }, {} as DataTableColumnsMeta); + }, [props.columns]); + + const rows: DataTableRecord[] = useMemo(() => { + const columnNames = props.columns?.map(({ name }) => name); + return props.rows + .map((row) => zipObject(columnNames, row)) + .map((row, idx: number) => { + return { + id: String(idx), + raw: row, + flattened: row, + } as unknown as DataTableRecord; + }); + }, [props.columns, props.rows]); + + const services = useMemo(() => { + const storage = new Storage(localStorage); + + return { + data: props.data, + theme: props.core.theme, + uiSettings: props.core.uiSettings, + toastNotifications: props.core.notifications.toasts, + fieldFormats: props.fieldFormats, + storage, + }; + }, [ + props.core.notifications.toasts, + props.core.theme, + props.core.uiSettings, + props.data, + props.fieldFormats, + ]); + + return ( + + ); +}; + +// eslint-disable-next-line import/no-default-export +export default DataGrid; diff --git a/src/plugins/esql_datagrid/public/index.ts b/src/plugins/esql_datagrid/public/index.ts new file mode 100644 index 0000000000000..14a92068f02cc --- /dev/null +++ b/src/plugins/esql_datagrid/public/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { ESQLDataGridPlugin } from './plugin'; +export { ESQLDataGrid } from './create_datagrid'; + +export function plugin() { + return new ESQLDataGridPlugin(); +} diff --git a/src/plugins/esql_datagrid/public/kibana_services.ts b/src/plugins/esql_datagrid/public/kibana_services.ts new file mode 100644 index 0000000000000..df52136ce021b --- /dev/null +++ b/src/plugins/esql_datagrid/public/kibana_services.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 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 { BehaviorSubject } from 'rxjs'; +import type { CoreStart } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; + +export let core: CoreStart; + +interface ServiceDeps { + core: CoreStart; + data: DataPublicPluginStart; + uiActions: UiActionsStart; + fieldFormats: FieldFormatsStart; +} + +const servicesReady$ = new BehaviorSubject(undefined); +export const untilPluginStartServicesReady = () => { + if (servicesReady$.value) return Promise.resolve(servicesReady$.value); + return new Promise((resolve) => { + const subscription = servicesReady$.subscribe((deps) => { + if (deps) { + subscription.unsubscribe(); + resolve(deps); + } + }); + }); +}; + +export const setKibanaServices = ( + kibanaCore: CoreStart, + data: DataPublicPluginStart, + uiActions: UiActionsStart, + fieldFormats: FieldFormatsStart +) => { + core = kibanaCore; + servicesReady$.next({ + core, + data, + uiActions, + fieldFormats, + }); +}; diff --git a/src/plugins/esql_datagrid/public/plugin.ts b/src/plugins/esql_datagrid/public/plugin.ts new file mode 100755 index 0000000000000..662d23c5190b8 --- /dev/null +++ b/src/plugins/esql_datagrid/public/plugin.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 type { Plugin, CoreStart, CoreSetup } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import { setKibanaServices } from './kibana_services'; + +interface ESQLDataGridPluginStart { + data: DataPublicPluginStart; + uiActions: UiActionsStart; + fieldFormats: FieldFormatsStart; +} +export class ESQLDataGridPlugin implements Plugin<{}, void> { + public setup(_: CoreSetup, {}: {}) { + return {}; + } + + public start(core: CoreStart, { data, uiActions, fieldFormats }: ESQLDataGridPluginStart): void { + setKibanaServices(core, data, uiActions, fieldFormats); + } + + public stop() {} +} diff --git a/src/plugins/esql_datagrid/public/row_viewer.test.tsx b/src/plugins/esql_datagrid/public/row_viewer.test.tsx new file mode 100644 index 0000000000000..712e23953fae9 --- /dev/null +++ b/src/plugins/esql_datagrid/public/row_viewer.test.tsx @@ -0,0 +1,119 @@ +/* + * 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 React from 'react'; +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import type { CoreStart } from '@kbn/core/public'; +import type { DataTableRecord } from '@kbn/discover-utils/types'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { setUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/plugin'; +import { mockUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/__mocks__'; +import { RowViewer } from './row_viewer'; + +describe('RowViewer', () => { + function renderComponent(closeFlyoutSpy?: jest.Mock, extraHit?: DataTableRecord) { + const dataView = { + title: 'foo', + id: 'foo', + name: 'foo', + toSpec: jest.fn(), + toMinimalSpec: jest.fn(), + isPersisted: jest.fn().mockReturnValue(false), + fields: { + getByName: jest.fn(), + }, + timeFieldName: 'timestamp', + }; + const columns = ['bytes', 'destination']; + const hit = { + flattened: { + bytes: 123, + destination: 'Amsterdam', + }, + id: '1', + raw: { + bytes: 123, + destination: 'Amsterdam', + }, + } as unknown as DataTableRecord; + + const hits = [hit]; + if (extraHit) { + hits.push(extraHit); + } + const services = { + toastNotifications: { + addSuccess: jest.fn(), + }, + }; + + setUnifiedDocViewerServices(mockUnifiedDocViewerServices); + + render( + + + + ); + } + + it('should render a flyout', async () => { + renderComponent(); + await waitFor(() => expect(screen.getByTestId('esqlRowDetailsFlyout')).toBeInTheDocument()); + }); + + it('should run the onClose prop when the close button is clicked', async () => { + const closeFlyoutSpy = jest.fn(); + renderComponent(closeFlyoutSpy); + await waitFor(() => { + userEvent.click(screen.getByTestId('esqlRowDetailsFlyoutCloseBtn')); + expect(closeFlyoutSpy).toHaveBeenCalled(); + }); + }); + + it('displays row navigation when there is more than 1 row available', async () => { + renderComponent(undefined, { + flattened: { + bytes: 456, + destination: 'Athens', + }, + id: '3', + raw: { + bytes: 456, + destination: 'Athens', + }, + } as unknown as DataTableRecord); + await waitFor(() => { + expect(screen.getByTestId('esqlTableRowNavigation')).toBeInTheDocument(); + }); + }); + + it('doesnt display row navigation when there is only 1 row available', async () => { + renderComponent(); + await waitFor(() => { + expect(screen.queryByTestId('esqlTableRowNavigation')).not.toBeInTheDocument(); + }); + }); +}); diff --git a/src/plugins/esql_datagrid/public/row_viewer.tsx b/src/plugins/esql_datagrid/public/row_viewer.tsx new file mode 100644 index 0000000000000..35c2b807fbbb3 --- /dev/null +++ b/src/plugins/esql_datagrid/public/row_viewer.tsx @@ -0,0 +1,235 @@ +/* + * 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 React, { useMemo, useCallback } from 'react'; +import { get } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { css } from '@emotion/react'; +import type { DataView } from '@kbn/data-views-plugin/public'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFlyoutResizable, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiTitle, + EuiPortal, + EuiPagination, + keys, + EuiButtonEmpty, + useEuiTheme, + useIsWithinMinBreakpoint, +} from '@elastic/eui'; +import type { DataTableRecord } from '@kbn/discover-utils/types'; +import type { DataTableColumnsMeta } from '@kbn/unified-data-table'; +import { UnifiedDocViewer } from '@kbn/unified-doc-viewer-plugin/public'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; +import { NotificationsStart } from '@kbn/core-notifications-browser'; + +export interface RowViewerProps { + toastNotifications?: NotificationsStart; + columns: string[]; + columnsMeta?: DataTableColumnsMeta; + hit: DataTableRecord; + hits?: DataTableRecord[]; + flyoutType?: 'push' | 'overlay'; + dataView: DataView; + onAddColumn: (column: string) => void; + onClose: () => void; + onRemoveColumn: (column: string) => void; + setExpandedDoc: (doc?: DataTableRecord) => void; +} + +function getIndexByDocId(hits: DataTableRecord[], id: string) { + return hits.findIndex((h) => { + return h.id === id; + }); +} + +export const FLYOUT_WIDTH_KEY = 'esqlTable:flyoutWidth'; +/** + * Flyout displaying an expanded ES|QL row + */ +export function RowViewer({ + hit, + hits, + dataView, + columns, + columnsMeta, + toastNotifications, + flyoutType = 'push', + onClose, + onRemoveColumn, + onAddColumn, + setExpandedDoc, +}: RowViewerProps) { + const { euiTheme } = useEuiTheme(); + + const isXlScreen = useIsWithinMinBreakpoint('xl'); + const DEFAULT_WIDTH = euiTheme.base * 34; + const defaultWidth = DEFAULT_WIDTH; + const [flyoutWidth, setFlyoutWidth] = useLocalStorage(FLYOUT_WIDTH_KEY, defaultWidth); + const minWidth = euiTheme.base * 24; + const maxWidth = euiTheme.breakpoint.xl; + + const actualHit = useMemo(() => hits?.find(({ id }) => id === hit?.id) || hit, [hit, hits]); + const pageCount = useMemo(() => (hits ? hits.length : 0), [hits]); + const activePage = useMemo(() => { + const id = hit.id; + if (!hits || pageCount <= 1) { + return -1; + } + + return getIndexByDocId(hits, id); + }, [hits, hit, pageCount]); + + const setPage = useCallback( + (index: number) => { + if (hits && hits[index]) { + setExpandedDoc(hits[index]); + } + }, + [hits, setExpandedDoc] + ); + + const onKeyDown = useCallback( + (ev: React.KeyboardEvent) => { + const nodeName = get(ev, 'target.nodeName', null); + if (typeof nodeName === 'string' && nodeName.toLowerCase() === 'input') { + return; + } + if (ev.key === keys.ARROW_LEFT || ev.key === keys.ARROW_RIGHT) { + ev.preventDefault(); + ev.stopPropagation(); + setPage(activePage + (ev.key === keys.ARROW_RIGHT ? 1 : -1)); + } + }, + [activePage, setPage] + ); + + const addColumn = useCallback( + (columnName: string) => { + onAddColumn(columnName); + toastNotifications?.toasts?.addSuccess?.( + i18n.translate('esqlDataGrid.grid.flyout.toastColumnAdded', { + defaultMessage: `Column '{columnName}' was added`, + values: { columnName }, + }) + ); + }, + [onAddColumn, toastNotifications] + ); + + const removeColumn = useCallback( + (columnName: string) => { + onRemoveColumn(columnName); + toastNotifications?.toasts?.addSuccess?.( + i18n.translate('esqlDataGrid.grid.flyout.toastColumnRemoved', { + defaultMessage: `Column '{columnName}' was removed`, + values: { columnName }, + }) + ); + }, + [onRemoveColumn, toastNotifications] + ); + + const renderDefaultContent = useCallback( + () => ( + + ), + [actualHit, addColumn, columns, columnsMeta, dataView, hits, removeColumn] + ); + + const bodyContent = renderDefaultContent(); + + return ( + + + + + + +

+ {i18n.translate('esqlDataGrid.grid.tableRow.docViewerEsqlDetailHeading', { + defaultMessage: 'Result', + })} +

+
+
+ {activePage !== -1 && ( + + + + )} +
+
+ {bodyContent} + + + {i18n.translate('esqlDataGrid.grid.flyout.close', { + defaultMessage: 'Close', + })} + + +
+
+ ); +} + +// eslint-disable-next-line import/no-default-export +export default RowViewer; diff --git a/src/plugins/esql_datagrid/public/row_viewer_lazy.tsx b/src/plugins/esql_datagrid/public/row_viewer_lazy.tsx new file mode 100644 index 0000000000000..a4fea13dffab2 --- /dev/null +++ b/src/plugins/esql_datagrid/public/row_viewer_lazy.tsx @@ -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 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 { withSuspense } from '@kbn/shared-ux-utility'; +import { lazy } from 'react'; +export type { RowViewerProps } from './row_viewer'; + +export const RowViewer = withSuspense(lazy(() => import('./row_viewer'))); diff --git a/src/plugins/esql_datagrid/tsconfig.json b/src/plugins/esql_datagrid/tsconfig.json new file mode 100644 index 0000000000000..5db30eb35fd20 --- /dev/null +++ b/src/plugins/esql_datagrid/tsconfig.json @@ -0,0 +1,33 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + }, + "include": [ + "../../typings/**/*", + "common/**/*", + "public/**/*", + ], + "kbn_references": [ + "@kbn/data-plugin", + "@kbn/es-types", + "@kbn/es-query", + "@kbn/discover-utils", + "@kbn/data-views-plugin", + "@kbn/expressions-plugin", + "@kbn/cell-actions", + "@kbn/unified-data-table", + "@kbn/kibana-utils-plugin", + "@kbn/kibana-react-plugin", + "@kbn/core", + "@kbn/ui-actions-plugin", + "@kbn/field-formats-plugin", + "@kbn/i18n", + "@kbn/unified-doc-viewer-plugin", + "@kbn/core-notifications-browser", + "@kbn/shared-ux-utility" + ], + "exclude": [ + "target/**/*", + ] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 912a135068d88..a3cb9e15a770d 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -816,6 +816,8 @@ "@kbn/esql-ast/*": ["packages/kbn-esql-ast/*"], "@kbn/esql-ast-inspector-plugin": ["examples/esql_ast_inspector"], "@kbn/esql-ast-inspector-plugin/*": ["examples/esql_ast_inspector/*"], + "@kbn/esql-datagrid": ["src/plugins/esql_datagrid"], + "@kbn/esql-datagrid/*": ["src/plugins/esql_datagrid/*"], "@kbn/esql-utils": ["packages/kbn-esql-utils"], "@kbn/esql-utils/*": ["packages/kbn-esql-utils/*"], "@kbn/esql-validation-autocomplete": ["packages/kbn-esql-validation-autocomplete"], diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc index 17a9812631e39..7408f5e5dd1c9 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc @@ -24,9 +24,9 @@ "licensing", "ml", "alerting", - "features" + "features", ], - "requiredBundles": ["kibanaReact"], + "requiredBundles": ["kibanaReact", "esqlDataGrid"], "optionalPlugins": ["cloud"], "extraPublicDirs": [] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.test.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.test.tsx index 6ac300fa7cb31..836b8f6ef7f93 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.test.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.test.tsx @@ -31,6 +31,9 @@ describe('VisualizeESQL', () => { toSpec: jest.fn(), toMinimalSpec: jest.fn(), isPersisted: jest.fn().mockReturnValue(false), + fields: { + getByName: jest.fn(), + }, }) ), }; @@ -73,6 +76,7 @@ describe('VisualizeESQL', () => { ObservabilityAIAssistantMultipaneFlyoutContext={ ObservabilityAIAssistantMultipaneFlyoutContext } + rows={[]} /> ); @@ -138,8 +142,61 @@ describe('VisualizeESQL', () => { }), }; renderComponent({}, lensService, undefined, ['There is an error mate']); + await waitFor(() => expect(screen.findByTestId('observabilityAiAssistantErrorsList'))); + }); + + it('should not display the table on first render', async () => { + const lensService = { + ...lensPluginMock.createStartContract(), + stateHelperApi: jest.fn().mockResolvedValue({ + formula: jest.fn(), + suggestions: jest.fn(), + }), + }; + renderComponent({}, lensService); + // the button to render a table should be present await waitFor(() => - expect(screen.getByTestId('observabilityAiAssistantErrorsList')).toBeInTheDocument() + expect(screen.findByTestId('observabilityAiAssistantLensESQLDisplayTableButton')) + ); + + await waitFor(() => + expect(screen.queryByTestId('observabilityAiAssistantESQLDataGrid')).not.toBeInTheDocument() + ); + }); + + it('should display the table when user clicks the table button', async () => { + const lensService = { + ...lensPluginMock.createStartContract(), + stateHelperApi: jest.fn().mockResolvedValue({ + formula: jest.fn(), + suggestions: jest.fn(), + }), + }; + renderComponent({}, lensService); + await waitFor(() => { + userEvent.click(screen.getByTestId('observabilityAiAssistantLensESQLDisplayTableButton')); + expect(screen.findByTestId('observabilityAiAssistantESQLDataGrid')); + }); + }); + + it('should render the ESQLDataGrid if Lens returns a table', async () => { + const lensService = { + ...lensPluginMock.createStartContract(), + stateHelperApi: jest.fn().mockResolvedValue({ + formula: jest.fn(), + suggestions: jest.fn(), + }), + }; + renderComponent( + { + attributes: { + visualizationType: 'lnsDatatable', + }, + }, + lensService ); + await waitFor(() => { + expect(screen.findByTestId('observabilityAiAssistantESQLDataGrid')); + }); }); }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx index 334db28a8b89a..fe850b18f4d5d 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/functions/visualize_esql.tsx @@ -15,6 +15,8 @@ import { EuiText, EuiDescriptionList, } from '@elastic/eui'; +import type { ESQLRow } from '@kbn/es-types'; +import { ESQLDataGrid } from '@kbn/esql-datagrid/public'; import type { DataViewsServicePublic } from '@kbn/data-views-plugin/public/types'; import { getESQLAdHocDataview, getIndexPatternFromESQLQuery } from '@kbn/esql-utils'; import type { DatatableColumn } from '@kbn/expressions-plugin/common'; @@ -63,6 +65,7 @@ interface VisualizeQueryResponsev0 { interface VisualizeQueryResponsev1 { data: { columns: DatatableColumn[]; + rows: ESQLRow[]; userOverrides?: unknown; }; content: { @@ -82,6 +85,8 @@ interface VisualizeESQLProps { uiActions: UiActionsStart; /** Datatable columns as returned from the ES|QL _query api, slightly processed to be kibana compliant */ columns: DatatableColumn[]; + /** Datatable rows as returned from the ES|QL _query api */ + rows: ESQLRow[]; /** The ES|QL query */ query: string; /** Actions handler */ @@ -106,6 +111,7 @@ export function VisualizeESQL({ dataViews, uiActions, columns, + rows, query, onActionClick, userOverrides, @@ -120,11 +126,17 @@ export function VisualizeESQL({ }, [lens]); const dataViewAsync = useAsync(() => { - return getESQLAdHocDataview(indexPattern, dataViews); + return getESQLAdHocDataview(indexPattern, dataViews).then((dataView) => { + if (dataView.fields.getByName('@timestamp')?.type === 'date') { + dataView.timeFieldName = '@timestamp'; + } + return dataView; + }); }, [indexPattern]); const chatFlyoutSecondSlotHandler = useContext(ObservabilityAIAssistantMultipaneFlyoutContext); const [isSaveModalOpen, setIsSaveModalOpen] = useState(false); + const [isTableVisible, setIsTableVisible] = useState(false); const [lensInput, setLensInput] = useState( userOverrides as TypedLensByValueInput ); @@ -238,88 +250,159 @@ export function VisualizeESQL({ if (!lensHelpersAsync.value || !dataViewAsync.value || !lensInput) { return ; } + // if the Lens suggestions api suggests a table then we want to render a Discover table instead + const isLensInputTable = lensInput?.attributes?.visualizationType === 'lnsDatatable'; + + const visualizationComponentDataTestSubj = isTableVisible + ? 'observabilityAiAssistantESQLDataGrid' + : 'observabilityAiAssistantESQLLensChart'; return ( <> - - {Boolean(errorMessages?.length) && ( - <> - - {i18n.translate('xpack.observabilityAiAssistant.lensESQLFunction.errorMessage', { - defaultMessage: 'There were some errors in the generated query', - })} - - - {errorMessages?.map((error, index) => { - return ( - - - - - - {error} - - - ); - })} - - - )} - - - - - { - chatFlyoutSecondSlotHandler?.setVisibility?.(true); - if (triggerOptions) { - uiActions.getTrigger('IN_APP_EMBEDDABLE_EDIT_TRIGGER').exec(triggerOptions); - } - }} - data-test-subj="observabilityAiAssistantLensESQLEditButton" - aria-label={i18n.translate('xpack.observabilityAiAssistant.lensESQLFunction.edit', { - defaultMessage: 'Edit visualization', + {!isLensInputTable && ( + + {Boolean(errorMessages?.length) && ( + <> + + {i18n.translate('xpack.observabilityAiAssistant.lensESQLFunction.errorMessage', { + defaultMessage: 'There were some errors in the generated query', })} - /> - - + + + {errorMessages?.map((error, index) => { + return ( + + + + + + {error} + + + ); + })} + + + )} + + + + + + setIsTableVisible(!isTableVisible)} + data-test-subj="observabilityAiAssistantLensESQLDisplayTableButton" + aria-label={ + isTableVisible + ? i18n.translate( + 'xpack.observabilityAiAssistant.lensESQLFunction.displayChart', + { + defaultMessage: 'Display chart', + } + ) + : i18n.translate( + 'xpack.observabilityAiAssistant.lensESQLFunction.displayTable', + { + defaultMessage: 'Display results', + } + ) + } + /> + + setIsSaveModalOpen(true)} - data-test-subj="observabilityAiAssistantLensESQLSaveButton" + iconType="pencil" + onClick={() => { + chatFlyoutSecondSlotHandler?.setVisibility?.(true); + if (triggerOptions) { + uiActions.getTrigger('IN_APP_EMBEDDABLE_EDIT_TRIGGER').exec(triggerOptions); + } + }} + data-test-subj="observabilityAiAssistantLensESQLEditButton" aria-label={i18n.translate( - 'xpack.observabilityAiAssistant.lensESQLFunction.save', + 'xpack.observabilityAiAssistant.lensESQLFunction.edit', { - defaultMessage: 'Save visualization', + defaultMessage: 'Edit visualization', } )} /> - - - - - + + setIsSaveModalOpen(true)} + data-test-subj="observabilityAiAssistantLensESQLSaveButton" + aria-label={i18n.translate( + 'xpack.observabilityAiAssistant.lensESQLFunction.save', + { + defaultMessage: 'Save visualization', + } + )} + /> + + + + + + {isTableVisible ? ( + + ) : ( + + )} + + + )} + {isLensInputTable && ( +
+ - - +
+ )} {isSaveModalOpen ? ( { const client = (await resources.context.core).elasticsearch.client.asCurrentUser; - const { error, errorMessages } = await validateEsqlQuery({ + const { error, errorMessages, rows, columns } = await runAndValidateEsqlQuery({ query, client, }); @@ -122,16 +121,12 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra }, }; } - const response = (await client.transport.request({ - method: 'POST', - path: '_query', - body: { - query, - }, - })) as ESQLSearchReponse; return { - content: response, + content: { + columns, + rows, + }, }; } ); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts index 268b1f5fb5fa6..154fb858342e4 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts @@ -8,11 +8,11 @@ import { validateQuery } from '@kbn/esql-validation-autocomplete'; import { getAstAndSyntaxErrors } from '@kbn/esql-ast'; import type { ElasticsearchClient } from '@kbn/core/server'; -import { ESQLSearchReponse } from '@kbn/es-types'; +import { ESQLSearchReponse, ESQLRow } from '@kbn/es-types'; import { esFieldTypeToKibanaFieldType, type KBN_FIELD_TYPES } from '@kbn/field-types'; import { splitIntoCommands } from './correct_common_esql_mistakes'; -export async function validateEsqlQuery({ +export async function runAndValidateEsqlQuery({ query, client, }: { @@ -26,6 +26,7 @@ export async function validateEsqlQuery({ type: KBN_FIELD_TYPES; }; }>; + rows?: ESQLRow[]; error?: Error; errorMessages?: string[]; }> { @@ -47,15 +48,12 @@ export async function validateEsqlQuery({ return 'text' in error ? error.text : error.message; }); - // With limit 0 I get only the columns, it is much more performant - const performantQuery = `${query} | limit 0`; - return client.transport .request({ method: 'POST', path: '_query', body: { - query: performantQuery, + query, }, }) .then((res) => { @@ -68,7 +66,7 @@ export async function validateEsqlQuery({ meta: { type: esFieldTypeToKibanaFieldType(type) }, })) ?? []; - return { columns }; + return { columns, rows: esqlResponse.values }; }) .catch((error) => { return { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts index 1523ca510238a..1979a0535083a 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/visualize_esql.ts @@ -7,7 +7,7 @@ import { VisualizeESQLUserIntention } from '@kbn/observability-ai-assistant-plugin/common/functions/visualize_esql'; import { visualizeESQLFunction } from '../../common/functions/visualize_esql'; import { FunctionRegistrationParameters } from '.'; -import { validateEsqlQuery } from './query/validate_esql_query'; +import { runAndValidateEsqlQuery } from './query/validate_esql_query'; const getMessageForLLM = ( intention: VisualizeESQLUserIntention, @@ -28,7 +28,7 @@ export function registerVisualizeESQLFunction({ resources, }: FunctionRegistrationParameters) { functions.registerFunction(visualizeESQLFunction, async ({ arguments: { query, intention } }) => { - const { columns, errorMessages } = await validateEsqlQuery({ + const { columns, errorMessages, rows } = await runAndValidateEsqlQuery({ query, client: (await resources.context.core).elasticsearch.client.asCurrentUser, }); @@ -38,6 +38,7 @@ export function registerVisualizeESQLFunction({ return { data: { columns, + rows, }, content: { message, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json index ce98c24be2a25..282363e50ec3f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json @@ -69,6 +69,7 @@ "@kbn/task-manager-plugin", "@kbn/cloud-plugin", "@kbn/observability-plugin", + "@kbn/esql-datagrid", "@kbn/alerting-comparators" ], "exclude": ["target/**/*"] diff --git a/yarn.lock b/yarn.lock index 66c3d86bcbbe7..c2a5e924f770f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4800,6 +4800,10 @@ version "0.0.0" uid "" +"@kbn/esql-datagrid@link:src/plugins/esql_datagrid": + version "0.0.0" + uid "" + "@kbn/esql-utils@link:packages/kbn-esql-utils": version "0.0.0" uid "" From 60801523d4518be6eb6c2c2657516beb133dc05b Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 5 Jun 2024 20:05:17 +0100 Subject: [PATCH 013/122] chore(NA): update versions after v8.14.1 bump (#184848) This PR is a simple update of our versions file after the recent bumps. --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 30d89496af039..b789d4463f918 100644 --- a/versions.json +++ b/versions.json @@ -8,7 +8,7 @@ "currentMinor": true }, { - "version": "8.14.0", + "version": "8.14.1", "branch": "8.14", "currentMajor": true, "previousMinor": true From bff17fe57fcb77d9b9df2866abf80b3cc6848dfd Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 5 Jun 2024 20:38:46 +0100 Subject: [PATCH 014/122] skip flaky suite (#184853) --- x-pack/test/monitoring_api_integration/apis/kibana/overview.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/monitoring_api_integration/apis/kibana/overview.ts b/x-pack/test/monitoring_api_integration/apis/kibana/overview.ts index 98a8687eedc06..3bb5bd3f3077e 100644 --- a/x-pack/test/monitoring_api_integration/apis/kibana/overview.ts +++ b/x-pack/test/monitoring_api_integration/apis/kibana/overview.ts @@ -28,7 +28,8 @@ export default function ({ getService }: FtrProviderContext) { }; testRunner(() => { - it('should get kibana rules at cluster level', async () => { + // FLAKY: https://github.com/elastic/kibana/issues/184853 + it.skip('should get kibana rules at cluster level', async () => { const { body } = await supertest .post('/api/monitoring/v1/clusters/rSEDbJNIQmOE-v9n2rV5cA') .set('kbn-xsrf', 'xxx') From 95604815e09b4aba9386e8de28927d21cbf98178 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Wed, 5 Jun 2024 21:49:27 +0200 Subject: [PATCH 015/122] Fix typo in ESQLSearchResponse type (#184861) Fixes a small typo in the `ESQLSearchResponse` (formerly known as `ESQLSearchReponse`). Co-authored-by: Stratoula Kalafateli --- packages/kbn-es-types/index.ts | 2 +- packages/kbn-es-types/src/index.ts | 4 ++-- packages/kbn-es-types/src/search.ts | 2 +- packages/kbn-esql-utils/src/utils/run_query.ts | 8 ++++---- packages/kbn-generate-csv/src/generate_csv_esql.test.ts | 2 +- packages/kbn-generate-csv/src/generate_csv_esql.ts | 4 ++-- .../field_stats_utils_text_based.ts | 4 ++-- src/plugins/data/common/search/expressions/esql.ts | 4 ++-- .../esql_requests/get_count_and_cardinality.ts | 4 ++-- .../classes/sources/esql_source/convert_to_geojson.ts | 4 ++-- .../public/classes/sources/esql_source/esql_source.tsx | 4 ++-- .../server/functions/query/validate_esql_query.ts | 4 ++-- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/kbn-es-types/index.ts b/packages/kbn-es-types/index.ts index 9d4c31644437b..0e78385d1792c 100644 --- a/packages/kbn-es-types/index.ts +++ b/packages/kbn-es-types/index.ts @@ -20,7 +20,7 @@ export type { MaybeReadonlyArray, ESQLColumn, ESQLRow, - ESQLSearchReponse, + ESQLSearchResponse, ESQLSearchParams, SearchField, } from './src'; diff --git a/packages/kbn-es-types/src/index.ts b/packages/kbn-es-types/src/index.ts index 5e2a67316fc9b..c5083f358aef2 100644 --- a/packages/kbn-es-types/src/index.ts +++ b/packages/kbn-es-types/src/index.ts @@ -17,7 +17,7 @@ import { SearchHit, ESQLColumn, ESQLRow, - ESQLSearchReponse, + ESQLSearchResponse, ESQLSearchParams, ChangePointType, } from './search'; @@ -53,7 +53,7 @@ export type { SearchHit, ESQLColumn, ESQLRow, - ESQLSearchReponse, + ESQLSearchResponse, ESQLSearchParams, ChangePointType, }; diff --git a/packages/kbn-es-types/src/search.ts b/packages/kbn-es-types/src/search.ts index 9802be6d13cb5..d6cae90f3c019 100644 --- a/packages/kbn-es-types/src/search.ts +++ b/packages/kbn-es-types/src/search.ts @@ -673,7 +673,7 @@ export interface ESQLColumn { export type ESQLRow = unknown[]; -export interface ESQLSearchReponse { +export interface ESQLSearchResponse { columns: ESQLColumn[]; // In case of ?drop_null_columns in the query, then // all_columns will have available and empty fields diff --git a/packages/kbn-esql-utils/src/utils/run_query.ts b/packages/kbn-esql-utils/src/utils/run_query.ts index 0de03d778507d..7c52365d76b98 100644 --- a/packages/kbn-esql-utils/src/utils/run_query.ts +++ b/packages/kbn-esql-utils/src/utils/run_query.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import type { ISearchGeneric } from '@kbn/search-types'; import { esFieldTypeToKibanaFieldType } from '@kbn/field-types'; -import type { ESQLColumn, ESQLSearchReponse, ESQLSearchParams } from '@kbn/es-types'; +import type { ESQLColumn, ESQLSearchResponse, ESQLSearchParams } from '@kbn/es-types'; import { lastValueFrom } from 'rxjs'; export function formatESQLColumns(columns: ESQLColumn[]): DatatableColumn[] { @@ -49,7 +49,7 @@ export async function getESQLQueryColumnsRaw({ ) ); - return (response.rawResponse as unknown as ESQLSearchReponse).columns ?? []; + return (response.rawResponse as unknown as ESQLSearchResponse).columns ?? []; } catch (error) { throw new Error( i18n.translate('esqlUtils.columnsErrorMsg', { @@ -100,7 +100,7 @@ export async function getESQLResults({ filter?: unknown; dropNullColumns?: boolean; }): Promise<{ - response: ESQLSearchReponse; + response: ESQLSearchResponse; params: ESQLSearchParams; }> { const result = await lastValueFrom( @@ -119,7 +119,7 @@ export async function getESQLResults({ ) ); return { - response: result.rawResponse as unknown as ESQLSearchReponse, + response: result.rawResponse as unknown as ESQLSearchResponse, params: result.requestParams as unknown as ESQLSearchParams, }; } diff --git a/packages/kbn-generate-csv/src/generate_csv_esql.test.ts b/packages/kbn-generate-csv/src/generate_csv_esql.test.ts index a59f86328a528..3eae4ed156bfa 100644 --- a/packages/kbn-generate-csv/src/generate_csv_esql.test.ts +++ b/packages/kbn-generate-csv/src/generate_csv_esql.test.ts @@ -23,7 +23,7 @@ import { IScopedSearchClient } from '@kbn/data-plugin/server'; import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; import { CancellationToken } from '@kbn/reporting-common'; import type { ReportingConfigType } from '@kbn/reporting-server'; -import type { ESQLSearchReponse as ESQLSearchResponse } from '@kbn/es-types'; +import type { ESQLSearchResponse } from '@kbn/es-types'; import { UI_SETTINGS_CSV_QUOTE_VALUES, UI_SETTINGS_CSV_SEPARATOR, diff --git a/packages/kbn-generate-csv/src/generate_csv_esql.ts b/packages/kbn-generate-csv/src/generate_csv_esql.ts index da9b2f7aaf0c1..02da7e9f147d7 100644 --- a/packages/kbn-generate-csv/src/generate_csv_esql.ts +++ b/packages/kbn-generate-csv/src/generate_csv_esql.ts @@ -14,7 +14,7 @@ import type { IKibanaSearchResponse, IKibanaSearchRequest } from '@kbn/search-ty import { ESQL_SEARCH_STRATEGY, cellHasFormulas, getEsQueryConfig } from '@kbn/data-plugin/common'; import type { IScopedSearchClient } from '@kbn/data-plugin/server'; import { type Filter, buildEsQuery } from '@kbn/es-query'; -import type { ESQLSearchParams, ESQLSearchReponse } from '@kbn/es-types'; +import type { ESQLSearchParams, ESQLSearchResponse } from '@kbn/es-types'; import { i18n } from '@kbn/i18n'; import { AuthenticationExpiredError, @@ -103,7 +103,7 @@ export class CsvESQLGenerator { const { rawResponse, warning } = await lastValueFrom( this.clients.data.search< IKibanaSearchRequest, - IKibanaSearchResponse + IKibanaSearchResponse >(searchParams, { strategy: ESQL_SEARCH_STRATEGY, abortSignal: abortController.signal, diff --git a/packages/kbn-unified-field-list/src/services/field_stats_text_based/field_stats_utils_text_based.ts b/packages/kbn-unified-field-list/src/services/field_stats_text_based/field_stats_utils_text_based.ts index 4a194b9c4978f..806a787ba139c 100644 --- a/packages/kbn-unified-field-list/src/services/field_stats_text_based/field_stats_utils_text_based.ts +++ b/packages/kbn-unified-field-list/src/services/field_stats_text_based/field_stats_utils_text_based.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { ESQLSearchReponse } from '@kbn/es-types'; +import type { ESQLSearchResponse } from '@kbn/es-types'; import { appendToESQLQuery } from '@kbn/esql-utils'; import type { DataViewField } from '@kbn/data-views-plugin/common'; import type { FieldStatsResponse } from '../../types'; @@ -22,7 +22,7 @@ import { } from '../../utils/can_provide_stats'; import { getFieldExampleBuckets } from '../field_examples_calculator'; -export type SearchHandlerTextBased = ({ query }: { query: string }) => Promise; +export type SearchHandlerTextBased = ({ query }: { query: string }) => Promise; export function buildSearchFilter({ timeFieldName, diff --git a/src/plugins/data/common/search/expressions/esql.ts b/src/plugins/data/common/search/expressions/esql.ts index a14d56dfbaebb..6073bc5297991 100644 --- a/src/plugins/data/common/search/expressions/esql.ts +++ b/src/plugins/data/common/search/expressions/esql.ts @@ -18,7 +18,7 @@ import { Observable, defer, throwError } from 'rxjs'; import { catchError, map, switchMap, tap } from 'rxjs'; import { buildEsQuery } from '@kbn/es-query'; import type { ISearchGeneric } from '@kbn/search-types'; -import type { ESQLSearchReponse, ESQLSearchParams } from '@kbn/es-types'; +import type { ESQLSearchResponse, ESQLSearchParams } from '@kbn/es-types'; import { getEsQueryConfig } from '../../es_query'; import { getTime } from '../../query'; import { ESQL_ASYNC_SEARCH_STRATEGY, KibanaContext, ESQL_TABLE_TYPE } from '..'; @@ -194,7 +194,7 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { return search< IKibanaSearchRequest, - IKibanaSearchResponse + IKibanaSearchResponse >( { params: { ...params, dropNullColumns: true } }, { abortSignal, strategy: ESQL_ASYNC_SEARCH_STRATEGY } diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/esql_requests/get_count_and_cardinality.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/esql_requests/get_count_and_cardinality.ts index fc4db29b758c4..f10af0b74ca27 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/esql_requests/get_count_and_cardinality.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/esql_requests/get_count_and_cardinality.ts @@ -8,7 +8,7 @@ import { ESQL_ASYNC_SEARCH_STRATEGY } from '@kbn/data-plugin/common'; import pLimit from 'p-limit'; import { chunk } from 'lodash'; import { isDefined } from '@kbn/ml-is-defined'; -import type { ESQLSearchReponse } from '@kbn/es-types'; +import type { ESQLSearchResponse } from '@kbn/es-types'; import { appendToESQLQuery } from '@kbn/esql-utils'; import type { UseCancellableSearch } from '@kbn/ml-cancellable-search'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -111,7 +111,7 @@ const getESQLOverallStatsInChunk = async ({ if (!esqlResults) { return; } - const esqlResultsResp = esqlResults.rawResponse as unknown as ESQLSearchReponse; + const esqlResultsResp = esqlResults.rawResponse as unknown as ESQLSearchResponse; const sampleCount = !isDefined(limitSize) ? totalCount : limitSize; fieldsToFetch.forEach((field, idx) => { diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/convert_to_geojson.ts b/x-pack/plugins/maps/public/classes/sources/esql_source/convert_to_geojson.ts index a446f976b5677..e524c419e59ec 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/convert_to_geojson.ts +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/convert_to_geojson.ts @@ -8,11 +8,11 @@ // @ts-ignore import { parse } from 'wellknown'; import { Feature, FeatureCollection, GeoJsonProperties } from 'geojson'; -import type { ESQLSearchReponse } from '@kbn/es-types'; +import type { ESQLSearchResponse } from '@kbn/es-types'; import { EMPTY_FEATURE_COLLECTION } from '../../../../common/constants'; import { isGeometryColumn } from './esql_utils'; -export function convertToGeoJson(resp: ESQLSearchReponse): FeatureCollection { +export function convertToGeoJson(resp: ESQLSearchResponse): FeatureCollection { const geometryColumnIndex = resp.columns.findIndex(isGeometryColumn); if (geometryColumnIndex === -1) { return EMPTY_FEATURE_COLLECTION; diff --git a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx index a40e8daf79d4a..da689d12eaee5 100644 --- a/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/esql_source/esql_source.tsx @@ -14,7 +14,7 @@ import { Adapters } from '@kbn/inspector-plugin/common/adapters'; import { getIndexPatternFromESQLQuery, getLimitFromESQLQuery } from '@kbn/esql-utils'; import { buildEsQuery } from '@kbn/es-query'; import type { Filter, Query } from '@kbn/es-query'; -import type { ESQLSearchParams, ESQLSearchReponse } from '@kbn/es-types'; +import type { ESQLSearchParams, ESQLSearchResponse } from '@kbn/es-types'; import { getEsQueryConfig } from '@kbn/data-service/src/es_query'; import { getTime } from '@kbn/data-plugin/public'; import { FIELD_ORIGIN, SOURCE_TYPES, VECTOR_SHAPE_TYPE } from '../../../../common/constants'; @@ -238,7 +238,7 @@ export class ESQLSource requestResponder.ok({ json: rawResponse, requestParams }); - const esqlSearchResponse = rawResponse as unknown as ESQLSearchReponse; + const esqlSearchResponse = rawResponse as unknown as ESQLSearchResponse; const resultsCount = esqlSearchResponse.values.length; return { data: convertToGeoJson(esqlSearchResponse), diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts index 154fb858342e4..598feaacf8d51 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts @@ -8,7 +8,7 @@ import { validateQuery } from '@kbn/esql-validation-autocomplete'; import { getAstAndSyntaxErrors } from '@kbn/esql-ast'; import type { ElasticsearchClient } from '@kbn/core/server'; -import { ESQLSearchReponse, ESQLRow } from '@kbn/es-types'; +import { ESQLSearchResponse, ESQLRow } from '@kbn/es-types'; import { esFieldTypeToKibanaFieldType, type KBN_FIELD_TYPES } from '@kbn/field-types'; import { splitIntoCommands } from './correct_common_esql_mistakes'; @@ -57,7 +57,7 @@ export async function runAndValidateEsqlQuery({ }, }) .then((res) => { - const esqlResponse = res as ESQLSearchReponse; + const esqlResponse = res as ESQLSearchResponse; const columns = esqlResponse.columns?.map(({ name, type }) => ({ From 1772203328eb90c1be38033b441571491a551053 Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Wed, 5 Jun 2024 15:01:27 -0500 Subject: [PATCH 016/122] [data views editor] Disable loading rollups when rollups are disabled (#184765) ## Summary Previously we were checking the `/api/rollup/indices` endpoint when the data view editor was loaded. If rollups were disabled, it would harmlessly handle a 404 error. Still, people justifiably wonder whether something is wrong. This PR skips checking the endpoint as one would expect. A unit test has been added. I also manually verified the behavior is as expected. Follow up to https://github.com/elastic/kibana/pull/162674 --------- Co-authored-by: Lukas Olson --- .../public/data_view_editor_service.test.ts | 46 +++++++++++++++++++ .../public/data_view_editor_service.ts | 3 ++ 2 files changed, 49 insertions(+) create mode 100644 src/plugins/data_view_editor/public/data_view_editor_service.test.ts diff --git a/src/plugins/data_view_editor/public/data_view_editor_service.test.ts b/src/plugins/data_view_editor/public/data_view_editor_service.test.ts new file mode 100644 index 0000000000000..02e79d01e1e3c --- /dev/null +++ b/src/plugins/data_view_editor/public/data_view_editor_service.test.ts @@ -0,0 +1,46 @@ +/* + * 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 { DataViewEditorService } from './data_view_editor_service'; +import { HttpSetup } from '@kbn/core/public'; +import { DataViewsServicePublic } from '@kbn/data-views-plugin/public'; + +describe('DataViewEditorService', () => { + it('should check for rollup indices when rolls are enabled', () => { + const get = jest.fn(); + const http = { get } as unknown as HttpSetup; + new DataViewEditorService({ + services: { + http, + dataViews: { + getIdsWithTitle: jest.fn().mockResolvedValue([]), + getRollupsEnabled: jest.fn().mockReturnValue(true), + } as unknown as DataViewsServicePublic, + }, + initialValues: {}, + }); + + expect(get).toHaveBeenCalledTimes(1); + expect(get.mock.calls[0][0]).toEqual('/api/rollup/indices'); + }); + it('should skip check for rollup indices when rollups are disabled', () => { + const http = { get: jest.fn() } as unknown as HttpSetup; + new DataViewEditorService({ + services: { + http, + dataViews: { + getIdsWithTitle: jest.fn().mockResolvedValue([]), + getRollupsEnabled: jest.fn().mockReturnValue(false), + } as unknown as DataViewsServicePublic, + }, + initialValues: {}, + }); + + expect(http.get).toHaveBeenCalledTimes(0); + }); +}); diff --git a/src/plugins/data_view_editor/public/data_view_editor_service.ts b/src/plugins/data_view_editor/public/data_view_editor_service.ts index 52ac001b1f0a4..01c1842ee9425 100644 --- a/src/plugins/data_view_editor/public/data_view_editor_service.ts +++ b/src/plugins/data_view_editor/public/data_view_editor_service.ts @@ -179,6 +179,9 @@ export class DataViewEditorService { }; private getRollupIndexCaps = async () => { + if (this.dataViews.getRollupsEnabled() === false) { + return {}; + } let rollupIndicesCaps: RollupIndicesCapsResponse = {}; try { rollupIndicesCaps = await this.http.get('/api/rollup/indices'); From dceae3e5c37c5c115366f59f5d57d9f55bfa742a Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 5 Jun 2024 13:53:16 -0700 Subject: [PATCH 017/122] [UII] Remove references to `.fleet-servers` index (#183868) ## Summary Resolves https://github.com/elastic/kibana/issues/173537. This PR removes all usages and references to `.fleet-servers` index. A small refactoring was done that moves helper functions in enrollment settings API to fleet server services. It's a better place for them because they are related to fleet server anyway. With this change, we now use these functions to calculate the readiness of Fleet (`hasFleetServers` was previously reading on `.fleet-servers` index). The readiness of a fleet server is defined as at least one online agent enrolled into an agent policy that contains a fleet server policy. ### Changes in Security Solution (@paul-tavares) - Updated `enableFleetServerIfNecessary()` utility _(used for testing, dev)_ to not use `.fleet-servers` index and instead write a Agent record to the `.fleet-agents` index for Fleet Server. This record writing is skipped when running tests in serverless mode, instead, `xpack.fleet.internal.fleetServerStandalone=true` is added to mimic skipping checks for Fleet Server in real serverless. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Paul Tavares --- .../plugins/fleet/common/constants/index.ts | 3 - x-pack/plugins/fleet/common/index.ts | 1 - .../fleet/cypress/e2e/agents/agent_list.cy.ts | 4 +- .../cypress/e2e/fleet_agent_flyout.cy.ts | 11 +- .../fleet/cypress/e2e/fleet_startup.cy.ts | 4 +- x-pack/plugins/fleet/cypress/tasks/cleanup.ts | 7 - .../fleet/cypress/tasks/fleet_server.ts | 16 -- x-pack/plugins/fleet/dev_docs/data_model.md | 4 - .../debug/components/fleet_index_debugger.tsx | 1 - .../plugins/fleet/server/constants/index.ts | 1 - .../enrollment_settings_handler.test.ts | 110 ++--------- .../settings/enrollment_settings_handler.ts | 56 ++---- .../fleet/server/routes/setup/handlers.ts | 4 +- .../fleet/server/services/agents/status.ts | 4 +- .../services/fleet_server/index.test.ts | 182 +++++++++++++++++- .../server/services/fleet_server/index.ts | 72 ++++++- .../data_generators/fleet_agent_generator.ts | 7 +- .../data_loaders/index_fleet_agent.ts | 37 +++- .../data_loaders/index_fleet_server.ts | 176 +++++++++++++---- .../common/endpoint/data_loaders/utils.ts | 6 +- .../common/endpoint/index_data.ts | 3 +- .../management/cypress/support/common.ts | 6 +- .../cypress/support/data_loaders.ts | 1 + .../plugin_handlers/endpoint_data_loader.ts | 50 ++++- .../services/endpoint_loader.ts | 4 +- .../fleet_server/fleet_server_services.ts | 98 ++-------- .../serverless_config.ts | 5 + .../es_archives/fleet/agents/mappings.json | 64 ------ .../fleet/empty_fleet_server/mappings.json | 63 ------ .../services/endpoint.ts | 1 + 30 files changed, 539 insertions(+), 462 deletions(-) diff --git a/x-pack/plugins/fleet/common/constants/index.ts b/x-pack/plugins/fleet/common/constants/index.ts index 6e9af1e7d269c..31a7cd6b70686 100644 --- a/x-pack/plugins/fleet/common/constants/index.ts +++ b/x-pack/plugins/fleet/common/constants/index.ts @@ -37,8 +37,6 @@ export const FLEET_SERVER_INDICES_VERSION = 1; export const FLEET_SERVER_ARTIFACTS_INDEX = '.fleet-artifacts'; -export const FLEET_SERVER_SERVERS_INDEX = '.fleet-servers'; - export const FLEET_SERVER_INDICES = [ '.fleet-actions', '.fleet-actions-results', @@ -47,7 +45,6 @@ export const FLEET_SERVER_INDICES = [ '.fleet-enrollment-api-keys', '.fleet-policies', '.fleet-policies-leader', - FLEET_SERVER_SERVERS_INDEX, ]; // Nodes that can be queried by datastreams API diff --git a/x-pack/plugins/fleet/common/index.ts b/x-pack/plugins/fleet/common/index.ts index f572273a486a9..9b50a140a7e93 100644 --- a/x-pack/plugins/fleet/common/index.ts +++ b/x-pack/plugins/fleet/common/index.ts @@ -32,7 +32,6 @@ export { MESSAGE_SIGNING_KEYS_SAVED_OBJECT_TYPE, UNINSTALL_TOKENS_SAVED_OBJECT_TYPE, // Fleet server index - FLEET_SERVER_SERVERS_INDEX, FLEET_SERVER_ARTIFACTS_INDEX, AGENTS_INDEX, AGENT_POLICY_INDEX, diff --git a/x-pack/plugins/fleet/cypress/e2e/agents/agent_list.cy.ts b/x-pack/plugins/fleet/cypress/e2e/agents/agent_list.cy.ts index 459fa5f53bfc5..55c0e61057c9d 100644 --- a/x-pack/plugins/fleet/cypress/e2e/agents/agent_list.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/agents/agent_list.cy.ts @@ -9,7 +9,7 @@ import { FLEET_AGENT_LIST_PAGE } from '../../screens/fleet'; import { createAgentDoc } from '../../tasks/agents'; import { setupFleetServer } from '../../tasks/fleet_server'; -import { deleteFleetServerDocs, deleteAgentDocs, cleanupAgentPolicies } from '../../tasks/cleanup'; +import { deleteAgentDocs, cleanupAgentPolicies } from '../../tasks/cleanup'; import type { CreateAgentPolicyRequest } from '../../../common/types'; import { setUISettings } from '../../tasks/ui_settings'; @@ -87,7 +87,6 @@ function assertTableIsEmpty() { describe('View agents list', () => { before(() => { - deleteFleetServerDocs(true); deleteAgentDocs(true); cleanupAgentPolicies(); setupFleetServer(); @@ -103,7 +102,6 @@ describe('View agents list', () => { } }); after(() => { - deleteFleetServerDocs(true); deleteAgentDocs(true); cleanupAgentPolicies(); }); diff --git a/x-pack/plugins/fleet/cypress/e2e/fleet_agent_flyout.cy.ts b/x-pack/plugins/fleet/cypress/e2e/fleet_agent_flyout.cy.ts index 5c653ea3fcf21..97964d230e74b 100644 --- a/x-pack/plugins/fleet/cypress/e2e/fleet_agent_flyout.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/fleet_agent_flyout.cy.ts @@ -6,7 +6,7 @@ */ import { ADD_AGENT_BUTTON, AGENT_FLYOUT } from '../screens/fleet'; -import { cleanupAgentPolicies, deleteFleetServerDocs, deleteAgentDocs } from '../tasks/cleanup'; +import { cleanupAgentPolicies, deleteAgentDocs } from '../tasks/cleanup'; import { createAgentDoc } from '../tasks/agents'; import { setFleetServerHost } from '../tasks/fleet_server'; import { FLEET, navigateTo } from '../tasks/navigation'; @@ -18,7 +18,6 @@ import { login } from '../tasks/login'; const FLEET_SERVER_POLICY_ID = 'fleet-server-policy'; function cleanUp() { - deleteFleetServerDocs(true); deleteAgentDocs(true); cleanupAgentPolicies(); } @@ -53,14 +52,6 @@ describe('Fleet add agent flyout', () => { index: '.fleet-agents', docs: [createAgentDoc('agent1', policyId, 'online', kibanaVersion)], }); - cy.task('insertDocs', { - index: '.fleet-servers', - docs: [ - { - '@timestamp': new Date().toISOString(), - }, - ], - }); setFleetServerHost(); }); diff --git a/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts b/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts index 21eefd56eedea..523004f60261e 100644 --- a/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts @@ -19,7 +19,7 @@ import { import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup'; import { request } from '../tasks/common'; import { verifyPolicy, verifyAgentPackage, navigateToTab } from '../tasks/fleet'; -import { deleteFleetServer, setFleetServerHost } from '../tasks/fleet_server'; +import { setFleetServerHost } from '../tasks/fleet_server'; import { login } from '../tasks/login'; import { FLEET, navigateTo } from '../tasks/navigation'; @@ -28,8 +28,6 @@ describe('Fleet startup', () => { before(() => { unenrollAgent(); cleanupAgentPolicies(); - deleteFleetServer(); - setFleetServerHost(); }); diff --git a/x-pack/plugins/fleet/cypress/tasks/cleanup.ts b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts index c2d873d9b8dee..5e179bc9207f1 100644 --- a/x-pack/plugins/fleet/cypress/tasks/cleanup.ts +++ b/x-pack/plugins/fleet/cypress/tasks/cleanup.ts @@ -48,13 +48,6 @@ export function cleanupDownloadSources() { }); } -export function deleteFleetServerDocs(ignoreUnavailable: boolean = false) { - cy.task('deleteDocsByQuery', { - index: '.fleet-servers', - query: { match_all: {} }, - ignoreUnavailable, - }); -} export function deleteAgentDocs(ignoreUnavailable: boolean = false) { cy.task('deleteDocsByQuery', { index: '.fleet-agents', diff --git a/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts b/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts index e6bb58d7c2b9b..9907312042da8 100644 --- a/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts +++ b/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts @@ -44,26 +44,10 @@ export async function setupFleetServer() { index: '.fleet-agents', docs: [createAgentDoc('fleet-server', policyId, 'online', kibanaVersion)], }); - cy.task('insertDocs', { - index: '.fleet-servers', - docs: [ - { - '@timestamp': new Date().toISOString(), - }, - ], - }); setFleetServerHost(); }); } -export function deleteFleetServer() { - cy.task('deleteDocsByQuery', { - index: '.fleet-servers', - query: { match_all: {} }, - ignoreUnavailable: true, - }); -} - export function setFleetServerHost(host = 'https://fleetserver:8220') { request({ method: 'POST', diff --git a/x-pack/plugins/fleet/dev_docs/data_model.md b/x-pack/plugins/fleet/dev_docs/data_model.md index 1e74afe3115b9..44183cb597ae2 100644 --- a/x-pack/plugins/fleet/dev_docs/data_model.md +++ b/x-pack/plugins/fleet/dev_docs/data_model.md @@ -58,10 +58,6 @@ The total schema for actions is represented by the `FleetServerAgentAction` type - Cleanup model: N/A -### `.fleet-servers` - -- Cleanup model: N/A - ### `.fleet-artifacts` - Cleanup model: N/A diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx index f84468fb14738..71d4b85981954 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/debug/components/fleet_index_debugger.tsx @@ -43,7 +43,6 @@ export const FleetIndexDebugger = () => { const indices = [ { label: '.fleet-agents', value: '.fleet-agents' }, { label: '.fleet-actions', value: '.fleet-actions' }, - { label: '.fleet-servers', value: '.fleet-servers' }, { label: '.fleet-enrollment-api-keys', value: '.fleet-enrollment-api-keys' }, ]; const [index, setIndex] = useState(); diff --git a/x-pack/plugins/fleet/server/constants/index.ts b/x-pack/plugins/fleet/server/constants/index.ts index 87db7250513be..4b71f9e16c8d6 100644 --- a/x-pack/plugins/fleet/server/constants/index.ts +++ b/x-pack/plugins/fleet/server/constants/index.ts @@ -58,7 +58,6 @@ export { PACKAGE_POLICY_DEFAULT_INDEX_PRIVILEGES, AGENT_POLICY_DEFAULT_MONITORING_DATASETS, // Fleet Server index - FLEET_SERVER_SERVERS_INDEX, ENROLLMENT_API_KEYS_INDEX, AGENTS_INDEX, // Preconfiguration diff --git a/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.test.ts b/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.test.ts index 6862b36537ef5..b41debffb3e6b 100644 --- a/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.test.ts +++ b/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.test.ts @@ -4,21 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { savedObjectsClientMock, elasticsearchServiceMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock } from '@kbn/core/server/mocks'; -import { packagePolicyService, agentPolicyService } from '../../services'; -import { getAgentStatusForAgentPolicy } from '../../services/agents'; +import { agentPolicyService } from '../../services'; +import { getFleetServerPolicies } from '../../services/fleet_server'; -import { - getFleetServerPolicies, - hasActiveFleetServersForPolicies, - getDownloadSource, -} from './enrollment_settings_handler'; +import { getFleetServerOrAgentPolicies, getDownloadSource } from './enrollment_settings_handler'; jest.mock('../../services', () => ({ - packagePolicyService: { - list: jest.fn(), - }, agentPolicyService: { get: jest.fn(), getByIDs: jest.fn(), @@ -44,13 +37,12 @@ jest.mock('../../services', () => ({ }, })); -jest.mock('../../services/agents', () => ({ - getAgentStatusForAgentPolicy: jest.fn(), +jest.mock('../../services/fleet_server', () => ({ + getFleetServerPolicies: jest.fn(), })); describe('EnrollmentSettingsHandler utils', () => { const mockSoClient = savedObjectsClientMock.create(); - const mockEsClient = elasticsearchServiceMock.createInternalClient(); const mockAgentPolicies = [ { id: 'agent-policy-1', @@ -124,20 +116,21 @@ describe('EnrollmentSettingsHandler utils', () => { }, ]; - describe('getFleetServerPolicies', () => { + describe('getFleetServerOrAgentPolicies', () => { it('returns only fleet server policies if there are any when no agent policy ID is provided', async () => { - (packagePolicyService.list as jest.Mock).mockResolvedValueOnce({ - items: [{ policy_id: 'fs-policy-1' }, { policy_id: 'fs-policy-2' }], - }); - (agentPolicyService.getByIDs as jest.Mock).mockResolvedValueOnce(mockFleetServerPolicies); - const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerPolicies(mockSoClient); + (getFleetServerPolicies as jest.Mock).mockResolvedValueOnce(mockFleetServerPolicies); + const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerOrAgentPolicies( + mockSoClient + ); expect(fleetServerPolicies).toEqual(mockFleetServerPolicies); expect(scopedAgentPolicy).toBeUndefined(); }); it('returns no fleet server policies when there are none and no agent policy ID is provided', async () => { - (packagePolicyService.list as jest.Mock).mockResolvedValueOnce({ items: [] }); - const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerPolicies(mockSoClient); + (getFleetServerPolicies as jest.Mock).mockResolvedValueOnce([]); + const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerOrAgentPolicies( + mockSoClient + ); expect(fleetServerPolicies).toEqual([]); expect(scopedAgentPolicy).toBeUndefined(); }); @@ -147,7 +140,7 @@ describe('EnrollmentSettingsHandler utils', () => { ...mockFleetServerPolicies[1], package_policies: [mockPackagePolicies[1]], }); - const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerPolicies( + const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerOrAgentPolicies( mockSoClient, 'fs-policy-2' ); @@ -160,7 +153,7 @@ describe('EnrollmentSettingsHandler utils', () => { ...mockAgentPolicies[1], package_policies: [mockPackagePolicies[2]], }); - const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerPolicies( + const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerOrAgentPolicies( mockSoClient, 'agent-policy-2' ); @@ -170,7 +163,7 @@ describe('EnrollmentSettingsHandler utils', () => { it('returns no policies when specified agent policy ID is not found', async () => { (agentPolicyService.get as jest.Mock).mockResolvedValueOnce(undefined); - const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerPolicies( + const { fleetServerPolicies, scopedAgentPolicy } = await getFleetServerOrAgentPolicies( mockSoClient, 'agent-policy-3' ); @@ -179,73 +172,6 @@ describe('EnrollmentSettingsHandler utils', () => { }); }); - describe('hasActiveFleetServersForPolicies', () => { - it('returns false when no agent IDs are provided', async () => { - const hasActive = await hasActiveFleetServersForPolicies(mockEsClient, mockSoClient, []); - expect(hasActive).toBe(false); - }); - - it('returns true when at least one agent is online', async () => { - (getAgentStatusForAgentPolicy as jest.Mock).mockResolvedValueOnce({ - other: 0, - events: 0, - total: 1, - all: 1, - active: 0, - updating: 0, - offline: 0, - inactive: 0, - unenrolled: 0, - online: 1, - error: 0, - }); - const hasActive = await hasActiveFleetServersForPolicies(mockEsClient, mockSoClient, [ - 'policy-1', - ]); - expect(hasActive).toBe(true); - }); - - it('returns true when at least one agent is updating', async () => { - (getAgentStatusForAgentPolicy as jest.Mock).mockResolvedValueOnce({ - other: 0, - events: 0, - total: 1, - all: 1, - active: 0, - updating: 1, - offline: 0, - inactive: 0, - unenrolled: 0, - online: 0, - error: 0, - }); - const hasActive = await hasActiveFleetServersForPolicies(mockEsClient, mockSoClient, [ - 'policy-1', - ]); - expect(hasActive).toBe(true); - }); - - it('returns false when no agents are updating or online', async () => { - (getAgentStatusForAgentPolicy as jest.Mock).mockResolvedValueOnce({ - other: 0, - events: 0, - total: 3, - all: 3, - active: 1, - updating: 0, - offline: 1, - inactive: 1, - unenrolled: 1, - online: 0, - error: 1, - }); - const hasActive = await hasActiveFleetServersForPolicies(mockEsClient, mockSoClient, [ - 'policy-1', - ]); - expect(hasActive).toBe(false); - }); - }); - describe('getDownloadSource', () => { it('returns the default download source when no id is specified', async () => { const source = await getDownloadSource(mockSoClient); diff --git a/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.ts b/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.ts index 766882bebe640..1662fed3fc31b 100644 --- a/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.ts +++ b/x-pack/plugins/fleet/server/routes/settings/enrollment_settings_handler.ts @@ -7,9 +7,9 @@ import type { TypeOf } from '@kbn/config-schema'; -import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; +import type { SavedObjectsClientContract } from '@kbn/core/server'; -import { PACKAGE_POLICY_SAVED_OBJECT_TYPE, FLEET_SERVER_PACKAGE } from '../../../common/constants'; +import { FLEET_SERVER_PACKAGE } from '../../../common/constants'; import type { GetEnrollmentSettingsResponse, @@ -18,10 +18,10 @@ import type { } from '../../../common/types'; import type { FleetRequestHandler, GetEnrollmentSettingsRequestSchema } from '../../types'; import { defaultFleetErrorHandler } from '../../errors'; -import { agentPolicyService, packagePolicyService, downloadSourceService } from '../../services'; -import { getAgentStatusForAgentPolicy } from '../../services/agents'; +import { agentPolicyService, downloadSourceService } from '../../services'; import { getFleetServerHostsForAgentPolicy } from '../../services/fleet_server_host'; import { getFleetProxy } from '../../services/fleet_proxies'; +import { getFleetServerPolicies, hasFleetServersForPolicies } from '../../services/fleet_server'; export const getEnrollmentSettingsHandler: FleetRequestHandler< undefined, @@ -40,7 +40,7 @@ export const getEnrollmentSettingsHandler: FleetRequestHandler< try { // Get all possible fleet server or scoped normal agent policies const { fleetServerPolicies, scopedAgentPolicy: scopedAgentPolicyResponse } = - await getFleetServerPolicies(soClient, agentPolicyId); + await getFleetServerOrAgentPolicies(soClient, agentPolicyId); const scopedAgentPolicy = scopedAgentPolicyResponse || { id: undefined, name: undefined, @@ -51,10 +51,11 @@ export const getEnrollmentSettingsHandler: FleetRequestHandler< // Check if there is any active fleet server enrolled into the fleet server policies policies if (fleetServerPolicies) { settingsResponse.fleet_server.policies = fleetServerPolicies; - settingsResponse.fleet_server.has_active = await hasActiveFleetServersForPolicies( + settingsResponse.fleet_server.has_active = await hasFleetServersForPolicies( esClient, soClient, - fleetServerPolicies.map((p) => p.id) + fleetServerPolicies.map((p) => p.id), + true ); } @@ -99,7 +100,7 @@ export const getEnrollmentSettingsHandler: FleetRequestHandler< } }; -export const getFleetServerPolicies = async ( +export const getFleetServerOrAgentPolicies = async ( soClient: SavedObjectsClientContract, agentPolicyId?: string ): Promise<{ @@ -134,42 +135,9 @@ export const getFleetServerPolicies = async ( return {}; } - // If an agent policy is not specified, perform default behavior to retrieve all fleet server policies - const fleetServerPackagePolicies = await packagePolicyService.list(soClient, { - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${FLEET_SERVER_PACKAGE}`, - }); - - // Extract associated fleet server agent policy IDs - const fleetServerAgentPolicyIds = [ - ...new Set(fleetServerPackagePolicies.items.map((p) => p.policy_id)), - ]; - - // Retrieve associated agent policies - const fleetServerAgentPolicies = fleetServerAgentPolicyIds.length - ? await agentPolicyService.getByIDs(soClient, fleetServerAgentPolicyIds) - : []; - - return { - fleetServerPolicies: fleetServerAgentPolicies.map(mapPolicy), - }; -}; - -export const hasActiveFleetServersForPolicies = async ( - esClient: ElasticsearchClient, - soClient: SavedObjectsClientContract, - agentPolicyIds: string[] -): Promise => { - if (agentPolicyIds.length > 0) { - const agentStatusesRes = await getAgentStatusForAgentPolicy( - esClient, - soClient, - undefined, - agentPolicyIds.map((id) => `policy_id:${id}`).join(' or ') - ); - - return agentStatusesRes.online > 0 || agentStatusesRes.updating > 0; - } - return false; + // If an agent policy is not specified, return all fleet server policies + const fleetServerPolicies = (await getFleetServerPolicies(soClient)).map(mapPolicy); + return { fleetServerPolicies }; }; export const getDownloadSource = async ( diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.ts index 5cbdd87ebb142..58555f233142a 100644 --- a/x-pack/plugins/fleet/server/routes/setup/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/setup/handlers.ts @@ -25,9 +25,7 @@ export const getFleetStatusHandler: FleetRequestHandler = async (context, reques const isApiKeysEnabled = await appContextService .getSecurity() .authc.apiKeys.areAPIKeysEnabled(); - const isFleetServerMissing = !(await hasFleetServers( - coreContext.elasticsearch.client.asInternalUser - )); + const isFleetServerMissing = !(await hasFleetServers(esClient, soClient)); const isFleetServerStandalone = appContextService.getConfig()?.internal?.fleetServerStandalone ?? false; diff --git a/x-pack/plugins/fleet/server/services/agents/status.ts b/x-pack/plugins/fleet/server/services/agents/status.ts index 041298d57b4eb..f4d0e312ba027 100644 --- a/x-pack/plugins/fleet/server/services/agents/status.ts +++ b/x-pack/plugins/fleet/server/services/agents/status.ts @@ -130,14 +130,14 @@ export async function getAgentStatusForAgentPolicy( const allActive = allStatuses - combinedStatuses.unenrolled - combinedStatuses.inactive; return { ...combinedStatuses, + all: allStatuses, + active: allActive, /* @deprecated no agents will have other status */ other: 0, /* @deprecated Agent events do not exists anymore */ events: 0, /* @deprecated use active instead */ total: allActive, - all: allStatuses, - active: allActive, }; } export async function getIncomingDataByAgentsId( diff --git a/x-pack/plugins/fleet/server/services/fleet_server/index.test.ts b/x-pack/plugins/fleet/server/services/fleet_server/index.test.ts index aef5bb9fcc916..b5a2a38b73685 100644 --- a/x-pack/plugins/fleet/server/services/fleet_server/index.test.ts +++ b/x-pack/plugins/fleet/server/services/fleet_server/index.test.ts @@ -15,9 +15,13 @@ import { createAppContextStartContractMock } from '../../mocks'; import { agentPolicyService } from '../agent_policy'; import { packagePolicyService } from '../package_policy'; -import { getAgentsByKuery, getAgentStatusById } from '../agents'; +import { getAgentsByKuery, getAgentStatusById, getAgentStatusForAgentPolicy } from '../agents'; -import { checkFleetServerVersionsForSecretsStorage } from '.'; +import { + checkFleetServerVersionsForSecretsStorage, + hasFleetServersForPolicies, + getFleetServerPolicies, +} from '.'; jest.mock('../agent_policy'); jest.mock('../package_policy'); @@ -111,3 +115,177 @@ describe('checkFleetServerVersionsForSecretsStorage', () => { expect(result).toBe(true); }); }); + +describe('getFleetServerPolicies', () => { + const soClient = savedObjectsClientMock.create(); + const mockPackagePolicies = [ + { + id: 'package-policy-1', + name: 'Package Policy 1', + package: { + name: 'fleet_server', + title: 'Fleet Server', + version: '1.0.0', + }, + policy_id: 'fs-policy-1', + }, + { + id: 'package-policy-2', + name: 'Package Policy 2', + package: { + name: 'fleet_server', + title: 'Fleet Server', + version: '1.0.0', + }, + policy_id: 'fs-policy-2', + }, + { + id: 'package-policy-3', + name: 'Package Policy 3', + package: { + name: 'system', + title: 'System', + version: '1.0.0', + }, + policy_id: 'agent-policy-2', + }, + ]; + const mockFleetServerPolicies = [ + { + id: 'fs-policy-1', + name: 'FS Policy 1', + is_managed: true, + is_default_fleet_server: true, + has_fleet_server: true, + download_source_id: undefined, + fleet_server_host_id: undefined, + }, + { + id: 'fs-policy-2', + name: 'FS Policy 2', + is_managed: true, + is_default_fleet_server: false, + has_fleet_server: false, + download_source_id: undefined, + fleet_server_host_id: undefined, + }, + ]; + + it('should return no policies if there are no fleet server package policies', async () => { + (mockedPackagePolicyService.list as jest.Mock).mockResolvedValueOnce({ + items: [], + }); + const result = await getFleetServerPolicies(soClient); + expect(result).toEqual([]); + }); + + it('should return agent policies with fleet server package policies', async () => { + (mockedPackagePolicyService.list as jest.Mock).mockResolvedValueOnce({ + items: mockPackagePolicies, + }); + (mockedAgentPolicyService.getByIDs as jest.Mock).mockResolvedValueOnce(mockFleetServerPolicies); + const result = await getFleetServerPolicies(soClient); + expect(result).toEqual(mockFleetServerPolicies); + }); +}); + +describe('hasActiveFleetServersForPolicies', () => { + const mockSoClient = savedObjectsClientMock.create(); + const mockEsClient = elasticsearchServiceMock.createInternalClient(); + + it('returns false when no agent IDs are provided', async () => { + const hasFs = await hasFleetServersForPolicies(mockEsClient, mockSoClient, []); + expect(hasFs).toBe(false); + }); + + describe('activeOnly is true', () => { + it('returns true when at least one agent is online', async () => { + (getAgentStatusForAgentPolicy as jest.Mock).mockResolvedValueOnce({ + other: 0, + events: 0, + total: 1, + all: 1, + active: 0, + updating: 0, + offline: 0, + inactive: 0, + unenrolled: 0, + online: 1, + error: 0, + }); + const hasFs = await hasFleetServersForPolicies( + mockEsClient, + mockSoClient, + ['policy-1'], + true + ); + expect(hasFs).toBe(true); + }); + + it('returns true when at least one agent is updating', async () => { + (getAgentStatusForAgentPolicy as jest.Mock).mockResolvedValueOnce({ + other: 0, + events: 0, + total: 1, + all: 1, + active: 0, + updating: 1, + offline: 0, + inactive: 0, + unenrolled: 0, + online: 0, + error: 0, + }); + const hasFs = await hasFleetServersForPolicies( + mockEsClient, + mockSoClient, + ['policy-1'], + true + ); + expect(hasFs).toBe(true); + }); + + it('returns false when no agents are updating or online', async () => { + (getAgentStatusForAgentPolicy as jest.Mock).mockResolvedValueOnce({ + other: 0, + events: 0, + total: 3, + all: 3, + active: 1, + updating: 0, + offline: 1, + inactive: 1, + unenrolled: 1, + online: 0, + error: 1, + }); + const hasFs = await hasFleetServersForPolicies( + mockEsClient, + mockSoClient, + ['policy-1'], + true + ); + expect(hasFs).toBe(false); + }); + }); + + describe('activeOnly is false', () => { + it('returns true when at least one agent is found regardless of its status', async () => { + (getAgentStatusForAgentPolicy as jest.Mock).mockResolvedValueOnce({ + other: 0, + events: 0, + total: 0, + all: 1, + active: 0, + updating: 0, + offline: 1, + inactive: 0, + unenrolled: 0, + online: 0, + error: 0, + }); + const hasFs = await hasFleetServersForPolicies(mockEsClient, mockSoClient, ['policy-1']); + expect(hasFs).toBe(true); + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/fleet_server/index.ts b/x-pack/plugins/fleet/server/services/fleet_server/index.ts index 192cb1d626f58..cebebe2aa94b8 100644 --- a/x-pack/plugins/fleet/server/services/fleet_server/index.ts +++ b/x-pack/plugins/fleet/server/services/fleet_server/index.ts @@ -9,26 +9,78 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/ import semverGte from 'semver/functions/gte'; import semverCoerce from 'semver/functions/coerce'; -import { FLEET_SERVER_SERVERS_INDEX, SO_SEARCH_LIMIT } from '../../constants'; +import type { AgentPolicy } from '../../../common/types'; +import { PACKAGE_POLICY_SAVED_OBJECT_TYPE, FLEET_SERVER_PACKAGE } from '../../../common/constants'; + +import { SO_SEARCH_LIMIT } from '../../constants'; import { getAgentsByKuery, getAgentStatusById } from '../agents'; import { packagePolicyService } from '../package_policy'; import { agentPolicyService } from '../agent_policy'; +import { getAgentStatusForAgentPolicy } from '../agents'; import { appContextService } from '..'; /** - * Check if at least one fleet server is connected + * Retrieve all agent policies which has a Fleet Server package policy */ -export async function hasFleetServers(esClient: ElasticsearchClient) { - const res = await esClient.search<{}, {}>({ - index: FLEET_SERVER_SERVERS_INDEX, - ignore_unavailable: true, - filter_path: 'hits.total', - track_total_hits: true, - rest_total_hits_as_int: true, +export const getFleetServerPolicies = async ( + soClient: SavedObjectsClientContract +): Promise => { + const fleetServerPackagePolicies = await packagePolicyService.list(soClient, { + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${FLEET_SERVER_PACKAGE}`, }); - return (res.hits.total as number) > 0; + // Extract associated fleet server agent policy IDs + const fleetServerAgentPolicyIds = [ + ...new Set(fleetServerPackagePolicies.items.map((p) => p.policy_id)), + ]; + + // Retrieve associated agent policies + const fleetServerAgentPolicies = fleetServerAgentPolicyIds.length + ? await agentPolicyService.getByIDs(soClient, fleetServerAgentPolicyIds) + : []; + + return fleetServerAgentPolicies; +}; + +/** + * Check if there is at least one agent enrolled into the given agent policies. + * Assumes that `agentPolicyIds` contains list of Fleet Server agent policies. + * `activeOnly` flag can be used to filter only active agents. + */ +export const hasFleetServersForPolicies = async ( + esClient: ElasticsearchClient, + soClient: SavedObjectsClientContract, + agentPolicyIds: string[], + activeOnly: boolean = false +): Promise => { + if (agentPolicyIds.length > 0) { + const agentStatusesRes = await getAgentStatusForAgentPolicy( + esClient, + soClient, + undefined, + agentPolicyIds.map((id) => `policy_id:${id}`).join(' or ') + ); + + return activeOnly + ? agentStatusesRes.online > 0 || agentStatusesRes.updating > 0 + : agentStatusesRes.all > 0; + } + return false; +}; + +/** + * Check if at least one fleet server agent exists, regardless of its online status + */ +export async function hasFleetServers( + esClient: ElasticsearchClient, + soClient: SavedObjectsClientContract +) { + return await hasFleetServersForPolicies( + esClient, + soClient, + (await getFleetServerPolicies(soClient)).map((policy) => policy.id) + ); } /** diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_generator.ts index 806ae7f289f26..62fa05d794725 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_generator.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_agent_generator.ts @@ -84,6 +84,7 @@ export class FleetAgentGenerator extends BaseDataGenerator { const hostname = this.randomHostname(); const now = new Date().toISOString(); const osFamily = this.randomOSFamily(); + const version = overrides?._source?.agent?.version ?? this.randomVersion(); const componentStatus = this.randomChoice( FleetServerAgentComponentStatuses ); @@ -113,19 +114,19 @@ export class FleetAgentGenerator extends BaseDataGenerator { enrolled_at: now, agent: { id: agentId, - version: this.randomVersion(), + version, }, local_metadata: { elastic: { agent: { - 'build.original': `8.0.0-SNAPSHOT (build: ${this.randomString( + 'build.original': `${version} (build: ${this.randomString( 5 )} at 2021-05-07 18:42:49 +0000 UTC)`, id: agentId, log_level: 'info', snapshot: true, upgradeable: true, - version: '8.0.0', + version, }, }, host: { diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts index 1a91b283d241c..dcb4c27031098 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts @@ -6,15 +6,20 @@ */ import type { Client } from '@elastic/elasticsearch'; -import type { DeleteByQueryResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { + DeleteByQueryResponse, + IndexRequest, +} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { KbnClient } from '@kbn/test'; import type { FleetServerAgent } from '@kbn/fleet-plugin/common'; import { AGENTS_INDEX } from '@kbn/fleet-plugin/common'; import type { BulkRequest } from '@elastic/elasticsearch/lib/api/types'; +import type { DeepPartial } from 'utility-types'; +import type { ToolingLog } from '@kbn/tooling-log'; import { usageTracker } from './usage_tracker'; import type { HostMetadata } from '../types'; import { FleetAgentGenerator } from '../data_generators/fleet_agent_generator'; -import { wrapErrorAndRejectPromise } from './utils'; +import { createToolingLogger, wrapErrorAndRejectPromise } from './utils'; const defaultFleetAgentGenerator = new FleetAgentGenerator(); @@ -189,3 +194,31 @@ export const deleteIndexedFleetAgents = async ( return response; }; + +export const indexFleetServerAgent = async ( + esClient: Client, + log: ToolingLog = createToolingLogger(), + overrides: DeepPartial = {} +): Promise => { + const doc = defaultFleetAgentGenerator.generateEsHit({ + _source: overrides, + }); + + const indexRequest: IndexRequest = { + index: doc._index, + id: doc._id, + body: doc._source, + op_type: 'create', + refresh: 'wait_for', + }; + + log.verbose(`Indexing new fleet agent with:\n${JSON.stringify(indexRequest, null, 2)}`); + + await esClient.index(indexRequest).catch(wrapErrorAndRejectPromise); + + return { + fleetAgentsIndex: doc._index, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + agents: [doc._source!], + }; +}; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_server.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_server.ts index 63d6819c0db60..a245b9ab1ddb8 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_server.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_server.ts @@ -6,53 +6,155 @@ */ import type { Client } from '@elastic/elasticsearch'; -import { FLEET_SERVER_SERVERS_INDEX } from '@kbn/fleet-plugin/common'; +import { kibanaPackageJson } from '@kbn/repo-info'; +import type { KbnClient } from '@kbn/test'; +import type { + GetPackagePoliciesResponse, + AgentPolicy, + GetOneAgentPolicyResponse, + CreateAgentPolicyResponse, +} from '@kbn/fleet-plugin/common'; +import { + AGENT_POLICY_API_ROUTES, + agentPolicyRouteService, + AGENTS_INDEX, + FLEET_SERVER_PACKAGE, + PACKAGE_POLICY_SAVED_OBJECT_TYPE, + packagePolicyRouteService, +} from '@kbn/fleet-plugin/common'; +import type { ToolingLog } from '@kbn/tooling-log'; +import { indexFleetServerAgent } from './index_fleet_agent'; +import { catchAxiosErrorFormatAndThrow } from '../format_axios_error'; import { usageTracker } from './usage_tracker'; -import { wrapErrorAndRejectPromise } from './utils'; +import { createToolingLogger, wrapErrorAndRejectPromise } from './utils'; /** - * Will ensure that at least one fleet server is present in the `.fleet-servers` index. This will - * enable the `Agent` section of kibana Fleet to be displayed + * Will ensure that at least one fleet server is present in the `.fleet-agents` index. This will + * enable the `Agent` section of kibana Fleet to be displayed. We skip on serverless because + * Fleet Server agents are not checked against there. * * @param esClient + * @param kbnClient + * @param log * @param version */ export const enableFleetServerIfNecessary = usageTracker.track( 'enableFleetServerIfNecessary', - async (esClient: Client, version: string = '8.0.0') => { - const res = await esClient.search({ - index: FLEET_SERVER_SERVERS_INDEX, - ignore_unavailable: true, - rest_total_hits_as_int: true, - }); - - if (res.hits.total) { - return; + async ( + esClient: Client, + isServerless: boolean = false, + kbnClient: KbnClient, + log: ToolingLog = createToolingLogger(), + version: string = kibanaPackageJson.version + ) => { + const agentPolicy = await getOrCreateFleetServerAgentPolicy(kbnClient, log); + + if (!isServerless && !(await hasFleetServerAgent(esClient, agentPolicy.id))) { + log.debug(`Indexing a new fleet server agent`); + const lastCheckin = new Date(); + lastCheckin.setFullYear(lastCheckin.getFullYear() + 1); + + const indexedAgent = await indexFleetServerAgent(esClient, log, { + policy_id: agentPolicy.id, + agent: { version }, + last_checkin_status: 'online', + last_checkin: lastCheckin.toISOString(), + }); + + log.verbose(`New fleet server agent indexed:\n${JSON.stringify(indexedAgent)}`); + } else { + log.debug(`Nothing to do. A Fleet Server agent is already registered with Fleet`); } + } +); - // Create a Fake fleet-server in this kibana instance - await esClient - .index({ - index: FLEET_SERVER_SERVERS_INDEX, - refresh: 'wait_for', - body: { - agent: { - id: '12988155-475c-430d-ac89-84dc84b67cd1', - version, - }, - host: { - architecture: 'linux', - id: 'c3e5f4f690b4a3ff23e54900701a9513', - ip: ['127.0.0.1', '::1', '10.201.0.213', 'fe80::4001:aff:fec9:d5'], - name: 'endpoint-data-generator', - }, - server: { - id: '12988155-475c-430d-ac89-84dc84b67cd1', - version, - }, - '@timestamp': '2021-05-12T18:42:52.009482058Z', - }, +const getOrCreateFleetServerAgentPolicy = async ( + kbnClient: KbnClient, + log: ToolingLog = createToolingLogger() +): Promise => { + const packagePolicies = await kbnClient + .request({ + method: 'GET', + headers: { 'elastic-api-version': '2023-10-31' }, + path: packagePolicyRouteService.getListPath(), + query: { + perPage: 1, + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: "${FLEET_SERVER_PACKAGE}"`, + }, + }) + .catch(catchAxiosErrorFormatAndThrow); + + if (packagePolicies.data.items[0]) { + log.debug(`Found an existing package policy - fetching associated agent policy`); + log.verbose(JSON.stringify(packagePolicies.data.items[0])); + + return kbnClient + .request({ + headers: { 'elastic-api-version': '2023-10-31' }, + method: 'GET', + path: agentPolicyRouteService.getInfoPath(packagePolicies.data.items[0].policy_id), }) - .catch(wrapErrorAndRejectPromise); + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => { + log.verbose( + `Existing agent policy for Fleet Server:\n${JSON.stringify(response.data.item)}` + ); + + return response.data.item; + }); } -); + + log.debug(`Creating a new fleet server agent policy`); + + // create new Fleet Server agent policy + return kbnClient + .request({ + method: 'POST', + path: AGENT_POLICY_API_ROUTES.CREATE_PATTERN, + headers: { 'elastic-api-version': '2023-10-31' }, + body: { + name: `Fleet Server policy (${Math.random().toString(32).substring(2)})`, + description: `Created by CLI Tool via: ${__filename}`, + namespace: 'default', + monitoring_enabled: [], + // This will ensure the Fleet Server integration policy + // is also created and added to the agent policy + has_fleet_server: true, + }, + }) + .then((response) => { + log.verbose( + `No fleet server agent policy found. Created a new one:\n${JSON.stringify( + response.data.item + )}` + ); + + return response.data.item; + }) + .catch(catchAxiosErrorFormatAndThrow); +}; + +const hasFleetServerAgent = async ( + esClient: Client, + fleetServerAgentPolicyId: string +): Promise => { + const searchResponse = await esClient + .search( + { + index: AGENTS_INDEX, + ignore_unavailable: true, + rest_total_hits_as_int: true, + size: 1, + _source: false, + query: { + match: { + policy_id: fleetServerAgentPolicyId, + }, + }, + }, + { ignore: [404] } + ) + .catch(wrapErrorAndRejectPromise); + + return Boolean(searchResponse?.hits.total); +}; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/utils.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/utils.ts index 01974b85d6f65..f695bfc3afa67 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/utils.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/utils.ts @@ -10,13 +10,14 @@ import type { ToolingLogTextWriterConfig } from '@kbn/tooling-log'; import { ToolingLog } from '@kbn/tooling-log'; import type { Flags } from '@kbn/dev-cli-runner'; import moment from 'moment/moment'; +import { EndpointError } from '../errors'; export const RETRYABLE_TRANSIENT_ERRORS: Readonly> = [ 'no_shard_available_action_exception', 'illegal_index_shard_state_exception', ]; -export class EndpointDataLoadingError extends Error { +export class EndpointDataLoadingError extends EndpointError { constructor(message: string, public meta?: unknown) { super(message); } @@ -88,7 +89,8 @@ export const retryOnError = async ( return result; } catch (err) { - log.warning(msg(`attempt ${thisAttempt} failed with: ${err.message}`), err); + log.warning(msg(`attempt ${thisAttempt} failed with: ${err.message.split('\n').at(0)}`)); + log.verbose(err); // If not an error that is retryable, then end loop here and return that error; if (!isRetryableError(err)) { diff --git a/x-pack/plugins/security_solution/common/endpoint/index_data.ts b/x-pack/plugins/security_solution/common/endpoint/index_data.ts index 5caf47b1ade33..1e0009a8a5cf9 100644 --- a/x-pack/plugins/security_solution/common/endpoint/index_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/index_data.ts @@ -74,6 +74,7 @@ export const indexHostsAndAlerts = usageTracker.track( withResponseActions = true, numResponseActions?: number, alertIds?: string[], + isServerless: boolean = false, logger_?: ToolingLog ): Promise => { const random = seedrandom(seed); @@ -103,7 +104,7 @@ export const indexHostsAndAlerts = usageTracker.track( // If `fleet` integration is true, then ensure a (fake) fleet-server is connected if (fleet) { - await enableFleetServerIfNecessary(client); + await enableFleetServerIfNecessary(client, isServerless, kbnClient, logger); } // Keep a map of host applied policy ids (fake) to real ingest package configs (policy record) diff --git a/x-pack/plugins/security_solution/public/management/cypress/support/common.ts b/x-pack/plugins/security_solution/public/management/cypress/support/common.ts index 2364f08b39681..92d5eeba9aa28 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/support/common.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/support/common.ts @@ -17,6 +17,9 @@ export const setupStackServicesUsingCypressConfig = async (config: Cypress.Plugi return RUNTIME_SERVICES_CACHE.get(config)!; } + const isServerless = config.env.IS_SERVERLESS; + const isCloudServerless = config.env.CLOUD_SERVERLESS; + const stackServices = await createRuntimeServices({ kibanaUrl: config.env.KIBANA_URL, elasticsearchUrl: config.env.ELASTICSEARCH_URL, @@ -25,7 +28,8 @@ export const setupStackServicesUsingCypressConfig = async (config: Cypress.Plugi password: config.env.KIBANA_PASSWORD, esUsername: config.env.ELASTICSEARCH_USERNAME, esPassword: config.env.ELASTICSEARCH_PASSWORD, - asSuperuser: !config.env.CLOUD_SERVERLESS, + asSuperuser: !isCloudServerless, + useCertForSsl: !isCloudServerless && isServerless, }).then(({ log, ...others }) => { return { ...others, diff --git a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts index acf0a3af4531a..e96b3a057a21b 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts @@ -217,6 +217,7 @@ export const dataLoaders = ( withResponseActions, numResponseActions, alertIds, + isServerless, }); }, diff --git a/x-pack/plugins/security_solution/public/management/cypress/support/plugin_handlers/endpoint_data_loader.ts b/x-pack/plugins/security_solution/public/management/cypress/support/plugin_handlers/endpoint_data_loader.ts index f89dedad7bff9..841a857846a2a 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/support/plugin_handlers/endpoint_data_loader.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/support/plugin_handlers/endpoint_data_loader.ts @@ -45,6 +45,7 @@ export interface CyLoadEndpointDataOptions isolation: boolean; bothIsolatedAndNormalEndpoints?: boolean; alertIds?: string[]; + isServerless?: boolean; } /** @@ -73,6 +74,7 @@ export const cyLoadEndpointDataHandler = async ( isolation, numResponseActions, alertIds, + isServerless = false, } = options; const DocGenerator = EndpointDocGenerator.custom({ @@ -80,6 +82,8 @@ export const cyLoadEndpointDataHandler = async ( }); if (waitUntilTransformed) { + log.info(`Stopping transforms...`); + // need this before indexing docs so that the united transform doesn't // create a checkpoint with a timestamp after the doc timestamps await stopTransform(esClient, log, metadataTransformPrefix); @@ -88,6 +92,8 @@ export const cyLoadEndpointDataHandler = async ( await stopTransform(esClient, log, METADATA_UNITED_TRANSFORM_V2); } + log.info(`Calling indexHostAndAlerts() to index [${numHosts}] endpoint hosts...`); + // load data into the system const indexedData = await indexHostsAndAlerts( esClient as Client, @@ -106,25 +112,31 @@ export const cyLoadEndpointDataHandler = async ( withResponseActions, numResponseActions, alertIds, + isServerless, log ); + log.info(`Hosts have been indexed`); + if (waitUntilTransformed) { + log.info(`starting transforms...`); + // missing transforms are ignored, start either name - await startTransform(esClient, metadataTransformPrefix); - await startTransform(esClient, METADATA_CURRENT_TRANSFORM_V2); + await startTransform(esClient, log, metadataTransformPrefix); + await startTransform(esClient, log, METADATA_CURRENT_TRANSFORM_V2); const metadataIds = Array.from(new Set(indexedData.hosts.map((host) => host.agent.id))); - await waitForEndpoints(esClient, 'endpoint_index', metadataIds); + await waitForEndpoints(esClient, log, 'endpoint_index', metadataIds); - await startTransform(esClient, METADATA_UNITED_TRANSFORM); - await startTransform(esClient, METADATA_UNITED_TRANSFORM_V2); + await startTransform(esClient, log, METADATA_UNITED_TRANSFORM); + await startTransform(esClient, log, METADATA_UNITED_TRANSFORM_V2); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const agentIds = Array.from(new Set(indexedData.agents.map((agent) => agent.agent!.id))); - await waitForEndpoints(esClient, 'united_index', agentIds); + await waitForEndpoints(esClient, log, 'united_index', agentIds); } + log.info(`Done - [${numHosts}] endpoint hosts have been indexed and are now available in kibana`); return indexedData; }; @@ -133,6 +145,8 @@ const stopTransform = async ( log: ToolingLog, transformId: string ): Promise => { + log.debug(`Stopping transform id: ${transformId}`); + await esClient.transform .stopTransform({ transform_id: `${transformId}*`, @@ -147,17 +161,27 @@ const stopTransform = async ( }); }; -const startTransform = async (esClient: Client, transformId: string): Promise => { +const startTransform = async ( + esClient: Client, + log: ToolingLog, + transformId: string +): Promise => { const transformsResponse = await esClient.transform.getTransformStats({ transform_id: `${transformId}*`, }); + log.verbose( + `Transform status found for [${transformId}*] returned:\n${dump(transformsResponse)}` + ); + await Promise.all( transformsResponse.transforms.map((transform) => { if (STARTED_TRANSFORM_STATES.has(transform.state)) { return Promise.resolve(); } + log.debug(`Staring transform id: [${transform.id}]`); + return esClient.transform.startTransform({ transform_id: transform.id }); }) ); @@ -173,6 +197,7 @@ const startTransform = async (esClient: Client, transformId: string): Promise => { @@ -218,8 +243,13 @@ const waitForEndpoints = async ( const expectedSize = ids.length || 1; + log.info(`Waiting for [${expectedSize}] endpoint hosts to be available`); + log.verbose(`Query for searching index [${index}]:\n${dump(body, 10)}`); + await pRetry( - async () => { + async (attemptCount) => { + log.debug(`Attempt [${attemptCount}]: Searching [${index}] to check if hosts are availble`); + const response = await esClient.search({ index, size: expectedSize, @@ -227,12 +257,16 @@ const waitForEndpoints = async ( rest_total_hits_as_int: true, }); + log.verbose(`Attempt [${attemptCount}]: Search response:\n${dump(response, 10)}`); + // If not the expected number of Endpoints, then throw an error so we keep trying if (response.hits.total !== expectedSize) { throw new Error( `Expected number of endpoints not found. Looking for ${expectedSize} but received ${response.hits.total}` ); } + + log.info(`Attempt [${attemptCount}]: Done - [${expectedSize}] host are now available`); }, { forever: false } ); diff --git a/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_loader.ts b/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_loader.ts index 9658ea46a09d8..b2e0f8a5c0cdf 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_loader.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_loader.ts @@ -21,6 +21,7 @@ import { METADATA_DATASTREAM } from '../../../../common/endpoint/constants'; import { EndpointMetadataGenerator } from '../../../../common/endpoint/data_generators/endpoint_metadata_generator'; import { getEndpointPackageInfo } from '../../../../common/endpoint/utils/package'; import { ENDPOINT_ALERTS_INDEX, ENDPOINT_EVENTS_INDEX } from '../../common/constants'; +import { isServerlessKibanaFlavor } from '../../common/stack_services'; let WAS_FLEET_SETUP_DONE = false; @@ -90,8 +91,9 @@ export const loadEndpoints = async ({ } if (!WAS_FLEET_SETUP_DONE) { + const isServerless = await isServerlessKibanaFlavor(kbnClient); await setupFleetForEndpoint(kbnClient); - await enableFleetServerIfNecessary(esClient); + await enableFleetServerIfNecessary(esClient, isServerless, kbnClient, log); // eslint-disable-next-line require-atomic-updates WAS_FLEET_SETUP_DONE = true; } diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts index 1eefe220c0d39..3707436c042f2 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts @@ -16,7 +16,6 @@ import { AGENT_POLICY_API_ROUTES, API_VERSIONS, FLEET_SERVER_PACKAGE, - FLEET_SERVER_SERVERS_INDEX, PACKAGE_POLICY_SAVED_OBJECT_TYPE, } from '@kbn/fleet-plugin/common'; import type { @@ -42,13 +41,8 @@ import { } from '@kbn/dev-utils'; import { maybeCreateDockerNetwork, SERVERLESS_NODES, verifyDockerInstalled } from '@kbn/es'; import { resolve } from 'path'; -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { captureCallingStack, dump, prefixedOutputLogger } from '../utils'; -import { - createToolingLogger, - RETRYABLE_TRANSIENT_ERRORS, - retryOnError, -} from '../../../../common/endpoint/data_loaders/utils'; +import { createToolingLogger } from '../../../../common/endpoint/data_loaders/utils'; import { isServerlessKibanaFlavor } from '../stack_services'; import type { FormattedAxiosError } from '../../../../common/endpoint/format_axios_error'; import { catchAxiosErrorFormatAndThrow } from '../../../../common/endpoint/format_axios_error'; @@ -329,9 +323,12 @@ const startFleetServerWithDocker = async ({ await updateFleetElasticsearchOutputHostNames(kbnClient, log); if (isServerless) { - log.info(`Waiting for server [${hostname}] to register with Elasticsearch`); - await waitForFleetServerToRegisterWithElasticsearch(kbnClient, hostname, 180000); + log.info(`Waiting for Fleet Server [${hostname}] to start running`); + if (!(await isFleetServerRunning(kbnClient, log))) { + throw Error(`Unable to start Fleet Server [${hostname}]`); + } } else { + log.info(`Waiting for Fleet Server [${hostname}] to enroll with Fleet`); await waitForHostToEnroll(kbnClient, log, hostname, 120000); } @@ -683,7 +680,7 @@ export const isFleetServerRunning = async ( const url = new URL(fleetServerUrl); url.pathname = '/api/status'; - return pRetry( + return pRetry( async () => { return axios .request({ @@ -698,75 +695,20 @@ export const isFleetServerRunning = async ( `Fleet server is up and running at [${fleetServerUrl}]. Status: `, response.data ); - return true; }) - .catch(catchAxiosErrorFormatAndThrow) - .catch((e) => { - log.debug(`Fleet server not up at [${fleetServerUrl}]`); - log.verbose(`Call to [${url.toString()}] failed with:`, e); - return false; - }); - }, - { maxTimeout: 10000 } - ); -}; - -/** - * Checks and waits until the given fleet server hostname has been registered into elasticsearch. - * This check can be used when enrolling a standalone fleet-server, since those would not show up - * in Kibana's Fleet UI. - */ -const waitForFleetServerToRegisterWithElasticsearch = async ( - kbnClient: KbnClient, - fleetServerHostname: string, - timeoutMs: number = 30000 -): Promise => { - const started = new Date(); - const hasTimedOut = (): boolean => { - const elapsedTime = Date.now() - started.getTime(); - return elapsedTime > timeoutMs; - }; - let found = false; - - while (!found && !hasTimedOut()) { - found = await retryOnError(async () => { - const fleetServerRecord = await kbnClient - .request({ - method: 'POST', - path: '/api/console/proxy', - query: { - path: `${FLEET_SERVER_SERVERS_INDEX}/_search`, - method: 'GET', - }, - body: { - query: { - bool: { - filter: [ - { - term: { - 'host.name': fleetServerHostname, - }, - }, - ], - }, - }, - }, - }) - .then((response) => response.data) .catch(catchAxiosErrorFormatAndThrow); - - return ((fleetServerRecord?.hits?.total as estypes.SearchTotalHits)?.value ?? 0) === 1; - }, RETRYABLE_TRANSIENT_ERRORS); - - if (!found) { - // sleep and check again - await new Promise((r) => setTimeout(r, 2000)); + }, + { + maxTimeout: 10000, + retries: 5, + onFailedAttempt: (e) => { + log.warning( + `Fleet server not (yet) up at [${fleetServerUrl}]. Retrying... (attempt #${e.attemptNumber}, ${e.retriesLeft} retries left)` + ); + log.verbose(`Call to [${url.toString()}] failed with:`, e); + }, } - } - - if (!found) { - throw new Error( - `Timed out waiting for fleet server [${fleetServerHostname}] to register with Elasticsearch` - ); - } + ) + .then(() => true) + .catch(() => false); }; diff --git a/x-pack/test/defend_workflows_cypress/serverless_config.ts b/x-pack/test/defend_workflows_cypress/serverless_config.ts index b3b01d69c4331..2efc55ea48081 100644 --- a/x-pack/test/defend_workflows_cypress/serverless_config.ts +++ b/x-pack/test/defend_workflows_cypress/serverless_config.ts @@ -51,6 +51,11 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { `--xpack.fleet.agents.elasticsearch.host=http://${hostIp}:${defendWorkflowsCypressConfig.get( 'servers.elasticsearch.port' )}`, + + // Enable Fleet server standalone so that no checks are done to see if fleet-server has + // registered with Kibana and we are able to access the Agents page of Fleet + '--xpack.fleet.internal.fleetServerStandalone=true', + // set the packagerTaskInterval to 5s in order to speed up test executions when checking fleet artifacts '--xpack.securitySolution.packagerTaskInterval=5s', `--xpack.securitySolution.enableExperimental=${JSON.stringify(enabledFeatureFlags)}`, diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json index a345f97f54166..bbed5094bc3ef 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json @@ -375,67 +375,3 @@ } } } - -{ - "type": "index", - "value": { - "aliases": { - ".fleet-servers": { - } - }, - "index": ".fleet-servers-7", - "mappings": { - "_meta": { - "migrationHash": "e2782448c7235ec9af66ca7997e867d715ac379c" - }, - "dynamic": "false", - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "properties": { - "id": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "host": { - "properties": { - "architecture": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "ip": { - "type": "keyword" - }, - "name": { - "type": "keyword" - } - } - }, - "server": { - "properties": { - "id": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "number_of_replicas": "1", - "number_of_shards": "1" - } - } - } -} diff --git a/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json b/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json index a04b7a7dc21c7..b10f0934d981d 100644 --- a/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json +++ b/x-pack/test/functional/es_archives/fleet/empty_fleet_server/mappings.json @@ -375,66 +375,3 @@ } } -{ - "type": "index", - "value": { - "aliases": { - ".fleet-servers": { - } - }, - "index": ".fleet-servers-7", - "mappings": { - "_meta": { - "migrationHash": "e2782448c7235ec9af66ca7997e867d715ac379c" - }, - "dynamic": "false", - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "properties": { - "id": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "host": { - "properties": { - "architecture": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "ip": { - "type": "keyword" - }, - "name": { - "type": "keyword" - } - } - }, - "server": { - "properties": { - "id": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "number_of_replicas": "1", - "number_of_shards": "1" - } - } - } -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/security_solution_endpoint/services/endpoint.ts b/x-pack/test/security_solution_api_integration/test_suites/security_solution_endpoint/services/endpoint.ts index 00a395fdc4b59..df8dee3493ec0 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/security_solution_endpoint/services/endpoint.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/security_solution_endpoint/services/endpoint.ts @@ -160,6 +160,7 @@ export class EndpointTestResources extends FtrService { undefined, undefined, undefined, + undefined, this.log ); From 3b88219aed21f7a0a77e9edc5a2ffcc5e322345b Mon Sep 17 00:00:00 2001 From: Rickyanto Ang Date: Wed, 5 Jun 2024 14:12:30 -0700 Subject: [PATCH 018/122] [Cloud Security] Update CSP Version to 1.8.1 for Test (#184492) ## Summary With 8.13 released, we want to make sure our CSP is using the latest CSP version for our test environment --- x-pack/plugins/cloud_security_posture/common/constants.ts | 2 ++ .../test/api_integration/apis/cloud_security_posture/helper.ts | 3 ++- x-pack/test/cloud_security_posture_api/config.ts | 3 ++- x-pack/test/cloud_security_posture_functional/config.ts | 3 ++- .../test_suites/security/config.cloud_security_posture.ts | 3 ++- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index ef7191c9efe11..31f36b8d57a7c 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -192,3 +192,5 @@ export const AZURE_CREDENTIALS_TYPE_TO_FIELDS_MAP = { managed_identity: [], manual: [], }; + +export const CLOUD_SECURITY_PLUGIN_VERSION = '1.8.1'; 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 5565e7a6e096b..37bdd4975b2a6 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 @@ -10,6 +10,7 @@ import { Client } from '@elastic/elasticsearch'; import expect from '@kbn/expect'; import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { IndexDetails } from '@kbn/cloud-security-posture-plugin/common/types_old'; +import { CLOUD_SECURITY_PLUGIN_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; import { SecurityService } from '../../../../../test/common/services/security/security'; export const deleteIndex = (es: Client, indexToBeDeleted: string[]) => { @@ -51,7 +52,7 @@ export async function createPackagePolicy( posture: string, packageName: string = 'cloud_security_posture-1' ) { - const version = '1.7.1'; + const version = CLOUD_SECURITY_PLUGIN_VERSION; const title = 'Security Posture Management'; const streams = [ { diff --git a/x-pack/test/cloud_security_posture_api/config.ts b/x-pack/test/cloud_security_posture_api/config.ts index bbee66741210e..62a976da70669 100644 --- a/x-pack/test/cloud_security_posture_api/config.ts +++ b/x-pack/test/cloud_security_posture_api/config.ts @@ -6,6 +6,7 @@ */ import type { FtrConfigProviderContext } from '@kbn/test'; +import { CLOUD_SECURITY_PLUGIN_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const xpackFunctionalConfig = await readConfigFile( @@ -43,7 +44,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { * 2. merge the updated version number change to kibana */ `--xpack.fleet.packages.0.name=cloud_security_posture`, - `--xpack.fleet.packages.0.version=1.5.0`, + `--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`, // `--xpack.fleet.registryUrl=https://localhost:8080`, ], }, diff --git a/x-pack/test/cloud_security_posture_functional/config.ts b/x-pack/test/cloud_security_posture_functional/config.ts index bd2f1eb9d594d..28283fe427949 100644 --- a/x-pack/test/cloud_security_posture_functional/config.ts +++ b/x-pack/test/cloud_security_posture_functional/config.ts @@ -7,6 +7,7 @@ import { resolve } from 'path'; import type { FtrConfigProviderContext } from '@kbn/test'; +import { CLOUD_SECURITY_PLUGIN_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; import { pageObjects } from './page_objects'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { @@ -38,7 +39,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { * 2. merge the updated version number change to kibana */ `--xpack.fleet.packages.0.name=cloud_security_posture`, - `--xpack.fleet.packages.0.version=1.7.4`, + `--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`, // `--xpack.fleet.registryUrl=https://localhost:8080`, `--xpack.fleet.agents.fleet_server.hosts=["https://ftr.kibana:8220"]`, `--xpack.fleet.internal.fleetServerStandalone=true`, diff --git a/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.ts b/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.ts index 65903c2343df6..6a755c26e91d4 100644 --- a/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.ts +++ b/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { CLOUD_SECURITY_PLUGIN_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; import { createTestConfig } from '../../config.base'; export default createTestConfig({ @@ -14,7 +15,7 @@ export default createTestConfig({ }, kbnServerArgs: [ `--xpack.fleet.packages.0.name=cloud_security_posture`, - `--xpack.fleet.packages.0.version=1.5.2`, + `--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`, ], // load tests in the index file testFiles: [require.resolve('./ftr/cloud_security_posture')], From 6cb59ad9a358229fce3db13d6432b8b8b1f7d46d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:46:45 -0700 Subject: [PATCH 019/122] Update dependency elastic-apm-node to ^4.6.0 (main) (#184868) --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index dab6cc9b57d74..c97e0fb4cb77b 100644 --- a/package.json +++ b/package.json @@ -1010,7 +1010,7 @@ "deepmerge": "^4.2.2", "del": "^6.1.0", "diff": "^5.1.0", - "elastic-apm-node": "^4.5.4", + "elastic-apm-node": "^4.6.0", "email-addresses": "^5.0.0", "eventsource-parser": "^1.1.1", "execa": "^5.1.1", diff --git a/yarn.lock b/yarn.lock index c2a5e924f770f..5187eec56835b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16179,10 +16179,10 @@ elastic-apm-node@3.46.0: traverse "^0.6.6" unicode-byte-truncate "^1.0.0" -elastic-apm-node@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-4.5.4.tgz#add7c5a53f8a4ec29989e3365c9f2053ec64a20d" - integrity sha512-PqX8a5PdWo+mtH1Vn+xjmhJpa2RE9zbKDKFkKoENKG118KVgukxhFlVIpb3qrht9aeRkPxHqQsPNtNV3ljPjew== +elastic-apm-node@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-4.6.0.tgz#9de3b758158c85dee5932857eb93e21cf204c45a" + integrity sha512-mieujz8IA30wkavF8JG/mSBep2DG2zGMblQAh1uEkeXIjb8njrW3Ef+cqKPEdaFPN/Iqm2LZzZuy+Fu20MsfkA== dependencies: "@elastic/ecs-pino-format" "^1.5.0" "@opentelemetry/api" "^1.4.1" @@ -16202,7 +16202,7 @@ elastic-apm-node@^4.5.4: fast-safe-stringify "^2.0.7" fast-stream-to-buffer "^1.0.0" http-headers "^3.0.2" - import-in-the-middle "1.7.4" + import-in-the-middle "1.8.0" json-bigint "^1.0.0" lru-cache "^10.0.1" measured-reporting "^1.51.1" @@ -19531,10 +19531,10 @@ import-in-the-middle@1.7.1: cjs-module-lexer "^1.2.2" module-details-from-path "^1.0.3" -import-in-the-middle@1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz#508da6e91cfa84f210dcdb6c0a91ab0c9e8b3ebc" - integrity sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg== +import-in-the-middle@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.8.0.tgz#c94d88d53701de9a248f9710b41f533e67f598a4" + integrity sha512-/xQjze8szLNnJ5rvHSzn+dcVXqCAU6Plbk4P24U/jwPmg1wy7IIp9OjKIO5tYue8GSPhDpPDiApQjvBUmWwhsQ== dependencies: acorn "^8.8.2" acorn-import-attributes "^1.9.5" From 90d1bc6388130f35938f394396fbad3e22669cc2 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Wed, 5 Jun 2024 16:12:54 -0700 Subject: [PATCH 020/122] [DOCS] Stack Management Alerts app (#184384) --- docs/user/alerting/alerting-setup.asciidoc | 58 ++++++++++-- .../alerting/create-and-manage-rules.asciidoc | 17 +--- .../images/stack-management-alerts-page.png | Bin 0 -> 238977 bytes .../stack-management-alerts-query-menu.png | Bin 0 -> 294124 bytes docs/user/alerting/index.asciidoc | 1 + docs/user/alerting/view-alerts.asciidoc | 83 ++++++++++++++++++ .../stack_alerting/list_view.ts | 25 ++++++ 7 files changed, 160 insertions(+), 24 deletions(-) create mode 100644 docs/user/alerting/images/stack-management-alerts-page.png create mode 100644 docs/user/alerting/images/stack-management-alerts-query-menu.png create mode 100644 docs/user/alerting/view-alerts.asciidoc diff --git a/docs/user/alerting/alerting-setup.asciidoc b/docs/user/alerting/alerting-setup.asciidoc index 82e64557b55dd..cf1f84c9cc032 100644 --- a/docs/user/alerting/alerting-setup.asciidoc +++ b/docs/user/alerting/alerting-setup.asciidoc @@ -48,18 +48,60 @@ For more information on the scalability of {alert-features}, go to [[alerting-security]] === Security -If you want to use the {alert-features} in a {kib} app, you must have the appropriate feature privileges. -For example, to create rules in *Discover* or *{stack-manage-app} > {rules-ui}*, you must have `all` privileges for the *Management > {stack-rules-feature}* feature. -To add rule actions and test connectors, you must also have `read` privileges for the *{connectors-feature}* feature. -To change rule settings, you must have `all` privileges for the *Rules Settings* privilege or `all` privileges for the appropriate sub-feature such as flapping detection. -For more information on configuring roles that provide access to features, go to <>. +To use {alert-features} in a {kib} app, you must have the appropriate feature privileges: + +[options="header"] +|=== + +| Action | {kib} privileges +| Give full access to manage alerts, connectors, and rules in *{stack-manage-app}* or *Discover* +a| +* `All` for the *Management > {stack-rules-feature}* feature. +* `All` for the *Management > Rules Settings* feature. +* `All` for the *Management > {connectors-feature}* feature. +* `Read` index privileges for the `.alerts-*` system indices + +[NOTE] +==== +The *{connectors-feature}* feature privilege is required to manage connectors. +To add rule actions and test connectors, you require only `Read` privileges. + +By default, `All` privileges for the *Rules Settings* feature include authority to edit flapping detection settings unless you customize the sub-feature privileges. preview:[] To create a rule that uses the <>, you must also have `all` privileges for the *Cases* feature. -Each rule also has a rule visibility value (or `consumer` in the APIs), which affects the {kib} feature privileges that are required to access it. -To view or edit a rule that has a `Stack Rules` rule visibility, for example, you must have the appropriate *Management > {stack-rules-feature}* feature privileges. +The rule type also affects the privileges that are required. +For example, to create or edit {ml} rules, you must have `all` privileges for the *Analytics > {ml-app}* feature. +For {stack-monitor-app} rules, you must have the `monitoring_user` role. +For {observability} rules, you must have `all` privileges for the appropriate {observability} features. +For Security rules, refer to {security-guide}/detections-permissions-section.html[Detections prerequisites and requirements]. +==== + +| Give view-only access to alerts, connectors, and rules in *{stack-manage-app}* or *Discover* +a| +* `Read` for the *Management > {stack-rules-feature}* feature. +* `Read` for the *Management > Rules Settings* feature. +* `Read` for the *Management > {connectors-feature}* feature. +* `Read` index privileges for the `.alerts-*` system indices + +[NOTE] +==== +The rule type also affects the privileges that are required. +For example, to view {ml} rules, you must have `read` privileges for the *Analytics > {ml-app}* feature. +For {stack-monitor-app} rules, you must have the `monitoring_user` role. +For {observability} rules, you must have `read` privileges for the appropriate {observability} features. +For Security rules, refer to {security-guide}/detections-permissions-section.html[Detections prerequisites and requirements]. +==== + +| Revoke all access to alerts, connectors, and rules in *{stack-manage-app}* or *Discover* +a| +* `None` for the *Management > {stack-rules-feature}* feature. +* `None` for the *Management > Rules Settings* feature. +* `None` for the *Management > {connectors-feature}* feature. + +|=== -For details about the prerequisites required to run each API, refer to <>. +For more information on configuring roles that provide access to features, go to <>. [float] [[alerting-authorization]] diff --git a/docs/user/alerting/create-and-manage-rules.asciidoc b/docs/user/alerting/create-and-manage-rules.asciidoc index 5e108b963b18a..5a17a583fb387 100644 --- a/docs/user/alerting/create-and-manage-rules.asciidoc +++ b/docs/user/alerting/create-and-manage-rules.asciidoc @@ -170,19 +170,7 @@ image::images/rule-details-alerts-active.png[Rule details page with multiple ale // NOTE: This is an autogenerated screenshot. Do not edit it directly. In this example, the rule detects when a site serves more than a threshold number of bytes in a 24 hour period. Four sites are above the threshold. These are called alerts - occurrences of the condition being detected - and the alert name, status, time of detection, and duration of the condition are shown in this view. Alerts come and go from the list depending on whether the rule conditions are met. - -When an alert is created, it generates actions. If the conditions that caused the alert persist, the actions run again according to the rule notification settings. There are four common alert statuses: - -`active`:: The conditions for the rule are met and actions should be generated according to the notification settings. -`flapping`:: The alert is switching repeatedly between active and recovered states. -`recovered`:: The conditions for the rule are no longer met and recovery actions should be generated. -`untracked`:: Actions are no longer generated. For example, you can choose to move active alerts to this state when you disable or delete rules. - -NOTE: The `flapping` state is possible only if you have enabled alert flapping detection in *{stack-manage-app}* > *{rules-ui}* > *Settings*. For each space, you can choose a look back window and threshold that are used to determine whether alerts are flapping. For example, you can specify that the alert must change status at least 6 times in the last 10 runs. If the rule has actions that run when the alert status changes, those actions are suppressed while the alert is flapping. - -You can mute an alert to temporarily suppress future actions. -Open the action menu (…) for the appropriate alert in the table and select *Mute*. -To permanently suppress actions for an alert, open the actions menu and select *Mark as untracked*. +For more information about alerts, go to <>. If there are rule actions that failed to run successfully, you can see the details on the *History* tab. In the *Message* column, click the warning or expand icon image:images/expand-icon-2.png[double arrow icon to open a flyout with the document details] or click the number in the *Errored actions* column to open the *Errored Actions* panel. @@ -192,9 +180,6 @@ In this example, the action failed because the <>. - [float] [[importing-and-exporting-rules]] === Import and export rules diff --git a/docs/user/alerting/images/stack-management-alerts-page.png b/docs/user/alerting/images/stack-management-alerts-page.png new file mode 100644 index 0000000000000000000000000000000000000000..4e985c3d6e6771df5cf6c4de004b660772e86c66 GIT binary patch literal 238977 zcmeFZWmH_-wlzu!NeFI%;1;}am%`m$0|a*q?!g^Ga1ZY8?(XjH?rv}Gz0bXGpZmUZ zzIOh-AD6ZY7FE!y)tY0D(MRuntRPuw5qKCZ7zhXmcrj5yc?byTWeAA3sL=0$XVTy= zfgf*7OaugE#RLQhWWQS(nwT3vK#)h;M>a~la_Yf(1ZTU3&k#e& zn-BQFKg~nt=d98NrSDd!s@{^YPuM94o4r0Vyes2EUMx#;qkLZxzNce@rwp;7&$e`9C?}aJ%RaG48qegzL$< zUSDH~4Qi3nJ&f}M*PhKlRm@OI3W5?ihlY3)U;+UJoV@`aSil1U0`fQHe?0@e{QK>H zoxer><3*;>yDA6>UI;NkK1HWDM=9@|&{Qz|Wg-baBBOxnG;DI~%xtJnN~oXEYS*N_ zh`Mou8-cG6(Cy0;uc_FE43)9V`kSlkYC8{0&budH<{yvQdG7D;pGD}9Am03^2Qehi z^Hr1_CPo*XS}^~A`rk-_{7^$dW%+Bh<= zNCCs_(yEHjmMjw>B03(7H)n$VyFL?q6I@%m52S7af0}?w_-R}s<3|<+%kWYu9V)~gK(@NSD~NElJ?NM)tnej{5Z-Ip%Z}+mHQ+mlgdRRGukzkuZQglhe^|0_x+k91?-wy61?eLF3jWh zBsyPVkUf;ZFtBUo_2djH>9%&3i?o)HbOx(GXtqri+c|`bydEwuD}EaIN1-J6iVQ5v z*JT9B_y6+h65)I4^-52aEV~vrlxf3YWFc$4rEoZ!Q?9PfMjqYV%AefY*?}1kqh33j zi|xiT2bJiSE9qBZvs#XiXu1|PRH5}p$z=*(=P#7TNW$QqthoM$v2bt7>vytF2{-Hi|5tXglBQD`6K9Z)HKkN-|Bc>@~;TsBZC;18kpVL@L5Cr$5U&a z;@}I(wIu&L*e!)eqBoFU$ah!!sMpwZlAmU*A93a@xv_-SZXTl84V z<4q5u%cFUVG(JQ7etFZm`c5)su)Dikk^a9|aOsZ~Tv|qvg#OnnNb7|;Nj6|rYF7GF zU@w`|F|sE-O_J4WB{r#zSU5a4UEskqi4YzVIlS$()iE2TJ7jO?`C%Bl!S$BgVy?_@ z#%d09SYxp&rrqk19!dQEaN+x2etuN%*yS$m)}y~43LR2eEJVPi9M^oAO16%`qe6}( zrrq-CM=SB?_i!=kw{x3_0Z&+Ct+gfa3L{mgfYAf{QA6jqb6nF89e*Rl*{IG{w z+wb9!Hh%Z75gJkl)Yq@c`5w&+SEEaQSL>Z34a7}eSyEBrsWD)8kZPS|&R{eJ-@M0& z?st|C2zcpHWTSlzG%1THurB81r>oC_0$*`C9e&|~FJd((v&5)b3nk(x4KJN?M%=d# z>=){7X~9V8el2eI{P}`?#UM2X`I6-MxA2D@UxAenilfmav^ph2lkhzdPn?Q^!Jr}F zN8Dzn8k(ze=G1KUh{D0$luw!&mXr!%LmM7ayWIA71#-exym+VWF73q0@}ohGdn5Xl zCUnL~N;7ZnXmaLYT&Y}#FJ3f_CRTxZHBotYNDC#|8`pCa=Qz3b8{2Y#t=_pVU9t)TtlLp`5eM@a|9-s-L5uc z?eFiGD>)q4cmf?jhu?EuW=kd2j2|yL?(Zw$UtCE_KBa=>GN8+EW7|Sk88vE;vqCUv zCpUYaQiDhYJ=jTh1%puD&wx8-UT;@DCu~1!^Y(=9Z`*b(b+d8yW}*)#K}YCe=to81 z^Ypv+Vd5F>6ggicBvYw4?APzd)?pZprpD=vuQa=otvs3teXioVz|=p%5x-YJ*0mUn zJ+?cHeSHqaUyb<{^4NDs-Tb*1t8rj-Ow)D$x}WU96XN~JHtZtw%cPY%n9KIhvQ%1uwkoPKPVQ< z^R3(xi^zC?I9M42&w7a-^`8JVmAM+>L_N< z2tBaCt$C>@e!YqQanzCTI2H_~Z#a~CwZVRQjce~OL9C=7T10wQ|2 z7}dJ5e*gAQs_ao^g7BI2`?UczEz=e}N_@TpbmPfTkh>F|w? z>0}yL&RNeSGI%W2*=z|Dz#2J*ik0$s}>4Zgkr+6vbxvMdeBl zA_?sXveIg|`Wg3)q0^|7c6eXsKHYyWR01K$ zpQOm&0cpBAw3M?T*fL(EA4P~lVkgw@et=omt3P{C#r`nq9a-$ja$+^MNmri@jQX-o zdq?(EvxbPNY->$PGUE#W4+g`bFBA-nMN5sR5X1LIZ=Pq$XzY(CR?5`lJa13H*H6u~ z6o;zCXnI3Qt$|o9c@im{;rJ3V;qy+-sH;(Er8F-YSqt$Cog{81qe{L{p zX5uF(ka7h85X_r?7?0+>czZV%U8^U)lv+0wyvpZDoll2h5V$}Zy%?N&Z(|X zriY96+Ljovj@V!2oTRQ!XOmQa>KKC%nA{LBYsPofo_;?)$qfvHeeRzbTu0m}6&kXf zTJ7nmQbPw0<#awLXWrcYFrTj&D_hUpwpGAnGzdl$mw!&^^{&+K|0RF=3NL%ec7A_p zq{*FUHhK1Jvoqwp%&~d(A87dq?o? z(W-u3ZzcZS-*WN)z>2(IzMSn0Yg`xT_J$Yd2yg&zh4GN7;+eAM-wnRM+*Rr*CVsgIUUn!qL&t5D*QiNA|O(Lh^0~DFLBN`KmYZKU$UIPKamRo?{Vkaoi_^yZi+t1-=u)~R{BFICFo z<}~q|$?V3B*(&~-tD+k%;9=tW!#C-XsQg7_!Ff2)J~63F}DuXoX%W^=y{2HpT0e~lW%6YQ&eAo6fm0^H%m~? zo-BPW+_~bQ`mLwN!!ueuLad$Ln)?HAPhMTpO7G7ZF+|^;O41$&gBxpKcLGMf| z2I}3CHT4My&CqPTE!YhV4cZyT&iBrXDVzx`b0*7kzU=8Dv}VhSF79bkTcdNk<0WLd zS97>UP2W*2QJ2{4k%_#gPv_Xt>oVEOX}%?9%rr_rg+l8G|B zPbfE>6>U-PWS$>hbm)C?U%7N2n~g9ElrB}SF*Am`@XQo2Lw37HJG|aLK=YY;WUGQL z7i%P>5V7uZ;cRlBl0BbuGM$9&qrH{Uu`7PFs4>V?gHir!JJypRxR!lSAARP%{zn%3 z?_YVN3EGl=F&Yi4_|bx(z9I7(&*e`VDV=^is`u*5B=^SV_AF9GV9Qg^8>ogHT9hvF{%q z3QQz|0uY<0k+eaS%74caF{3r1M6jc3uinySY}6c{Rf{xC=#h$`H8zwut8Oa76nMJs%A;GN3!o&K{%U8 za_Sl_8`}2ZbM}MTLLf8OX+jbTVsRSAKftAO8N7FYyph6%Jd_hkC+(5BlW^ir)IaYg zqP6YWh_%rR&_G)vcW-pqCrI^Sw&P)qX;>?fGQipH8zoWj#x7Ycx2-kr$tV~9G_ z7>%-LVYWFmYAtD4viNs7eOzyFWThoiII6}ieDgmMjaLZiZHytBJDw~>VZSn<_IU;% z;HzjI#GYqpdVi;Ob~{wxwH|@S>G%S99@4o|zLzZ!Fr!#xtP^!=k&PJg?)&aY zy1spHMn>s{n|`|TLRG#2IAC-0vdo4pFOj)mplaO{lm#SJcjOWCgdz@yqiAStCDk0Y zy*$-Jw?z=SEVkzRY(cR%{AKp9NO(+q){i{%x0IV6Y zC8B4@&f_h_ba}O7=qu7jTyxkm{Y3!$%x6#DcJc3j?|J__CH;9K2nG2%r1^P|NzJWe z6%vt}({nw;h4Mz)`fvu9xm3yxBW;nw;dJFK3Fh8;gD{e8g>P#ujzS9Cl0-YCv%M0| zj4x~1JcH4ID5!+qNL{YW02z-w3sgVn#A-zGi!3fFcr>k*ZWd~r6x!|egsk2srdr2S z6|Iv9dZo=E0;yHGl&pCnnnKfCK1=fX6F?RztMhI?CqF6)xu=Sy_i>I; zdv|fTY9*f5=b(T7A;9)=^OlDHv+d76_@2jGe0kcaPEMOUvYRYsJ5lY*j!q_%CqE`r z5h-s0eu|ruWlj$)tKhsZuE{y>Th?3RGwy`6{aACLVyJwuqKtSz}X z8$ri6$Bhi2g!-E%LznA=Qe{NEsaf(YMA!NC+s_&gSNmCO^2gtPuE}}@gPra~KP`U) zQz}A+gT4i0c3z-oXFszFjiJ$H?4zai_V-tfjRM8Ub*2h^1%Ii;dfl4{Z4qle+rwvv zAyjR9U^_dv{IgftSn3CpzcR;}NZW->)fww5Qi9wu$Mt^I9cfsxa;-EqGOJx^@iL@E ztI4IZ>1>O_@8i1m(0v8JL$ygt&BFJ*#Q&0nfhL2RQ)nC5hSkptA4~ofG0J#t2ajE? zI2nsl>$i(&HavS4;?q0(6WL0WIVer#@v_kLsz1(;)Y_O6OtF(I*fv6b z?0|$r_jU?oExmr6UjAVIMK1TlshuA~ZMxOd3Yj#oQnK=F>onoD55tP-m59YjB8C#+ z1$W}KG~s$TXgy9)J3@*z948VgclSC2BK)O_2F$wAb2!NHWa>_~3uki@_Xbj1p^?mo zfgbG6AgsL43oKOT{EAdiE`l$SG>?Gr2G75UT}05T^DsmBn)0H1Jt-WIQ!I(aLIFHg zMwWbczPxvv`eHV4<}w_FQJ2C#s=r{QdN7qQC~+CfpafGbPqj43EufGCXPn70^QEfe z_io~DZcdQoMO<0{9Cmgv7B;IXZ?}*WpMdK*!y2aB)18>2y`LArxtK+ z9BMrOtKO82W>eiv+@m5VvYX{bHE97A>gL`3OmX6b4xy8RZ`Eswn#_}~Lh9_%axcB* z*W)r#pTG7f1f<-G&;US%dIN-(YoqSA>BAkpv1g#FIyNnHYnPg7uYFAwyg6vd`1KY7IyvNLCh zYYGdUX;}w8Tk3Wu9}7UcS>`9d6?sH;`oh&lo&$fF6`jEOeeO4NAqKWPebnp~fbjE0 zM!Bbe&X3`1DM;6Np$PXHpH9*ROpmry#)@^5p%*5E*oE4dsn_+atG9q}zz(iK7C&;sb&3u@E;pj96oa=MxDeaM9$&(?i7q>4m73Dt=k&&E3}$0ugh zSDO?R*E6W7V5nCa*T4z%K(ZB=-{z|@FqnYY zZC#43>4r+1$kh{y>4US$CcDH|?h9)er6~*jPi!M{Fof0B_ddIBw&fBF2`nC+0#G8G zGZu9+&tTCkRCZeZCKVNz$>$rXg9Jg3%jAeCGPT|L1;SXLbvnaKypt1C+z?z867js9 zw-R-xEITJF)i@KuU{-P+rKRP~4=h!3&l*yqpEJeLe966(3TN{-cSqAiq%@*L0Xp&F z_R+`XdEAdivq5~9_G<>v(@xZ1V(8z#{eTFN6kwB;CCmfsx9?q$1JHE!5EYKLi8X49 zqQ#xCY$EWrTV5Sb79>1xaEor}}CX0;y;HM6(32th(0AHq|V-V+oD}UwU&IP7Z~m z<>h8YEm8MIh<#rC4dwvhfKy6hrRzq>Ot8slarF85-MIpj#e=z8*P&+}bhE(-F$ydR zTA_SBB(v3wXumoaM+@dNb1LY4i+QFo3-(#}+Y0V<}$X-D^<-NBUF zLbYotPVlZ=t%t%w#l7}9=muka!3Ck}!=Jnuv^%7nmR+UGb>cTU?M6$mAZt6(=bMxO z*D#bQ=)h`IOX2Vh4dmqpb&Q+ArO)Ju?vS7&=gS+^=EpO!KnrfvD&}-gL~CIn*)Bqt zL7!D3z4v&*8jDEjs9fujgSJY>(TfUEz@ZrUXzYddPra_7IV5v|%BR&AEz(Y+*&4VZE33au`@)kD*x@JJ)Fpr6{5S8+WJay${s@AgwI1LgS-;j?3v7Eub%4D4RN_M zOi+yRVS8)gj9WY*e-lXAc~#JQ1|ycs4aLefdl_v*oy5Fcop}7e$YiioF*04Y!Nbq@ z97924s%^+>VSXgNT_MH#{TWxbGehXK%mxEnrq6{cR#SG?s2@>DWdrKmA4?KhV#ZuJ zB;v;eEHc~;D^!Pm?fK7U>V9N06Qgh?N{woMnbq!}*ozb}Q01;}BUs--FEdnQ3c5Ci zAcr(ME@$y^xqotf?~1mma;!eR*B|A;G-OtUU zWPCUbn{|I+y0AT?NoUg#i*pB;o&DWO4udKg|1J_SoyEhda@eq`OQ2;D|0fzO_tz7V zQLUy-jMA0;FG@$?4mES--tU3uoj!tg!I+F3#9_W4AVCfH4@yoO8*xYo9xoSR zTCI<~M=^)X0ize!Q@70ZjXlJOti1%DkE~o@sdoNZ28VfrP(PI}fQ`j8CxI@N#G+un zfkBLpOdhMciMsnj9!_U8cgCDlzyzLII)YvCxEE@B^lT4--yQkhy038$;>L~noUkZ!Io7kg5oihI`YmIAfdGy%|D_#sb07ACz4d6;g^3i98SDeEVY!Xl$^tk zux)aR2D>V!e4zFir8qUYA?ivck(@v9oK2z(M>DWmY035rc}gP#xh1mcWOW}dw7&jS z$EQtw21o(@k*t-`YiyQ}rQ+9piqO@i+N~2422|7RXJAFiM>x$2eUeX9>T_AvXXC_H ze*n^>9xcgzycf_M z%jJF`;C#77R2+a)B(iJ)&58-oVrI1d-6gD+OTSY4oWLX!JNbtL{OvnZo(e*&7{0v> zftGfGKmRBvUe;0s>UF7_&@$og7;nlnd0PCwMU>OMhyKBP27P9DUAb$u|B#Y<^%Ss1 z>QMAKx^FpQB3n`vQ=TlN>tk~NFiFW7I)d_X1-(DIU)wl_$oYHq z@$uptExsxK$hCUh3VGk|jnApD+EFvAYh#{kbk%vL(*vdp^4>xsN|Y+mQmWBcvsG%O zvjZpK5Bhh7(wZK*FfpbF3(+7sNpN?vCwky*v}Yc5wd|L=(02ln(^c!~s&o}5mk#$@ ztW8=T_#?^8GBDzG;c57475Yr(=v!PN$^efgbhBH{;Iv1cS=|xC^?`&-EBt7F>yeK= zf1T0p1<@u$epI9-oX_X2uMo4DBI85GM3>lPU^935C(utBC*KMh#poMMuCGqS&X+sI zI0BEWJ|80TDpf;peieW9J2-euT>J($74u800?*`Bt5jOO>X=RxQHSBOCiuIC(ck0M zx$mZOB!gFd4t|UN1tonydyyaS8%`Jeu=0QkI7_TP%vY~2Xvc(f2e^tO-XG0;TxTAH zofT)+O(w(GQ|HN$8(oX*OrIhD2%rvM2%bsZZbu@-bC<^xRPePsahfAH?Fx(x8$N|! zE+;$msOCRA3Ip^0P=JL~IBK#jmt6-X;=x9EK#%MN$gl?70C<})>m5*fS>Jd?f{X`9 zl^|L)L5nX3Ld)o$ntXkEDS) zeaGo=B*$uYkFz}xTk(L#^U>z{u3T#hkW}}BjF#>w?1app020ev)%W|wmdQeeLBK(F zK=YLKXM*lvj7LB98e@JC-ZvR;Y7P6Wnc^gc1*ZJHMkJ0hkzbgeqjHHMwqZXv3*Hg6 zuN#m`rILoIo?U2U#sUr#XBR*?Nb9^av_+)~&`nTvnrgBYWWDt`euA@@mZ$x;2udw4e1%7{W$<|i`wV`wFMUHC1=di$ z_t-F}I8QbuZTbnQc&h$%MGB=sXTK)B8T3U(v|HTLD~)K!-mmM3+|Ne=OsbM`|8qHB zg7*p_I7-hrDVomxX!h)$aIDdzsWY2g$bXWr`|-dSn`ZX>fS8Fw5*(PenZMs~_M`JO z1fXQ|J3q0UDd#Hxm&QT!QBZAsxH}|nZ{_)eLp=qj!%0RQQFv8SVWDPECjme%*PuGl z@|P@mKJmM_t|7^P^qcFMW)DApoBrVsq$mgh2_oH^Eo8;-+pR}hg&to&ejN2ZBjxT6 z(@Vj=fVNJEC;A(rES_Osm{Vmti>H)a;XLS29gd2l z8^FptTe6r(RZH4QnD%gcNYXSM8au4k^=(A;x8AT}dJRuNcs!lQ7iQEBY?jo<^{4t| z0m$pa#}8!oGdcE*6sBuZ>^Cpzz8e$FC<%XNjp`YL^*4NrNF+Tbl+#Ma3-=zpa7kzOfdt~ltA?yYW1`8!2umiH zA;ATzF6<`;CM^xUUbr|&mQD^^XY}`Bc+Ao2)hA#4I6*Lah(tL>lKa1|G&&oEm5vu` zki2snCwyReWM+z%3A7jdK}(nC=Ss8bH8c!a_w_cfF9P=P7d_mqL-Ww3d_+~+Hn!7z zG)56bfYzyenp^LDrk=oHP=scQnHt(18ATSJ(<8OmM~OaWEW{-K7)oTfa;Eb(G?nZF z0*-QG-)3-34_yz7zpS+vu?#EO0nu0ZV?y2=D)*2yLJRL)a9m zPbJwM^1v34Hz_wb2zr22F~_^MeTZmxJ8nx+XA_JaGLb6|-5v)2G=>KF_%=|i?Zc@$ zq)AX#d2N5LS~fq9#c8#cA7eKo-yYE0{*62G>J$I1Ao2>Y)WUtE53~|y*YcX0n#TJZ zo>{#x)n_8!;C8#ynf9`|9Jgu8PyJ?hyc<#)3d-5v->KKTy)o&mi8nPW0Ri$nli3d1 zKpIb}9O})9Y^#<4nbxfQ(_ku+=-^nG_JT&P*1m zPh&1f3dd?&iF--q?%z^Z?pZUsTw!m=BXbw`-i(*N`4D$Vp${nEtmj!>eqIAy4t_^_^}%xPEeqcgPNPO z?gGb1xVcBOc5yH;FvN+trsEgtY7IsfYG}2ZvU-Vd5IwmD^%@&{XO%T1J)a+xZrmSt zsNGR6&4tj0MC7*=2qdA~j{_Mn2)Raw>g%$uD@0$hPj9=zP(}Q)^mQbRKfeMlPqquZ zNtq4&fD7?tw)8t^w8?@=J+QhTg(TLzo`pK&`E2Q`=&3zzH)EKe6%HjM19ue7@>wif zMb2&2d)S3PkQ}cs2@;7AE17g^#sPCt1isnvGT8khZ`gAw5eqv5TS1Y(1TG`#rylkM zvFFp3pC!*(Os?3M4l(C0N0@yDUAI4$33?VPwb_ZRQ|kPS0@)>RUcR+^EgkzmE#Tj$ zLjs%rFc~%7qN@P8=r>7awcKOme zj%tWnzR^_#+I7}yauOroY7S~WMvV+>HL-gf!OgeZG4sJhy?Z$3T)y-mr24wq?X}kP z8Ce{N=L`ZbD1Ns-!rZwN9uK~!BHw?h$NovI{sY~@dG%prF(FB>wzy{k_9mza%HJH? zD_mWvHbv#kW;1e=q+vxSSSJgBWhrW=L_?<5ayjP%BA&Qo#_4M7>~K^kRW_1M%KWuq zzC1}j|9wTrwfPxWNLk_Jx)$+Xg7qwRe6{&_=*2c{pyTj~bR4xdA1nq~-th1~guP_aXrsR;sd`N-%gPs8bRa*O9}CR@3#{6v=} z@;L*Y(Vq*53@IiQ-#pr3anmcKyP6&-;f|}3$luY;}Hw+`H*Dk z2}k@!$sSNM&6p`?3lKsD1qVXkY!6~Al-ptqC)M&o^Mt?SFhEZ^JG@G$tg?I-o^P>C zQCDnqkfQvW_w6Uk)yYb;1Ry^l?bX-wb;E2=J1jaLW$?Tn(dv$J%MHSzj;4YqKb7yM zo}-c;4ww&{(`}Mah;4MS1X+gTa!OAc4gGp5PUviYL=4ncAN^qO%`9ndpMsL*y^Ao z{~KKTTZsG>DE|l-Vn{h@yGor-(!%rE0yUorSRH{8ocVpg>7{(VSmg{`Z814eP@^+% zyj!w7RcT~Jk@0baOS$N))Dxw430xR9XYkSz|H>xxXtQ(3OnZVu{M9vJdB)`jF4%-8F6m@4CQ5B@YrSl8+Q__FHjh`p+Ey2TYm`aN@RJX1fq z$=WlGjt}4o%1GKqg*}8v}^3#FjVZ=ac)%?fH!=EqpY}txxSatnbTlaztahrm_Tk))0bT_`V=z3$o&b8y`2o zD`yrcj;~gVe_9voQXhv8h=&=?z()5d+tZucvr)D!%UQ2E=G<58{|;aQCIAbhF>88H z`8R)Lwm^RolJdv6eSUO&&`$HH(%=8yS@3Oleo?0N#m9Is)`H1(2JX8<_|gj8oZj1j zxL|BfQudy(Pv#z<|NNjtRBy<7RX5c3dGWd3(~UOf6Z(k1zq$n$-6GHaJNNJTM{{nw z5N^+h9Ie0rTk{K3Mc&~Lv8v8@q_}K0GP6e-A=-A%`uwSFjWXI{CqDI+(yA`M#L-2C zqI}tcGacs^rI)Vcb~kWXbD9Hsomh|pzO4JqMwp#Asv@2ewZCx^9k zxqgX?rPjv$1=za-B4nl7J(m|^w)XZuXY9fhw$Bd^hs?fcS^oM`rS)tUaZjVw6dy}l ztI4#zw#K`}stoe<8mlsyG(MauR+h<^h@(*iEZvpIY0%@-9e%KW7}>ZR^R^*uMe6O| z@3yG`FF{3VR8&;|3&0!amh1Hv*xMh@WDAF3?!SZU^r z0jbFs&yv0%=i{-EcVYgdr2GX8ye)jAm91U(eoILrfO;$ zE%c0bSJnfZ#{!Y&!t!zogMJ?`K&zw=#84@Oe(q_-`n;mO3_;33A|4H}0xo@tg({`; z!03ftalBH6e!rc;!q87bfxWH%C{sB=(9AcREn)DyJJZ2p|DL6;QfVk<3QUJ2B944@ zJYEorB9)Tw4MrtHpw_4vB6r&W-0Fd|*}B_a`X+5c%n{tx#@8<7`tV~JdvdOd|!a$7fw z$Lq65h@)mT8y;mRnHRYCM4pPUCUL%;tvmQ*so?r0%{x!!9!|4%e8#2lG7tB*9+huV zMe_A1-C@`&ED}*1%mzq0Ic&)h%sm;gC7K*+lT1?!ZjU!%Sga;|z2QlYjs~UuSJ-rc z4EmBXt!Om*rG(pT9}sbC7B+us%HRyO3y0$1ZU7d=V3n>N7T4wkI*(9!wES?ZRd=Fu z*LU5hE7-cdFi&wvu3AsSNv!t#NE$tW`*Af|1sbJJh!Bh&mU+6(RAcuX5dasYep0~Jf7}M zZ3dz#OiovtIdVQxDQDdrFBV!<1tH>dkF|Ndtrk)&R%d2@U2A{4e0|n1t!}-ONF)Ta zJjZo%w%*x)h6BnPFS!N6C;@GGD1k9RIvM(|-mFiF^Yo|qW#zB51glj~QV;)z`ny+4 zRQcV`x_@7LXOLBGk7|?%z1Vzzo>tz@zy~X*i?5C5yra<6eMOSjg^fxLLeh0iZAtIu zEE(fOMhQK>s}Epcnsag@{l!JJ>AB;GNIXA%LAnC4;;QaSN(G7&)x~ne-#TSfbciZV zW3G4U$H9WZh9eJTicqWrTby=#L|m44lxmGQ0z^zvnxuw0KXYZ=jUPhQ(ADQ!O}huC z0ph^&5fKML*zNKpGucmq%N(on78Ni(buQWgiH)LTu9?$r);A&|;vk{RTKZ-n0P5|H zoi2IZ`u)W<4!9s9#v0g>(=bMbIYNbMD zlgfrGAdKvsM~sD7g<~8*qG{aVY`~Dlx)Dh%0z6Hg!IHi4aD8~SH%?4K72(DM*l1}$ zDkaG!QpN^flb_NO1{j&DMnW$CUdsQ!=ka88o&okNW;>@Xh8{>$z7$?K`QSX+oURKc zRh+_Y8KLC@!(4EtnOvgc$-$CC$k?|dRS0zUkAj#otiUWv^*#bRt+L{5i(7pKlj#+k zWm5Uvl`%jo=xFc7w@ zjOE(EJJ#&>2UGNkNhsE}50U|0wQ9Jb%emph)< z2h-WsUmT9c^m_4BRY7uv%GCBWH{!l%ZzTx3luN#f`N3k;%#uJkCj&E1{Yc;Oc|5YH zR7&=s2;55NIZ<4F=#7q$a|HqrDiXna)^&_0xy%UJ-8yYUn66#xKV^181(HmPJ)R%B zw6xLmkmE~BX`P*%$b}AUhOwHhV^)cC7V>c+#pXCvv?@_aC1pjnZ{;_8!ls`Z9Z$1% z@v7HEygSvIjmLPYSDJbci`M=xiF1zskQ(%COi8EBwpGQxTqwl12}0PF2HqeL2xPy1Ku2oojb@fXd;x828JCO@3#~Qn6Lk<-5Hd zoxN%GQOhZ(y5|#(ru*Hm)TTRL8{O{TU(Pq>`_0Aj&BOK4h#L%636AIu@7t5?&R1;b zdDI}uD1QjQLfU@Y3;;zzGmRL5&lSa3ZpzQFDG5 zxiX^8P_T%*KNlHogK>S{GYv@$H`VmBd!V~naXU-xN7eN;5uW0;?$GsLMX$A-%;CWlmqGS%>KWj z*8|t3lcOrD7iNJ%nA732=ieC&XzbI86o(5;Rx^UW+5M9Hli4wiwzZZk86j~rlS|I9 zcE=!tn-fl6V3ZI&=|qW|8Me9sFh`GB!5?C$Se^ee5H{F>k-XlmDJdxt)?~|?Jz}>F z8=(GVcQBU<3|@#(DCEc{0rw_A4(SmN$C1F{9>C(XxlpV_@la#jZChw^rRA3h5)QY) z5e&p1M0{=Qff08H_&K0!XaxLK(srHL2b;YSvn(H(mJ5`qC;~rLtw+2ERmno3isPdn zTSMoEVlq++O;EwQPRn+oxh*w0SEA|Xh4B-PH#ytt(#vji1syxo{M2nDss%<9l2XV* zgaOls0KKm7am2`*x9?@Wp*~JISBMH>`yZ`$2H2ghfX{Kn@@vLP0Xdu|m5g{g1JJ;J z#l>O3V=;+R>&egzB{WaPGoUZcRm{x4MGTRSzV6eroUaffGhAm#9Sr_N#g?C_+?RpA z@UzUm)e@Mwp)FP7%hISOmdTlc#wKW?`t$#9!z zA-0B(|8Nifv$p*I79gYpDD>lIOF6sBt2U{m9VW+HC9LMNI=M914E@LSMW*lV^jPyP z@mGBr7F(A)Z>d)u)Tj^CNjRsmS`t#Z;qN9+vdwhi#&t(>LYV3WZ1$Ihj?akC_Xi!Z z%C6Wf=3G0=#CPhKD6~N86S>}$y!7UEPixdzOd_wCkJU+|#gGhx~MM}ZxF^i>r3c2E#tA@a^DV0p#=GJmo27d7|r-zIo7_4dhy-_z>DKH=I zxY0V0&S3K0!{chDzmlC|^jXtH?)h)$WeEkh+`Q&fq#Diu;aW0%7_C+hfuvgVYL_zr zT_&1qG`lDPzMYDGj?RwlL6z}Sa3idN%3jFZDqFQ$k4&jld6=zH5kQX0QOv(es=mM2 ziR`Q~9*=gp+7kjDl=b|9-ZL_iqA7kUtTZ|MIYxv=PceRUMp#%=iTxI1769&cxQRlZgjw?M-yOc~c1k7tOLG9S6;+b1DZ z>E(L7oy+Tt@ZRi|@r7NFtG}ODf4L8NMSN>SHc14b(HoL?EagnHZq1dNn%W>isap2? z3X}nVSoy6TGKEcGme7|0RAD@s6NdI~{t%6@``aRmXLUKlXn|7U1mOJ>MV2|ME@O?7 z&+drBptu?8(27+x&-@%9$UxR0w?N(-Pp>Eccynx@fnA~(A;$iFOE&S{Vc)LtLKTHn z3WpM|5m1GImG$|6c;L&vR0kLUOw-0h(J15v9kFiSZyg^OxAejZv59ZOW3!NpIWILj zmeP#srj{{zI6Q<{w(#1a#W$O8DdWu(Xd={s-YE z#r$8SN!EcBWLZ8?(SZl&X^$0ig@B)za7buN}5tAcf{^a`dMG50lI5)I8MA`y9S7=4J38- zO0;l^MVhRMa=$}qmTfgG`Q7&a3lfk07(J32ijeFoTB_v{4X=XJAcjNKKUS0GE((&B zE4raI84e~m0lVg+F4Z-3r%O+NmyHCaG9-`1PTrba6igQMMtM4Dkw|1D6|%aK*F%G+ zDh;K@Q~DB4?whhBsbqp^^IKvk*PVwydH<$Ss-T$6wC_DVfMQi+B+W21U>K+6U+UDU zmE7|IZ3d@9xV>a!#(OnNC!ESxQ zu~_j`u;|cxN~HZ{fHG@)JFjt}?h#BA_*2c?%y&0=Vm>NZg`v8+8KrULgPU4nujI~& zacTNn+}-m*#3}tLmTM2!FV6>bVskw5(CruvSEHIT-BpO8ssapvN zUF7_((GA;?+?KBOyCp_=&US)paKB|guZ|r|_#jUvZyS2+V?6Zm~oA_gRFNy`7u z#(kzpjXVfCQa5bPYthy?y9{l)Y;JpOotP_zms;S#Zt8aQRSlT4@UeCZCG`0)c7xkk zbg|Wu-V6vk#de4{k$yZt_XmSaC{sq3i@8>RYAZGJeFC`c!uER}Q}!u|!x?JhK3UHQ zaCmt57U4rfeSHv;3e9)hh530kUlH3J;C=@crbB@fdxt8X%;W)LL6SZEhzJS>19PrY zgR#{1N&xFSu}y8URq6Djn`Q>f6%&)gF0X&*=(rPoFolyfg&X&Gj^%j9yFVBYr*UzE zK|0b!e<+{XQtd-QDmPtpttQvoa1O_lq7l9Gjcz7j^y&X$@2#Wi*s}G}Kp;VaTOhbQ z1P$))ZUKV3yE_C3?yehm3l0hH?(XjHuX4Kk-qW}HoZD}VH{SS--#Gv55wfdxRjpcU z&ToG6n{xr2o~lh53(OY8NK_ZEI&k|LEFX*kYk~r+Q)M(_S(gE-{h0CDOPxcluOka2C^>WsnxO-`-os2e9ich%s}FC_SqkB{e)OsTU#3)mI@Wf z(js?(P*vXE?z&`oiqI|n{B*P_>fN!!+`P7nBjt#^#zPL*pK_kw9#Dc0dt|1cSzx8q zY{cQ~1^xX^HMm0&1)!MyyU`C@^R{OP!X!RF?HrqeMBNdQh$t~+M99jy<8V#4FUbYe z{Cfo}(Ls#RYl9r>l}kMSlY0XZag;GVg2C%!fnagu%7eRA+DQiHl(eY}a2#0lXR+_737lR^{O z$dt=9C>0jgXgF8}o}fsF!}h3OH9VsXHT8Yvbe?27 zZ>63_TQD|{r#p~w^KZ02!rY|*-nOC2*icOyX@J`gI02gwjMG(^cjIk9j-siqw2!_d zq0o~?gDD2rQ`H+~9#=wgh^(d`2z2aGmVC+bMw3IiMmlug3jFY6;D#l82e=AcF8QLZ zv3W%PMrlI^GU-%&&$*5e3_4o=0i_(D*KdnDD)Up)IGl>^GD-P;e{2uk?-&4`NBT7V zV>d8X-Uh%1C9a!&;gfczhxeMwm%+;^+#JbRDUhUa2GSHm>0BCyK!Sv>i$vWARV9{6 zC0w_Y{)LMFiy6r6=2#e@ea%_SroRbC;Fd}TOqXdEhgeDj1zISZ);S?)LobrbZ=s2i zVjIq{%%q?xy0WoKZB%KmjqUELUhn{=#9=0|1jYa`T|4wuATFS`FgpcrWV|9BVHn|e z>T1MV=+hmC!>8yL&E;%?8nlZPqj`WC7V&ECv9`PA=n)S}X!)ZB znZaS%lwFbU2hgCJe{_*1B?=9?PRXq0%c*P5WOY7D*Fx|do4yqPfR}SogE4;Noa=cj z11bn1FMHmnddV zJ7dt6u@_bOIg7eO6l?9OJULl>k<#}tJk#kO;W4T$ zDy@?{(-o>!tKM61I({F3_;KM=WJo$!qgOQ~2Z1)zll zfZ{6M8nsfKAl9EW7J+69!g)+RrTU>d>k0n7_Gvzvux`v_$yuyO7MiO0YVWFSHiVTb zs+>-=k{Jv_x~?pSQU!c{bc_od9S({VbgZaCb^~D(=(KV3vQsj=p4AxiPdKT;8EUYY zO(P4f<-|FTCmL%FPV_A1Yvhs_u6oz9YqC>>Lea-c)T;e=8S5U~HQlPZ!#)f|8qZga ziswrtgaa97fsmklz)Va4h|QiLCz?b;7~rp?08leF6i=h^wZrykrA?bvNdPILj3JgG zWLMZFK5*Q`2J4@|?5YY-E3ocu?28h10+t|t(9NFC5R{hGCV4% z9cZFZVAbYRV}2)|6RNxRx{bwhUQ&xlcmjxCp@;yP;(3>S$%!*eeZvD6RLl1H4h7?&)mg!J(Lz+l1y&C>ljkNcc>_ri#r)pmr z2i5jFhe?aap%6ZWw75KoiDBWmz^}Bvh#;i5fgT7i<8DF`?2p6gEVz*AgGPRGL`)x> z{uD+-(M3e>NvtYzQAkExI%PwZz~`4gYT7K-cMyTk$Ysu8#UpnxpO`7JFiPYm>Xi4v z4E1j`{b>z3&0T-xAT9aeilv8oVtuUW2M0^L&=3tbj|Ah_NGsz^@LWPb(VzA{c z0*l$VHZdgB4Oz_TDrZuD+tVPDAI#6)B7&8~V#o_jN?Hm_jW4v?O2vxVy8M%u)leq! z1Ol!N1QrutqUtL%Zhw5))uJQRwhVlS*=g5P!@;&Z%F1+YzOk{9gI+y@fetm>@##_q zs56s-@8XAhUY$S(+P9F>s8)D07!8*=>LHN-K(n7s0SkIJUjfv#i%3^g1hlkQZ1p0o zIz|G0I%sn-84dlD@CDsoT)5Ts5IC{HsS3LJk)P`*g5Fl^$4|rDgc^1eDW!9|*z2NO z4(OJ^piz!i84P?XPUhm5IQznvM&)LjOt0h1o&gXkG1ElIp((Td33M_Yfp9SDzs`5FaMPAz%N4Cov$r^WC&!&zP&jB(E9jPu}a^-z(6vs@oVt4@OGf^ z3n)N!lvhQW-Mp1>@e6u~k)DA&zRLGB^lX7M`>Eh9m;wYm9-H`3@^?}#BcC}SBV3@9 zlgDJSPrTO0e%NyJhDCc)gcDpf0_h}Or<*_|(d{4KAkZM1cE%WA|K(l6KaS^0N34fw!ztW030j6=|tLG-0QqoX0ak8Mj$1 z;T=Ef9u}59x7Slyiq)I7vF=nC)1SncbuNURTp>${>GtzswY1=VBL@*cRCkp9Ve9jD z_{D>A<}XgN7(U82Lj})a13uM5G=VkY%ms6luJY7-vP_vax$^$o{G%__hi*ESeCNu7 z8bqEcs^oNA&^3Y>h~=Aauqa?Ifv^pDa>FZ&QhAb7Yl7w|)f{2wWabCF;%-e6e#tXD zvF1DM?siu>GSn`#l1H|+=~&u$`r(9#332jO_wi7N`| zx5b(qPbys|;Ru=Dx1kP@aw2W@$Hmy{j|i&;Ad=Z_OUex|NPXKK+YMcDx+hiq4$reL zLg`L;ZZlaRH*Qf^I}-_HLegg90E!^QDh-u&ZfRshrf$m$f|73eafhBK@9_JIXAY3a zODRGwi=dOeKAe*RbPoF8S09Hu0aH~tWH_8!nCBN=!TQ?K$kI3f291Gwd}}U8tW>?$ z-ascw#|J%#9*aT$t5UlECw=q}Ud}^!`c%_ES1n#h*2U>@b-8W^hfRmx6?q&^=L+>9 zLOk>baxH^;-vCO3{#dyM2r{I}hAKo+s>UQ9uU5-&@!eu@NSNL`O6<9mnCNYn3-*sU z>9E59PEN>3Gk>HG_$MU^uPWjyox$k|P!9hUi6}QRjmzjKFFqmCEg)l2DwAK@r?aA* z>CTwyj=;-kbUG+OU4sJuLD)_(v_ENKeDNNK-2nsvG>u#1hqO2jg~$IA{%Sghje$I( z2m;`D1%v%}67zq4fLn-u&ANAE%4VDc71gLKDbltrLoyNntoK8z{7%GpqBX@Z z#f8|K7~TL){(Aoj<`gPaHK>kEg^l=P@!;u<9IgYCbvvr7(WxF*>gBmQzTDM#w4-y{(0Nj)%Ku*n7fyAst z56^PNVn|Ij;1ldF^6s?jCIcO%YphnZTxI4eJL;^xw)1qX-te8h>i|e;ar=&S1VBd? z3{>EU*=`St4G&Kjm#bxVXlcyOHc9%ufzwZZ*|-AAY~G$pcoNnQE(g!onjHwT4)Taa z6E{v&$dW3TRCtu30X!9JK8Zy9?s>>;m{2XXv;6+uvvDbKck||npf-;Sr?|cm`G2my z_GbZm*3hDAok`E=dUw*Y{0D(@YW~gkfP^b%e z1{s^H+j5d~!1|4+7?Z;ie5y>z51@|GacLp#zOF)$N~W5h!_0Z>P_5O) zBo7x@%{ZW4@)97c*Qt~)bf*yNEz*x=31$RIZAwN6B^HLX%#aH#Jk462eFR$42yt(n z=VcQn#mE*3O7piPMJVI6O8ITSchj;#y_lLOTD$5=wW+7J+g`&;@!#Mzaj7N)Nh^7> z%qXg)lSzSVE(4fjtt(K#iz5DGVX?G5qiz=kWju56oUEF78{l8r<@>c05y>eWw!@DJ z?USbSuE+&!^xn1xA~$qSImYZ^K`NlM(Js32^;q4GCM}HY&I(zjS(~m`#l*Igz)ztb zWfuwUmvfY(YZ;c*4*vY$ms0$}1Lzz%Iy3U~04fx>q_+0pTMN1B0&BsMyE*C-#1-fC zb+rA|ZtCN>!rSS~kgKfta0m3ZR_dn~$+vg8Az6e(aMPqjndE z-+JkfWbUZSu&hx(0k}#G%y5LVS^y!+_k`or3Ne(RxM4wCY#<2j3?}I%Alh*{xiPHH z{s3}ab(nnshrD-XcEA-f=MD~wGur_Z#J#RksoQ0ay!aj-SXi1w2*Mpf2(0FYGn_%k zbU#j?_D&l9_u9yA8{C};;VUotch^- z`bezP(JVheQUO8X{doG)LZQ%wH=U#j$2Uw4z7!!W2w%a~^)87Tpx01N>!I4ys?QRW zLZK)!>3p4@Da(hC+k5dt_Lq4(8$V)I>8NT^BbMCBIoYg`7?A+_}i z(GX_JC@nE{PTWT1)h`4J_x|?!@?2Oe>lj6p{;X=z4RX|H0gf50U~7KV@aX>HYsNwF z=`NYq=CU8DaNcW%-p>pX`SYYR*ehHb^F)o9UHD?k$h^>DU*K!VEUEM`NFJhPBiL>4 z;Z_9UF$yzL;x|L9T~y5&?O?|j-j#zz5#e&Wixo$_KUovTa5GYOGetxeFXZsJNQ$nx z@3k9E4nka0?Z8+1={#@QXwO1GZK@_L_}y3`He9kmfM@|@V#u+3a$C&=(SR9EkrVwG4qYmIK~7FvsKq)fnbf zQPms2V{`Y7#)LH3@K>cm%IS4~%R1j0D9+b$Isur1yvx0z7s3(Tm`|PYY!Zp|1Y3PE zJ)djeef&ia#9R#qb_rfrtq#U@F#`qo49Ou`@AH8kW5O2o-ZL>lK|y_uqqLhwWGUy= za7Py#?*E;S0xIBB+DkRQe|r^6F6TRok~e)DO85&~dgU7ruz9GsPXm1t**kPM`S3p@ ztJax=#L5Zm45jiVlNk25Ih{vettH*E9PwDostjjbg<*2>yIXE%Qi;5QFejk5iMCPY zLHDB3Vv@OmWTVxnSjD51tsp_ZY!&UGC_nw1}o{o*Ad7k=WPc{>hfs) znLk`FN2)X#PY7KVRU1kQ?!`br$xXtb1e+mf6@iolKT#?y+rWQzEvc(?0`zn;rlQoi zP0CqJq%xH!zAir`@0ux0j$L1#p6n9vCR!zy6*-IZEmHyNY&5$x0nj5!QmoC1Kvz0! zUcPQTyR8)qRKab@7IG_BAYDr$)nicUPh$t`sz9t0cMESHw-_)2ku1;^b9PhnP;|=N zyRGl#VRW0L_=1{EP<8`bH!cFpU``n7)ENjkb-`l3e}75nF*>T3jM3O@d7#pho_F?X zeRvW{g7o`r!YPV$h~2g)kZ|0VxgfJFf30||m~Y+wr0*loT-oiI;U&6&a0eSw29$8g z%@LOF8Ulr8Yx}Lo3r@V|rpe2(u))Eew}`glU73S72P!W^t(li$yB^N3UDkXXCQDqX z*n!;aSFK_HV1?b)A02?g+*g#WIhab9)fS@n`w5R6zte^I03swdxZg!kaJ>0^jY;QP zQcZWdsH$qm%B8~LCl$b~Z~tKtsCQHeb2dxe33FN=v zLt~V$xLl1;pd5sljx0Z^BtJjD%kaXdl!OH!OPypI&VUG&08w{Be@z|DAY^+6nX3J5 zdqDfE$z*{~)NbI1bX4u>dyq9j4mS{1n?e23XVsZ6Sx(j%hM8{C@=IVQrxa5G-H$?_ zf#!iKwJL`e6^K3PCohd)K*cEEs{^EgR}j=Fx24W+lJC ztV{{+P5tl=k->xK%tq9(i9W?0pXtUZG^?7~V9ge{42eb~-f=W&xaN76kwJlbK>Uz1ZB%>M8wlBZvn+vs9{_wY*UKvvRqUT(h4 z{Uu;ta$cx)^!B|bfNqvCB28%McpzBpJ`nQHyd zwePWP6|D7B_;WCP3cbuG$gld zzznH+2y=;)ci$DdP`og+TJ0#!+Z~pbXplUQ&^42RBv*6mJf7C5G@Cm(zCSCgF6I=N zj}abp1+gXs9ZaXJq`nJwL*!|FCO}8tX-}L+v379C@=~G8H&Gx%>gk6Q)6lpN)Y*oBTA?t7y~&wXKgSGl@SPV&oDgLm zHK%|4J&)TB7_Lw)i}fQUvMU`JKOLbGpAbd1Xb+4k;vuALrH5{VYnS7ddc$?NCMp^q zU!|-fqFm!8d=?77H!(2*Wb1`=szJ=4rDKd#qWSZV%ggs`Xr)9nG5({&H zbm0MX1$bpDld*N@Mj1E5;R}KMop-~P2{ij6IO_YN>VXb$Q)U#9U=WDBuYUXR$wsf= zFDljta=LTR-Qj>N?;Q>|n^AihZGpg)JR&(Q_{WbQ8I3wZuq*4dvoN< zY?w{!$irlv5c6>bZ)>hkVymw_z85mWi|%9#>2jjkQmLWioyeAEw?~~Ut>>=Bp3{kb z!%NsoNoM*!vwOsC7N#e6V_QZ+Mtmvh>w!B2cOs&pMj0t}T{ZhAk8HA8p@gwlm^hwP zv0LmYm+MQzXA|)Qo+$1cnt?AUtGY67hb=DS$K5iy9YYztUv~^|;b^O7&aMjhR4`H( z#u+tUd%xknPvgAY)1KBI@sdKStqpb6bh#G0mcX3fxNT%Vix$c24=aBr#QNm0BvB0- z*d5{G(_;5pH3_@Q>Wr^=_Z!``tD0j;xgz}}9UUDVQX=NCuP?)+r2oNCfE)6%EKY*9 zLG(G5N2EKc()Qs7sF0fT9Zq~2u*&X84p5-5=yoYltW2$y5DTjIA`h7G++IxR72PR8 zb!82KxB8WpqLL6BzPhY6Gz7@U;ChOMz`BPH1fId^&)N@(76d^Ukj#nP9o zuV7CgfhJjr2g8GSUeu2zrjSGT$i4SQX%6w9UH3rCO;izF*Q#|hKboO76Za#I*+Spw z??p-qshyje4Sz{aEkCMrMHmB3Fb$~XOQ#*qkzL9$`kRcI6=+FNK;e780{`1bz1r%M z)5_2k=TjTM{pFdo|7TcwFfa^gW0s&qiv_#d0)e+HK6>nmk0xpC+v-LmxGPS+JL-wh zP@9Oe4FfJvzcB8m>iO+JorOA{*V+}e;|h1V3a1dhGuUv?>X2&ACiLeest3f_j)&T~ z-mmRV=MPEV3Dcw>f;F#?rDB5(-{;*(MRsOyag_EwNutO7q$ZL~VO|K+v^UO0$S;kA zo>1xEE>%;Lb9J&X9C37Sw)nz9)fBcN$tV{j<+>5B)oQ3QvA|M7aPqBh8G*w|=bJGL z=EBc1-k|I8cl24bSeBDP!nTsr9ih(6Maoci0$Njj}Wi|os9Qgt=hBFm-f8cvf@Ax63L!%JH2Tu@Sq&p z5rvONyOq;vdg04`hB3}-l^1z=c}bRFNag!kkVHa&{cT~wpsa#QGKVqvp7r;I?dzVR zI4V*3b0oIdSn8>w`*2;FqNm-_EI(`@elHj@$-{Vp6&lk61f{YEGA9s#1J1{0v+dkJ zEZ6v6W-M;$)ulDF!f@T(e9fHL_y!((cZTMDj_><#xLoR&bfei$IeTeIt>W}Y*GfSX zmw?`!O$y#QIUUv~H6PGnpQ{n zRp+gc&Xl?}#|&!G(;hqbd%9soKtWJenC;N^2we#iXbX8YIZ~dTy-g)$g!A!+{Dk*9 zPxl8s`d22t_gKzZAaniWFUbst0$_KMU0fGjuO9ESL`t2XCef=20;E(yU%+siu!B$uuIczA;`W z)5;fq_8&}c>q=HGE3qs1Ipnd>8<3XLo6Ey8ppHV0oRLU5G&m}8G=wPTH*88;xR*4y z@91h{I6!{4x#n|T1byF!Nt``kW|$>sSf3v{Y#eRzo;JU+IbSGQCkvd$PfBCu-ZOxV zXfT1NJf4Hrn69?i@G7PF?7QAbLVlYTp~8;&DYjdw*Ov%%21jF~JD0sP&%$x;D$@OP z10q|a{a|thaV@+l0j(FEICsmy@8ddUw((SwnUlTG7P)*w;%r8JPo%G9%}`J;>r_T# zZ}_n`9bO{C$EP6P#$B$vlVa$h9jV$cjLNg*!+!)NNrz+$3PGmt3BM4j<^-OQH)b1K zi7f>_lWjL&4A(wS@}Bt50p(dG>MiQZC8{I?@lRmfwr7$X61A2!i%Rw>lYumpAz)5t+`d_DQ`Rq)0!@A*v$Y+7+i(!&V4+i zljAAOoN!`0H<=36K+QD_78Q&)x2AqhY3d_Kq~zU&orfIhAfcTH7)16QA)LG2V=dcL z>*PZw^!a%4Eh3V6h{VbB{@#rmIPHn#$-?ys`W<$xONIlAovaT>1`eM}$O0YWd&&>Z zYd;cQ6ijiuWdx=#@n4Pa+$X&lU0_1a;glVgDm&5t!+^-ZsU1m0+Tkdl;S+F*Slv1-0^ z90mLIQA3Y7)z^}6Fd?8IS&5j1Tkg6WCz=%Q@kLdRNhGZFmsdGPo5e}F%1PAXAoBg% z?sS4X#_-<=#~M|&Qa7N1V2`s$^8=4(GbSnXX_FWZl@1}e5P78gr#Txl7XxC)epEm( zcdUwmf&?XqPeI|d;$1GuvV0Xs<>ao4=*GU2P4h#~6EFxDR6VXxn=+Y_d-Ar?(6(c3 zC`$b)U!ucFQzR=4B+Pv!Z!L1r-eo5#r}j59&sFaV&h(~%y4+g!~y3Jut@761Iw3dA;Bjwnrzd}q8sie? zT?|>IT)aQq3dq6Pq`#A~!>vpd$Pu}*0M?R5w#D^0e7c47z(cER@AJ3tvWywiL6P?I zS35b{xQ2w@?L6Qsw6l~uJf~rj^c|QU^bQT2=Xd;KA2IC?Z707uUo2(6chUI??iQW8 zSQXx8gbOHC-E|;?=|mCmG%I$(?t6Erz(5Sd>mjIa-))xmtCgVzIJRQ3^Hp z{g&8kp-YF_A|;`hoVhxw16>|}rBtz`htEG%56>sWU&K}pl- z(KnxMIf*=+wc}N13Pui_1^otkurYd>D9D`-hp?E9xr{M0?4bOY8Q>63TdZB7n$^dJ#ed*t8nPNh95g#_O{B% zgAKsO8XKv_L0tz}Q&fFfxu{eVLv?93<0W!yZ5cno!_$C?jZB1CZP#{(bX1^7tv&tD zOwE~sLgF1cN63H8a70_5^45FtvifzH9#?=nA_ORT+uz2PRyN1=nD?zk^>Xe``QdCO z!VORbs;RKua2q1KxuP)_XxJ8`SQFtd+gaI4jyNItM;o=>oVKvq1^^&`4d-gXlM*3Blt+k zWR;Me*A&`2`Kf{x7wcFzDw`&NJ%p^;olX8Mt+8)nitXVRbPDfxE&|w7q0kji! zNQeuQzA2Cy7O{5s_|$qx)xq8&v9o8QUlpmu79wQO$*kChr%n^7 zQ>MIQbqo$KBW-D7iQy>wq?yO#`4Nnje=Y5Lh zm`84}jiK)bheQz%QjATmL+Y5E`o^+zsmUxB`%X<=E{1|hCBynlL4Ls$RaRcdl`Eka z&tr~&)4}HfuiRF5?){A7K-}3qR-5~+L0SGE(e|&wjcEtAl%fGhEL-z&Ks}NRY+4Y0 zk@%I@2KoJ`3a_$l&zmQEHs@2>vORX4d8c94m^yRJbk<2WLi&%J-~gc&xjmG;Rpd0D z+t-jchtg`ht5>L59N(9%v83fM0&xy3{6snyW&X@gm|Zv!fD|cFj`xUQwJ|9NRsbl~ z;uSXNx{vH)p^wl21T}^71XZ2)6&uGWP$}t&JTH$D_MGFq1Ca!Nl0k~b$4}Eu7_K+$ zbfZ!l0t`osNgSHS?Pw5{t1dffR67XRh@Du3+A`^cX(NZUrRq+RRDoIskcqp9>RiKn zG*9>1_!%D0Lb6wyPDji@05S=CkkIlaB;6=O=20HkbMvFi(G}~ES4jRqVAuycC7Y+K zneF6ltDg^e?!-9KTmsK0=?|MrXD0*S722x911$A=K>{GFwhNpS=QAav8%s@+MTOCL zIt+?2IklIy&@dU)p<~`((_6f#J$&h`YUDF)EmMhx!X=j2@52KcaFGbyIDj74#&z8# z=plW&Ua%T3R-x;0krd3VhfZ~~MCc*qdG3tKK7l;RW}R=jx^_Mho4x=R@25ACo9dC! zP`60$>G7TLH=;oU`s*0lTj~b6lx%^ppK#|;r`^SfG;5vOK*OZWZ2EY(!M8em8aYOtgP+D^CW`FwoaO_Mv!s6 zSS`~B@b-TFk=bFRtI;lAgWsRe7YfYE8^p7-_cxuc2-V6(B90l1j!z)xrvbo4V&vKx zO4lfx?tZ?Px#ZV3yIDSlz~$W5HmAc_E?gTj-Fg_#Wo+OiDlrh*4QCo`_%rL5cOv1# z2LNE_;UZn3p(q6$S$LU-W|1<5HnL-yhv0uhW>RoWOiX3R6rc`vrLv24**V92p-zhX z=~AKRjvXi*4j*szaLc$z^6^fAa7}j$uVF6)m9TaQyI?#ml>@ZB?MB#)g#FWfHfuEZ zX}K52vZU)w8U(xZ!WpL*`29n(q1uRA_u>PML&M^JTT>xEyoGvssD6(37P_YUNNk`D%G|2SYQ>WC5EE%Tn2D`Y`gB?{_PE)eMJ| zX=XIN?1uXSo*OGlU|QB7XL-d<8~5zPV+M12asjM}tW;byS)x_=in)psU_n+reV*RJ zOPIU+HYl7YqL~*6h%1rH1b(=|V^jb75C0WQ?E^H07YDd(*qVtMO{X;X+qEFbBEL8! za&e!AZPGTXptlLo3ziv%N-wuLH-`zFgtGWP7~L)8bgh@Bt^4mEPW@~L3Xty96XFo9 zkyqXA<)K$hidhb;9Ltu(S|6Z0oKEH#ArQ&Mz_UWx*?dgxwg=%ptqP|U3P=PntO_3h z_9-uQV#C}6OIEGYHVz=}*)k0TDrF<8n+7~?mQg~Az>9J`TU;3|_VwGqSizJOA%1mB zVBaOEw`DO~`?+Ys>X5|U;?{@reI?%RjNfDF?%TvxgHZf0qjFn^R|8|+8W2{U;RUyZ>Fn?S9hrph z&D#s%nz#~T)l6`k`Qb_PDynk0qavWhMo}>v!m`C6H+8yDZ}efY^gzvaXsW|cD*_Gi zl&t-3S0>2ix8Lbf!l(AN%#((-HKqu%krc3bMaPt+>PxXA^Fol=1>1bMWOz9Bvllg{ zS_jzjC)%p*P8=(xXI=jJY4mk=A;X2nbcrSvu;*2HF|ancY!^y%uy+DnbpaD)@G~Dz ze5y!^U(=zofQ}*i8SHCc6TVn@Vpcvma67yhJG&Vi|NAO%RME&W)-`x2~L>l(JfZK_NHw|}=%zXPM#rnjYqBC_b7 z<9@kz%fA#jv;Fy@Mv)>)otaV$AR=;=uljYh#EbR{mOmtXaZuDqBDf~$^%3Zcw!i&~ z_SLTDHlk{0euJ+A@UYHcIF#bA%`dS)Geun6$+eaPxCdByGYo0@GmY%bMf#ctgUmA8 z3cqu@zp%|BiERI)(NWghlLWf9M0~E1qqSw zaOcsA_Uh2h$&3gS&6k~FBh>mb6eXZ?KfnK5Mr(qKmWL*(=b6&z5D>(Ij7Ou&87@Nx zHg)ZurP9w!o1gDfkgF}4%7y%rJ)hgb&R6|z?w&^EWzhorei}&TrMNm2se^rj7AwrV zU{`|A$F5`$IOIu0C3Wkw1m=zy@@RXqI9k8hR>&4eJq`vLN$yZDUt)YsPa6mv|CS#> zrWpk?y=>iZbR_rK;Vn)Hl}6OZXLit}|AM74uq*{BdO8ks-> z*me%&XV41-XiN83RlvSWbG2p(yO%LCmLwMH8Pq^lkNVJ1mIplk)eaFE_%BkJ_Y*Yg zLuLw48UEIR^9}0wsJtT)Qvum%<_Aq9pvp)H*FI-qN_5@r`9!+mB78yrc+o{Uvd?Kn zW=4%KPDe$HfJkJKxKuq2b<)*RvtBHwo8dUXsB|q;%Y84-yPA9t=as97xE2VgJF=ZR zrP}JxN*E}aYwOprYC)O2)14{TI|X_H{A%p)!9R@GgwwSq7nEA0)DnG_-*!Th(w@>m zVPd#j_>Sro8PP_;m1tecx;2vt5jcrJW=(L}m^W67re>w6US%6PLydIaI1KfEG|ZAZEFL8wzp=@uVh6 zNmeFEuqdFjNdI){$10~0t+^JXh{NTyE0qSI@$a2VHx@&YPRAQ$92}als{>${kXl$8 zvq+8bpk*86Caa7?Aa)1ZOIs4YI1K>1p@M*247#&g(Tpc5bObIM)mu~CH${^>ySw{w z^~$bJn7jbxO4TC~AtCjSdaY^7WK}J3ku(k?r#jiOXWw@gD#G8{oZmmy-|R4IU3(E+ zQ;Ad!2SsBAtI!khzwOXy_`BQw=hZg<#l-wJq5jPWelrAABXs#j-!ec+Sow^%8hw2G zZw~w0g#4E;Qh}3g-N9ClfOpkuTlCBJB6gXEN~nWU#r!FT>QYL(jQAp0~B1x7sU;TrKu|sGn{vJ=HqZUO3KSK5;HSv zjx$_xqO;|_$o`3`z(0f(S9?MO5d#UaSUL;>w0;rMLV2>hHi-urWaJ1@e)*!@Jdl`h z_s22McQAhgZ7o{D!tqhIQAqN&;x5G}H-cU75+w?-#rrCr$lIwSWA2^l8868jXkz+$Dl0Pt(QJcFz`3p2$`Y5Z+o;=nkB;_WJ z%$qOfpOr_Y6fJx$!v*3QFj(z;7;R{hl9HkgeZMoU0*QmF@mxMQ3Y9wJ^~uZ7;y2$& zaJdP|wu>)pkkbDIe0p<0)Fc#(gKXuy7MVUP;`Cr9i5O_RM|a|hI=%%j{pEOI@MWuo zg$fm_s{|9@`(~3T<*hhb=_Vh_NYb4}!OWj%7K`UjmdZ~P|A5NSI<0_doWn>UZn_~6 z?ShF?ZVzjf6HkHq0(Z+LC)Xx)COmY)qI*N4RxCVKn7Tsw(~&DoXu`TChxA^!O%j(a znxKzjPrh6lEx1S%BzwbgC7RcXCwUFzD>Ul9LF0y2WYZH#qJEL{2&SD(%eDQJ1>LK_ zYc)P)4z;)EnqwW93o=kYFn*JYHAShKWOZJW`wAA&aKuf`=(_<1bnfZq!BFg2x z^FW8Jpy@4QE>fcI-7g8{orN{lF4y8=tj(AqJ{lE#JHL`*SO!wR#G0?rQi{3DbI(#I z&NCDre2%RcF-D=z?p|OjQ{pR%r$ad`D*Mb0sDxO$4p}=+bJe0+lEVaFqd?W1c?~1k zZ>;pBn`y_E!dCThD^&8cnJm}madG5EB*%Xo%QcvkpN9xjDpy~=KgSvmlg0d#Km}F8 z$37@@Ba=h?;$(0FvF9Ef7lOJJIlRc{}mxdVLfoRdzR7k+8<3I2^0O zLDfZ?)r4TI1S)y_fBdpS%DoK}$DUswiHt@^CYl=TBV6I)Fr|$)s;mhiSvolDuP0VOi3zHOD3A2nHB*)J_iP@gYD)alxvTT2`eFNnAy^pzKN#A}` zvZ3qZ-X$GwM!HVo3EQMmVTopP?0WiUZ}Y(H7M-rAR2&=gWO$pe%9yHF(2o=Yf8L&j zTFm~GU9y00O|94nY;XKWBhPyaW&GlEO*HGndX_grIQ1?CxhOg{nU>>5f62WBXF^Ge z6z86rA0)vAg>Ov=d8w}4AkS8)(NsltYS@$Rr~D>Www7wIS8fg+@18eZwsyqg>X2U9 zR5?|m5}|R zJNEaLEB_Lcdh_^D8rG8?sf-?1Zf=gk=^%gC4vM|cAIXjkEIa?MJ@`v?4x_;<@~Kd- zDo|}k)($C*CovA20Cgcu0%qyz6Y7zT8;;>79mTO>7yIruP@|=v_>l_eP^Sm?vT=

?@yU2qrxNW=3Rx^dqCu=RjZd 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

3|vASo&5W&L!ul^yUK%UYk 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%0AEL5mvm9i=Tm4 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

7*wTdYWDQ{7oBcM{1WLp@idMhCKO`AWlW}= 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ॢKg7}DpMc4f8u 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 literal 0 HcmV?d00001 diff --git a/docs/user/alerting/index.asciidoc b/docs/user/alerting/index.asciidoc index b2b2082ce71f7..b86a9296c57ed 100644 --- a/docs/user/alerting/index.asciidoc +++ b/docs/user/alerting/index.asciidoc @@ -1,6 +1,7 @@ include::alerting-getting-started.asciidoc[] include::alerting-setup.asciidoc[] include::create-and-manage-rules.asciidoc[] +include::view-alerts.asciidoc[] include::rule-types.asciidoc[] include::action-variables.asciidoc[] include::alerting-troubleshooting.asciidoc[] diff --git a/docs/user/alerting/view-alerts.asciidoc b/docs/user/alerting/view-alerts.asciidoc new file mode 100644 index 0000000000000..745016f26a0af --- /dev/null +++ b/docs/user/alerting/view-alerts.asciidoc @@ -0,0 +1,83 @@ +[[view-alerts]] +== View alerts +:frontmatter-description: View and manage alerts in the {kib} {stack-manage-app} app. +:frontmatter-tags-products: [kibana, alerting] +:frontmatter-tags-content-type: [how-to] +:frontmatter-tags-user-goals: [manage] + +When the conditions of a rule are met, it creates an alert. +If the rule has actions, they run at the defined frequency. +For example, the rule can send email notifications for each alert at a custom interval. +For an introduction to the concepts of rules, alerts, and actions, refer to <>. + +You can manage the alerts for each rule in *{stack-manage-app}* > *{rules-ui}*. +Alternatively, manage all your alerts in *{stack-manage-app}* > *Alerts*. preview:[] + +[role="screenshot"] +image::images/stack-management-alerts-page.png[Alerts page with multiple alerts] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. + +[NOTE] +==== +You must have the appropriate {kib} {alert-features} and index privileges to view alerts. +Refer to <>. +==== + +[discrete] +[[filter-alerts]] +=== Filter alerts + +preview::[] + +In *{stack-manage-app}* > *Alerts*, you can filter the list (for example, by alert status or rule type) and customize the filter controls. +To search for specific alerts, use the KQL bar to create structured queries using {kibana-ref}/kuery-query.html[{kib} Query Language]. + +By default, the list contains all the alerts that you have authority to view in the selected time period except those associated with Security rules. +To view alerts for Security rules, click the query menu and select *Security rule types*: + +[role="screenshot"] +image::images/stack-management-alerts-query-menu.png[The Alerts page with the query menu open] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. + +Alternatively, view those alerts in the {security-guide}/alerts-ui-manage.html[{security-app}]. + +[discrete] +[[view-alert-details]] +=== View alert details + +To get more information about a specific alert, open its action menu (…) and select *View alert details* in either *{stack-manage-app} > Alerts* or *{rules-ui}*. +There you'll see the current status of the alert, its duration, and when it was last updated. +To help you determine what caused the alert, there is information such as the expected and actual threshold values and a summarized reason for the alert. + +If an alert is affected by a maintenance window, the alert details include its identifier. +For more information about their impact on alert notifications, refer to <>. + +[discrete] +[[alert-status]] +==== Alert statuses + +There are three common alert statuses: + +`active`:: The conditions for the rule are met and actions should be generated according to the notification settings. +`recovered`:: The conditions for the rule are no longer met and recovery actions should be generated. +`untracked`:: Actions are no longer generated. For example, you can choose to move active alerts to this state when you disable or delete rules. + +[NOTE] +==== +An alert can also be in a "flapping" state when it is switching repeatedly between active and recovered states. +This state is possible only if you have enabled alert flapping detection in *{stack-manage-app} > {rules-ui} > Settings*. +For each space, you can choose a look back window and threshold that are used to determine whether alerts are flapping. +For example, you can specify that the alert must change status at least 6 times in the last 10 runs. +If the rule has actions that run when the alert status changes, those actions are suppressed while the alert is flapping. +==== + + +[discrete] +[[mute-alerts]] +=== Mute alerts + +If an alert is active or flapping, you can mute it to temporarily suppress future actions. +In both *{stack-manage-app} > Alerts* and *{rules-ui}*, you can open the action menu (…) for the appropriate alert and select *Mute*. +To permanently suppress actions for an alert, open the actions menu and select *Mark as untracked*. + +To affect the behavior of the rule rather than individual alerts, check out <>. diff --git a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_alerting/list_view.ts b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_alerting/list_view.ts index 30f3a2c87dfd7..6903ac026cd81 100644 --- a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_alerting/list_view.ts +++ b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_alerting/list_view.ts @@ -58,5 +58,30 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 1024 ); }); + + it('alerts UI screenshots', async () => { + await pageObjects.common.navigateToUrl( + 'management', + 'insightsAndAlerting/triggersActionsAlerts', + { + shouldUseHashForSubUrl: false, + } + ); + await pageObjects.header.waitUntilLoadingHasFinished(); + await commonScreenshots.takeScreenshot( + 'stack-management-alerts-page', + screenshotDirectories, + 1400, + 1024 + ); + const queryMenu = await testSubjects.find('showQueryBarMenu'); + await queryMenu.click(); + await commonScreenshots.takeScreenshot( + 'stack-management-alerts-query-menu', + screenshotDirectories, + 1400, + 1024 + ); + }); }); } From 43ce965668eaad627092cd85649610566e8c9353 Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:24:57 -0700 Subject: [PATCH 021/122] [Response Ops][Rule Form V2] Rule Form V2: Rule Details (#183352) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Issue: https://github.com/elastic/kibana/issues/179105 Related PR: https://github.com/elastic/kibana/pull/180539 Part 1: https://github.com/elastic/kibana/pull/183325 Part 2 of 3 PRs of new rule form. This PR depends on the code from part 1, so only merge this when part 1 has been merged. This PR extracts the last section of the rule form, the rule details, from the original PR. The design philosophy in the PR is to create components that are devoid of any fetching or form logic. These are simply dumb components. I have also created a example plugin to demonstrate this PR. To access: 1. Run the branch with yarn start --run-examples 2. Navigate to http://localhost:5601/app/triggersActionsUiExample/rule_details And you should be able to play around with the components in this PR: Screenshot 2024-05-13 at 9 44 14 PM ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Zacqary Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../src/rule_form/index.ts | 2 + .../src/rule_form/rule_actions/index.ts | 9 ++ .../rule_actions/rule_actions.test.tsx | 33 +++++ .../rule_form/rule_actions/rule_actions.tsx | 31 +++++ .../src/rule_form/rule_details/index.ts | 9 ++ .../rule_details/rule_details.test.tsx | 79 ++++++++++++ .../rule_form/rule_details/rule_details.tsx | 117 ++++++++++++++++++ .../src/rule_form/translations.ts | 29 +++++ .../public/application.tsx | 18 +++ .../rule_form/rule_actions_sandbox.tsx | 13 ++ .../rule_form/rule_details_sandbox.tsx | 36 ++++++ .../public/components/sidebar.tsx | 10 ++ 12 files changed, 386 insertions(+) create mode 100644 packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/index.ts create mode 100644 packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.test.tsx create mode 100644 packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.tsx create mode 100644 packages/kbn-alerts-ui-shared/src/rule_form/rule_details/index.ts create mode 100644 packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.test.tsx create mode 100644 packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.tsx create mode 100644 x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_actions_sandbox.tsx create mode 100644 x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_details_sandbox.tsx diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/index.ts b/packages/kbn-alerts-ui-shared/src/rule_form/index.ts index dbdcd4efa464f..3751b1848d23e 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_form/index.ts +++ b/packages/kbn-alerts-ui-shared/src/rule_form/index.ts @@ -7,5 +7,7 @@ */ export * from './rule_definition'; +export * from './rule_actions'; +export * from './rule_details'; export * from './utils'; export * from './types'; diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/index.ts b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/index.ts new file mode 100644 index 0000000000000..bd84316ee7e2d --- /dev/null +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/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 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 * from './rule_actions'; diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.test.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.test.tsx new file mode 100644 index 0000000000000..19f1482072fd9 --- /dev/null +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.test.tsx @@ -0,0 +1,33 @@ +/* + * 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 React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { RuleActions } from './rule_actions'; + +const mockOnChange = jest.fn(); + +describe('Rule actions', () => { + afterEach(() => { + jest.resetAllMocks(); + }); + + test('Renders correctly', () => { + render(); + + expect(screen.getByTestId('ruleActions')).toBeInTheDocument(); + }); + + test('Calls onChange when button is click', () => { + render(); + + fireEvent.click(screen.getByTestId('ruleActionsAddActionButton')); + + expect(mockOnChange).toHaveBeenCalled(); + }); +}); diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.tsx new file mode 100644 index 0000000000000..f49cd85bbe12f --- /dev/null +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions.tsx @@ -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 React from 'react'; +import { EuiButton } from '@elastic/eui'; +import { ADD_ACTION_TEXT } from '../translations'; + +export interface RuleActionsProps { + onClick: () => void; +} + +export const RuleActions = (props: RuleActionsProps) => { + const { onClick } = props; + return ( +

+ ); +}; diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/index.ts b/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/index.ts new file mode 100644 index 0000000000000..a38da3214a07d --- /dev/null +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/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 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 * from './rule_details'; diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.test.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.test.tsx new file mode 100644 index 0000000000000..58b327af94b47 --- /dev/null +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.test.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 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 React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { RuleDetails } from './rule_details'; + +const mockOnChange = jest.fn(); + +describe('RuleDetails', () => { + test('Renders correctly', () => { + render( + + ); + + expect(screen.getByTestId('ruleDetails')).toBeInTheDocument(); + }); + + test('Should allow name to be changed', () => { + render( + + ); + + fireEvent.change(screen.getByTestId('ruleDetailsNameInput'), { target: { value: 'hello' } }); + expect(mockOnChange).toHaveBeenCalledWith('name', 'hello'); + }); + + test('Should allow tags to be changed', () => { + render( + + ); + + userEvent.type(screen.getByTestId('comboBoxInput'), 'tag{enter}'); + expect(mockOnChange).toHaveBeenCalledWith('tags', ['tag']); + }); + + test('Should display error', () => { + render( + + ); + + expect(screen.getByText('name is invalid')).toBeInTheDocument(); + expect(screen.getByText('tags is invalid')).toBeInTheDocument(); + }); +}); diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.tsx new file mode 100644 index 0000000000000..a2cd9b6b02bcf --- /dev/null +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_details/rule_details.tsx @@ -0,0 +1,117 @@ +/* + * 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 React, { useCallback, useMemo } from 'react'; +import { + EuiDescribedFormGroup, + EuiFormRow, + EuiFieldText, + EuiComboBox, + EuiComboBoxOptionOption, + EuiText, +} from '@elastic/eui'; +import type { SanitizedRule, RuleTypeParams } from '@kbn/alerting-types'; +import type { RuleFormErrors } from '../types'; +import { + RULE_DETAILS_TITLE, + RULE_DETAILS_DESCRIPTION, + RULE_NAME_INPUT_TITLE, + RULE_TAG_INPUT_TITLE, +} from '../translations'; + +export interface RuleDetailsProps { + formValues: { + tags?: SanitizedRule['tags']; + name: SanitizedRule['name']; + }; + errors?: RuleFormErrors; + onChange: (property: string, value: unknown) => void; +} + +export const RuleDetails = (props: RuleDetailsProps) => { + const { formValues, errors = {}, onChange } = props; + + const { tags = [], name } = formValues; + + const tagsOptions = useMemo(() => { + return tags.map((tag: string) => ({ label: tag })); + }, [tags]); + + const onNameChange = useCallback( + (e: React.ChangeEvent) => { + onChange('name', e.target.value); + }, + [onChange] + ); + + const onAddTag = useCallback( + (searchValue: string) => { + onChange('tags', tags.concat([searchValue])); + }, + [onChange, tags] + ); + + const onSetTag = useCallback( + (options: Array>) => { + onChange( + 'tags', + options.map((selectedOption) => selectedOption.label) + ); + }, + [onChange] + ); + + const onBlur = useCallback(() => { + if (!tags) { + onChange('tags', []); + } + }, [onChange, tags]); + + return ( + {RULE_DETAILS_TITLE}} + description={ + +

{RULE_DETAILS_DESCRIPTION}

+
+ } + data-test-subj="ruleDetails" + > + 0} + error={errors.name} + > + + + 0} + error={errors.tags} + > + + +
+ ); +}; diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/translations.ts b/packages/kbn-alerts-ui-shared/src/rule_form/translations.ts index 4ae1cbfd206c4..d9c86b60e7d9f 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_form/translations.ts +++ b/packages/kbn-alerts-ui-shared/src/rule_form/translations.ts @@ -194,3 +194,32 @@ export const INTERVAL_WARNING_TEXT = (minimum: string) => 'Intervals less than {minimum} are not recommended due to performance considerations.', values: { minimum }, }); + +export const ADD_ACTION_TEXT = i18n.translate('alertsUIShared.ruleForm.ruleActions.addActionText', { + defaultMessage: 'Add action', +}); + +export const RULE_DETAILS_TITLE = i18n.translate('alertsUIShared.ruleForm.ruleDetails.title', { + defaultMessage: 'Rule name and tags', +}); + +export const RULE_DETAILS_DESCRIPTION = i18n.translate( + 'alertsUIShared.ruleForm.ruleDetails.description', + { + defaultMessage: 'Define a name and tags for your rule.', + } +); + +export const RULE_NAME_INPUT_TITLE = i18n.translate( + 'alertsUIShared.ruleForm.ruleDetails.ruleNameInputTitle', + { + defaultMessage: 'Rule name', + } +); + +export const RULE_TAG_INPUT_TITLE = i18n.translate( + 'alertsUIShared.ruleForm.ruleDetails.ruleTagsInputTitle', + { + defaultMessage: 'Tags', + } +); diff --git a/x-pack/examples/triggers_actions_ui_example/public/application.tsx b/x-pack/examples/triggers_actions_ui_example/public/application.tsx index 6b1dfe98c22b2..b605a1245ab8d 100644 --- a/x-pack/examples/triggers_actions_ui_example/public/application.tsx +++ b/x-pack/examples/triggers_actions_ui_example/public/application.tsx @@ -39,6 +39,8 @@ import { AlertsTableSandbox } from './components/alerts_table_sandbox'; import { RulesSettingsLinkSandbox } from './components/rules_settings_link_sandbox'; import { RuleDefinitionSandbox } from './components/rule_form/rule_definition_sandbox'; +import { RuleActionsSandbox } from './components/rule_form/rule_actions_sandbox'; +import { RuleDetailsSandbox } from './components/rule_form/rule_details_sandbox'; export interface TriggersActionsUiExampleComponentParams { http: CoreStart['http']; @@ -174,6 +176,22 @@ const TriggersActionsUiExampleApp = ({ )} /> + ( + + + + )} + /> + ( + + + + )} + /> ); diff --git a/x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_actions_sandbox.tsx b/x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_actions_sandbox.tsx new file mode 100644 index 0000000000000..3114bad2a56bb --- /dev/null +++ b/x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_actions_sandbox.tsx @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { RuleActions } from '@kbn/alerts-ui-shared/src/rule_form'; + +export const RuleActionsSandbox = () => { + return {}} />; +}; diff --git a/x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_details_sandbox.tsx b/x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_details_sandbox.tsx new file mode 100644 index 0000000000000..6c1b83d79f46c --- /dev/null +++ b/x-pack/examples/triggers_actions_ui_example/public/components/rule_form/rule_details_sandbox.tsx @@ -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 React, { useState, useCallback } from 'react'; +import { RuleDetails } from '@kbn/alerts-ui-shared/src/rule_form'; +import { EuiCodeBlock, EuiTitle } from '@elastic/eui'; + +export const RuleDetailsSandbox = () => { + const [formValues, setFormValues] = useState({ + tags: [], + name: 'test-rule', + }); + + const onChange = useCallback((property: string, value: unknown) => { + setFormValues((prevFormValues) => ({ + ...prevFormValues, + [property]: value, + })); + }, []); + + return ( + <> +
+ +

Form State

+
+ {JSON.stringify(formValues, null, 2)} +
+ + + ); +}; diff --git a/x-pack/examples/triggers_actions_ui_example/public/components/sidebar.tsx b/x-pack/examples/triggers_actions_ui_example/public/components/sidebar.tsx index caaad858b4cc4..a6dd96190574b 100644 --- a/x-pack/examples/triggers_actions_ui_example/public/components/sidebar.tsx +++ b/x-pack/examples/triggers_actions_ui_example/public/components/sidebar.tsx @@ -85,6 +85,16 @@ export const Sidebar = () => { name: 'Rule Definition', onClick: () => history.push('/rule_definition'), }, + { + id: 'rule-actions', + name: 'Rule Actions', + onClick: () => history.push('/rule_actions'), + }, + { + id: 'rule-details', + name: 'Rule Details', + onClick: () => history.push('/rule_details'), + }, ], }, ]} From 60efc932c37520abb06d4546a2af468b762f77a8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:44:08 -0700 Subject: [PATCH 022/122] Update dependency @elastic/charts to v65.2.0 (main) (#184771) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c97e0fb4cb77b..ed541c789626d 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "@elastic/apm-rum": "^5.16.0", "@elastic/apm-rum-core": "^5.21.0", "@elastic/apm-rum-react": "^2.0.2", - "@elastic/charts": "65.1.0", + "@elastic/charts": "65.2.0", "@elastic/datemath": "5.0.3", "@elastic/ecs": "^8.11.1", "@elastic/elasticsearch": "^8.13.0", diff --git a/yarn.lock b/yarn.lock index 5187eec56835b..4f691866a05af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1650,10 +1650,10 @@ dependencies: object-hash "^1.3.0" -"@elastic/charts@65.1.0": - version "65.1.0" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-65.1.0.tgz#ff0c7f71ce7da76472813c9bf5cd3ec16df887ae" - integrity sha512-rIvsoCZH6YUb+w3dqelp8geujEMwdiJLuxi/Y+9UVJm+7QrhkK4uob7QEFgPv79p2NeBngZIyetZCYGEE3FMzw== +"@elastic/charts@65.2.0": + version "65.2.0" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-65.2.0.tgz#203496b6471e4845807cb70c48b0990676882ef4" + integrity sha512-yeqascGqvnDABvtYOHgd7sr6cEq5kivFWKaS3UWeb/GpOxk+O4Ef1PlbBxpchgDyInP957SWlhKDmhUFF1Ttzg== dependencies: "@popperjs/core" "^2.11.8" bezier-easing "^2.1.0" From 6c10fc0925a283b119de3648ad6c50523e3e7540 Mon Sep 17 00:00:00 2001 From: seanrathier Date: Wed, 5 Jun 2024 21:56:31 -0400 Subject: [PATCH 023/122] [Cloud Security] [Findings Phase 2] Add create detection rule to the CloudSecurityDataTable (#184058) --- .../cloud_security_data_table.test.tsx | 64 +++++++++++++------ .../cloud_security_data_table.tsx | 31 ++++++++- .../public/components/take_action.tsx | 16 ++++- .../latest_findings/latest_findings_table.tsx | 17 ++++- .../latest_vulnerabilities_table.tsx | 20 +++++- 5 files changed, 124 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx index 0fba4f27ed23a..9e5e8fa67058f 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.test.tsx @@ -46,22 +46,39 @@ const mockCloudPostureDataTable = { getRowsFromPages: jest.fn(), } as any; +const mockRows = [ + { + id: '1', + raw: { + field1: 'Label 1', + field2: 'Label 2', + }, + flattened: { + field1: 'Label 1', + field2: 'Label 2', + }, + }, +] as any; + const renderDataTable = (props: Partial = {}) => { const defaultProps: CloudSecurityDataTableProps = { isLoading: false, defaultColumns: mockDefaultColumns, - rows: [], + rows: props.rows || mockRows, total: 0, flyoutComponent: () => <>, cloudPostureDataTable: mockCloudPostureDataTable, loadMore: jest.fn(), + createRuleFn: jest.fn(), title: 'Test Table', }; + const propsWithDefaults = { ...defaultProps, ...props }; + return render( - + ); @@ -69,31 +86,17 @@ const renderDataTable = (props: Partial = {}) => { describe('CloudSecurityDataTable', () => { it('renders loading state', () => { - const { getByTestId } = renderDataTable({ isLoading: true }); + const { getByTestId } = renderDataTable({ isLoading: true, rows: [] }); expect(getByTestId('unifiedDataTableLoading')).toBeInTheDocument(); }); it('renders empty state when no rows are present', () => { - const { getByTestId } = renderDataTable(); + const { getByTestId } = renderDataTable({ rows: [] }); expect(getByTestId('csp:empty-state')).toBeInTheDocument(); }); it('renders data table with rows', async () => { - const mockRows = [ - { - id: '1', - raw: { - field1: 'Label 1', - field2: 'Label 2', - }, - flattened: { - field1: 'Label 1', - field2: 'Label 2', - }, - }, - ] as any; const { getByTestId, getByText } = renderDataTable({ - rows: mockRows, total: mockRows.length, }); @@ -101,4 +104,29 @@ describe('CloudSecurityDataTable', () => { expect(getByText('Label 1')).toBeInTheDocument(); expect(getByText('Label 2')).toBeInTheDocument(); }); + + it('renders data table with actions button', async () => { + const { getByRole } = renderDataTable({ + rows: mockRows, + total: mockRows.length, + }); + + const showActions = getByRole('button', { + name: 'More actions', + }); + + expect(showActions).toBeInTheDocument(); + }); + + it('renders data table without actions button', async () => { + const { queryByRole } = renderDataTable({ + createRuleFn: undefined, + rows: mockRows, + total: mockRows.length, + }); + const showActions = queryByRole('button', { + name: 'More actions', + }); + expect(showActions).toBeNull(); + }); }); diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.tsx b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.tsx index 5ec9ef01cb767..623de8401810c 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_data_table/cloud_security_data_table.tsx @@ -8,9 +8,15 @@ import React, { useState, useMemo } from 'react'; import { UnifiedDataTableSettings, useColumns } from '@kbn/unified-data-table'; import { UnifiedDataTable, DataLoadingState } from '@kbn/unified-data-table'; import { CellActionsProvider } from '@kbn/cell-actions'; +import { HttpSetup } from '@kbn/core-http-browser'; import { SHOW_MULTIFIELDS, SORT_DEFAULT_ORDER_SETTING } from '@kbn/discover-utils'; import { DataTableRecord } from '@kbn/discover-utils/types'; -import { EuiDataGridCellValueElementProps, EuiDataGridStyle, EuiProgress } from '@elastic/eui'; +import { + EuiDataGridCellValueElementProps, + EuiDataGridControlColumn, + EuiDataGridStyle, + EuiProgress, +} from '@elastic/eui'; import { AddFieldFilterHandler } from '@kbn/unified-field-list'; import { generateFilters } from '@kbn/data-plugin/public'; import { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; @@ -22,7 +28,9 @@ import { MAX_FINDINGS_TO_LOAD } from '../../common/constants'; import { useStyles } from './use_styles'; import { AdditionalControls } from './additional_controls'; import { useDataViewContext } from '../../common/contexts/data_view_context'; +import { TakeAction } from '../take_action'; +import { RuleResponse } from '../../common/types'; export interface CloudSecurityDefaultColumn { id: string; width?: number; @@ -77,6 +85,11 @@ export interface CloudSecurityDataTableProps { * Height override for the data grid. */ height?: number | string; + + /** + * This function will be used in the control column to create a rule for a specific finding. + */ + createRuleFn?: (rowIndex: number) => ((http: HttpSetup) => Promise) | undefined; /* Optional props passed to Columns to display Provided Labels as Column name instead of field name */ columnHeaders?: Record; /** @@ -97,6 +110,7 @@ export const CloudSecurityDataTable = ({ customCellRenderer, groupSelectorComponent, height, + createRuleFn, columnHeaders, hasDistributionBar = true, ...rest @@ -266,6 +280,20 @@ export const CloudSecurityDataTable = ({ /> ); + const externalControlColumns: EuiDataGridControlColumn[] | undefined = createRuleFn + ? [ + { + id: 'select', + width: 20, + headerCellRender: () => null, + rowCellRender: ({ rowIndex }) => + createRuleFn && ( + + ), + }, + ] + : undefined; + const rowHeightState = 0; const loadingStyle = { @@ -312,6 +340,7 @@ export const CloudSecurityDataTable = ({ showTimeCol={false} settings={settings} onFetchMoreRecords={loadMore} + externalControlColumns={externalControlColumns} externalCustomRenderers={externalCustomRenderers} externalAdditionalControls={externalAdditionalControls} gridStyleOverride={gridStyle} diff --git a/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx b/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx index a11459194036e..87d6d109b7db0 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx @@ -8,6 +8,7 @@ import React, { useState } from 'react'; import { EuiButton, + EuiButtonIcon, EuiContextMenuItem, EuiContextMenuPanel, EuiFlexGroup, @@ -19,6 +20,7 @@ import { import { toMountPoint } from '@kbn/react-kibana-mount'; import type { HttpSetup } from '@kbn/core/public'; import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n as kbnI18n } from '@kbn/i18n'; import { QueryClient, useQueryClient } from '@tanstack/react-query'; import type { RuleResponse } from '../common/types'; import { CREATE_RULE_ACTION_SUBJ, TAKE_ACTION_SUBJ } from './test_subjects'; @@ -33,6 +35,7 @@ interface TakeActionProps { enableBenchmarkRuleFn?: () => Promise; disableBenchmarkRuleFn?: () => Promise; isCreateDetectionRuleDisabled?: boolean; + isDataGridControlColumn?: boolean; } export const showCreateDetectionRuleSuccessToast = ( @@ -170,6 +173,7 @@ export const TakeAction = ({ enableBenchmarkRuleFn, disableBenchmarkRuleFn, isCreateDetectionRuleDisabled = false, + isDataGridControlColumn: isDataTableAction = false, }: TakeActionProps) => { const queryClient = useQueryClient(); const [isPopoverOpen, setPopoverOpen] = useState(false); @@ -182,7 +186,7 @@ export const TakeAction = ({ prefix: 'smallContextMenuPopover', }); - const button = ( + const button = !isDataTableAction ? ( + ) : ( + setPopoverOpen(!isPopoverOpen)} + /> ); const actionsItems = []; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_table.tsx index 7207c47cc0029..a93907825bc7d 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_table.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { Filter } from '@kbn/es-query'; import { DataTableRecord } from '@kbn/discover-utils/types'; +import { HttpSetup } from '@kbn/core-http-browser'; import { i18n } from '@kbn/i18n'; import { EuiDataGridCellValueElementProps, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import * as TEST_SUBJECTS from '../test_subjects'; @@ -20,6 +21,7 @@ import { TimestampTableCell } from '../../../components/timestamp_table_cell'; import { CspEvaluationBadge } from '../../../components/csp_evaluation_badge'; import { CspFinding } from '../../../../common/schemas/csp_finding'; import { FindingsRuleFlyout } from '../findings_flyout/findings_flyout'; +import { createDetectionRuleFromBenchmarkRule } from '../utils/create_detection_rule_from_benchmark'; import { findingsTableFieldLabels } from './findings_table_field_labels'; interface LatestFindingsTableProps { @@ -35,6 +37,10 @@ const isCspFinding = (source: Record | undefined): source is CspFin return source?.result?.evaluation !== undefined; }; +const getCspFinding = (source: Record | undefined): CspFinding | false => { + return isCspFinding(source) && (source as CspFinding); +}; + /** * This Wrapper component renders the children if the given row is a CspFinding * it uses React's Render Props pattern @@ -46,8 +52,7 @@ const CspFindingRenderer = ({ row: DataTableRecord; children: ({ finding }: { finding: CspFinding }) => JSX.Element; }) => { - const source = row.raw._source; - const finding = isCspFinding(source) && (source as CspFinding); + const finding = getCspFinding(row.raw._source); if (!finding) return <>; return children({ finding }); }; @@ -104,6 +109,13 @@ export const LatestFindingsTable = ({ showDistributionBar, }); + const createMisconfigurationRuleFn = (rowIndex: number) => { + const finding = getCspFinding(rows[rowIndex].raw._source); + if (!finding) return; + + return async (http: HttpSetup) => createDetectionRuleFromBenchmarkRule(http, finding.rule); + }; + return ( {error ? ( @@ -137,6 +149,7 @@ export const LatestFindingsTable = ({ customCellRenderer={customCellRenderer} groupSelectorComponent={groupSelectorComponent} height={height} + createRuleFn={createMisconfigurationRuleFn} columnHeaders={findingsTableFieldLabels} /> diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_table.tsx index 84b9b127f7eeb..d5d1c8dc220a2 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/latest_vulnerabilities_table.tsx @@ -10,6 +10,7 @@ import { DataTableRecord } from '@kbn/discover-utils/types'; import { i18n } from '@kbn/i18n'; import { EuiDataGridCellValueElementProps, EuiSpacer } from '@elastic/eui'; import { Filter } from '@kbn/es-query'; +import { HttpSetup } from '@kbn/core-http-browser'; import { CspVulnerabilityFinding } from '../../../common/schemas'; import { CloudSecurityDataTable } from '../../components/cloud_security_data_table'; import { useLatestVulnerabilitiesTable } from './hooks/use_latest_vulnerabilities_table'; @@ -18,6 +19,7 @@ import { getDefaultQuery, defaultColumns } from './constants'; import { VulnerabilityFindingFlyout } from './vulnerabilities_finding_flyout/vulnerability_finding_flyout'; import { ErrorCallout } from '../configurations/layout/error_callout'; import { CVSScoreBadge, SeverityStatusBadge } from '../../components/vulnerability_badges'; +import { createDetectionRuleFromVulnerabilityFinding } from './utils/create_detection_rule_from_vulnerability'; import { vulnerabilitiesTableFieldLabels } from './vulnerabilities_table_field_labels'; interface LatestVulnerabilitiesTableProps { @@ -34,6 +36,12 @@ const isCspVulnerabilityFinding = ( return source?.vulnerability?.id !== undefined; }; +const getCspVulnerabilityFinding = ( + source: Record | undefined +): CspVulnerabilityFinding | false => { + return isCspVulnerabilityFinding(source) && (source as CspVulnerabilityFinding); +}; + /** * This Wrapper component renders the children if the given row is a CspVulnerabilityFinding * it uses React's Render Props pattern @@ -45,8 +53,7 @@ const CspVulnerabilityFindingRenderer = ({ row: DataTableRecord; children: ({ finding }: { finding: CspVulnerabilityFinding }) => JSX.Element; }) => { - const source = row.raw._source; - const finding = isCspVulnerabilityFinding(source) && (source as CspVulnerabilityFinding); + const finding = getCspVulnerabilityFinding(row.raw._source); if (!finding) return <>; return children({ finding }); }; @@ -94,6 +101,14 @@ export const LatestVulnerabilitiesTable = ({ nonPersistedFilters, }); + const createVulnerabilityRuleFn = (rowIndex: number) => { + const finding = getCspVulnerabilityFinding(rows[rowIndex].raw._source); + if (!finding) return; + + return async (http: HttpSetup) => + createDetectionRuleFromVulnerabilityFinding(http, finding.vulnerability); + }; + return ( <> {error ? ( @@ -109,6 +124,7 @@ export const LatestVulnerabilitiesTable = ({ rows={rows} total={total} flyoutComponent={flyoutComponent} + createRuleFn={createVulnerabilityRuleFn} cloudPostureDataTable={cloudPostureDataTable} loadMore={fetchNextPage} title={title} From df0a2dae173421ecdbf60ad1dd580cef9405ba96 Mon Sep 17 00:00:00 2001 From: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:36:44 -0400 Subject: [PATCH 024/122] [Security Solution] Add a severless-dev version of the generator script that works with local defaults (#184610) ## Summary This pr adds a new command to the security solution package.json that's just a wrapper around the existing generate command, yarn test:generate:serverless-dev, but uses the serverless default username/password instead. Api keys do not seem to be needed at any point. ![image](https://github.com/elastic/kibana/assets/56408403/497e092f-005b-4fa0-b949-03f1ce071f1e) ### Checklist - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials --- x-pack/plugins/security_solution/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index d2afe4e4ae748..b6823c220ee8b 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -24,6 +24,7 @@ "cypress:dw:endpoint:open": "echo '\n** WARNING **: Run script `cypress:dw:endpoint:open` no longer valid! Use `cypress:dw:open` instead\n'", "junit:merge": "../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json && ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results && yarn junit:transform && mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/", "test:generate": "node scripts/endpoint/resolver_generator", + "test:generate:serverless-dev": "node scripts/endpoint/resolver_generator --node http://elastic_serverless:changeme@127.0.0.1:9200 --kibana http://elastic_serverless:changeme@127.0.0.1:5601", "mappings:generate": "node scripts/mappings/mappings_generator", "mappings:load": "node scripts/mappings/mappings_loader", "junit:transform": "node scripts/junit_transformer --pathPattern '../../../target/kibana-security-solution/cypress/results/*.xml' --rootDirectory ../../../ --reportName 'Security Solution Cypress' --writeInPlace", @@ -31,4 +32,4 @@ "openapi:generate:debug": "node --inspect-brk scripts/openapi/generate", "openapi:bundle": "node scripts/openapi/bundle" } -} +} \ No newline at end of file From f52adaf779404f2e3e7ff1b1e69a2d9b87d32c9e Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 6 Jun 2024 15:08:00 +1000 Subject: [PATCH 025/122] [api-docs] 2024-06-06 Daily api_docs build (#184891) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/729 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_selection.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/apm_data_access.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/assets_data_access.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_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.devdocs.json | 258 +++++- api_docs/controls.mdx | 4 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.devdocs.json | 48 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_quality.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/discover_shared.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.devdocs.json | 25 +- api_docs/embeddable.mdx | 4 +- 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/esql_data_grid.devdocs.json | 61 ++ api_docs/esql_data_grid.mdx | 30 + api_docs/event_annotation.mdx | 2 +- api_docs/event_annotation_listing.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/fields_metadata.devdocs.json | 762 ++++++++++++++++++ api_docs/fields_metadata.mdx | 61 ++ api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.devdocs.json | 141 +++- api_docs/fleet.mdx | 4 +- 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/ingest_pipelines.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_log_pattern_analysis.mdx | 2 +- api_docs/kbn_aiops_log_rate_analysis.mdx | 2 +- .../kbn_alerting_api_integration_helpers.mdx | 2 +- api_docs/kbn_alerting_comparators.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerting_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 +- api_docs/kbn_analytics_collection_utils.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_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_data_view.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_bfetch_error.mdx | 2 +- api_docs/kbn_calculate_auto.mdx | 2 +- .../kbn_calculate_width_from_char_count.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_mock.mdx | 2 +- api_docs/kbn_code_owners.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 +- ...tent_management_table_list_view_common.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.devdocs.json | 4 + 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 +- .../kbn_core_plugins_contracts_browser.mdx | 2 +- .../kbn_core_plugins_contracts_server.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 +- 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_security_browser.mdx | 2 +- .../kbn_core_security_browser_internal.mdx | 2 +- api_docs/kbn_core_security_browser_mocks.mdx | 2 +- api_docs/kbn_core_security_common.mdx | 2 +- api_docs/kbn_core_security_server.mdx | 2 +- .../kbn_core_security_server_internal.mdx | 2 +- api_docs/kbn_core_security_server_mocks.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 +- .../kbn_core_test_helpers_model_versions.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_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_profile_browser.mdx | 2 +- ...kbn_core_user_profile_browser_internal.mdx | 2 +- .../kbn_core_user_profile_browser_mocks.mdx | 2 +- api_docs/kbn_core_user_profile_common.mdx | 2 +- api_docs/kbn_core_user_profile_server.mdx | 2 +- .../kbn_core_user_profile_server_internal.mdx | 2 +- .../kbn_core_user_profile_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.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_custom_icons.mdx | 2 +- api_docs/kbn_custom_integrations.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_forge.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_data_stream_adapter.mdx | 2 +- api_docs/kbn_data_view_utils.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_fleet.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_deeplinks_security.mdx | 2 +- api_docs/kbn_deeplinks_shared.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_discover_utils.mdx | 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_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_agent_utils.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_elastic_assistant_common.mdx | 2 +- api_docs/kbn_entities_schema.devdocs.json | 39 +- api_docs/kbn_entities_schema.mdx | 4 +- 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.devdocs.json | 10 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_esql_ast.mdx | 2 +- api_docs/kbn_esql_utils.devdocs.json | 4 +- api_docs/kbn_esql_utils.mdx | 2 +- api_docs/kbn_esql_validation_autocomplete.mdx | 2 +- api_docs/kbn_event_annotation_common.mdx | 2 +- api_docs/kbn_event_annotation_components.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_field_utils.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- api_docs/kbn_formatters.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- .../kbn_ftr_common_functional_ui_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_grouping.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_index_management.mdx | 2 +- api_docs/kbn_inference_integration_flyout.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.devdocs.json | 16 + api_docs/kbn_io_ts_utils.mdx | 4 +- api_docs/kbn_ipynb.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_lens_embeddable_utils.mdx | 2 +- api_docs/kbn_lens_formula_docs.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_content_badge.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- .../kbn_management_settings_application.mdx | 2 +- ...ent_settings_components_field_category.mdx | 2 +- ...gement_settings_components_field_input.mdx | 2 +- ...nagement_settings_components_field_row.mdx | 2 +- ...bn_management_settings_components_form.mdx | 2 +- ...n_management_settings_field_definition.mdx | 2 +- api_docs/kbn_management_settings_ids.mdx | 2 +- ...n_management_settings_section_registry.mdx | 2 +- api_docs/kbn_management_settings_types.mdx | 2 +- .../kbn_management_settings_utilities.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 +- api_docs/kbn_ml_cancellable_search.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- api_docs/kbn_ml_chi2test.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_in_memory_table.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_time_buckets.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_mock_idp_utils.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.mdx | 2 +- api_docs/kbn_openapi_bundler.mdx | 2 +- api_docs/kbn_openapi_generator.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 +- api_docs/kbn_panel_loader.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_check.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- .../kbn_presentation_containers.devdocs.json | 107 ++- api_docs/kbn_presentation_containers.mdx | 4 +- .../kbn_presentation_publishing.devdocs.json | 487 ++++++++++- api_docs/kbn_presentation_publishing.mdx | 4 +- api_docs/kbn_profiling_utils.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_react_hooks.mdx | 2 +- api_docs/kbn_react_kibana_context_common.mdx | 2 +- api_docs/kbn_react_kibana_context_render.mdx | 2 +- api_docs/kbn_react_kibana_context_root.mdx | 2 +- api_docs/kbn_react_kibana_context_styled.mdx | 2 +- api_docs/kbn_react_kibana_context_theme.mdx | 2 +- api_docs/kbn_react_kibana_mount.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_reporting_csv_share_panel.mdx | 2 +- api_docs/kbn_reporting_export_types_csv.mdx | 2 +- .../kbn_reporting_export_types_csv_common.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf.mdx | 2 +- .../kbn_reporting_export_types_pdf_common.mdx | 2 +- api_docs/kbn_reporting_export_types_png.mdx | 2 +- .../kbn_reporting_export_types_png_common.mdx | 2 +- api_docs/kbn_reporting_mocks_server.mdx | 2 +- api_docs/kbn_reporting_public.mdx | 2 +- api_docs/kbn_reporting_server.mdx | 2 +- api_docs/kbn_resizable_layout.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_router_to_openapispec.mdx | 2 +- api_docs/kbn_router_utils.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_search_api_panels.mdx | 2 +- api_docs/kbn_search_connectors.mdx | 2 +- api_docs/kbn_search_errors.mdx | 2 +- api_docs/kbn_search_index_documents.mdx | 2 +- api_docs/kbn_search_response_warnings.mdx | 2 +- api_docs/kbn_search_types.mdx | 2 +- api_docs/kbn_security_hardening.mdx | 2 +- api_docs/kbn_security_plugin_types_common.mdx | 2 +- ..._security_plugin_types_public.devdocs.json | 226 ++++++ api_docs/kbn_security_plugin_types_public.mdx | 4 +- api_docs/kbn_security_plugin_types_server.mdx | 2 +- api_docs/kbn_security_solution_features.mdx | 2 +- api_docs/kbn_security_solution_navigation.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 +- ...ion_exception_list_components.devdocs.json | 10 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../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_common_settings.mdx | 2 +- .../kbn_serverless_observability_settings.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_search_settings.mdx | 2 +- api_docs/kbn_serverless_security_settings.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 +- .../kbn_shared_ux_button_exit_full_screen.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_error_boundary.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_tabbed_modal.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_sort_predicates.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_eui_helpers.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_timerange.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.mdx | 2 +- api_docs/kbn_try_in_console.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_data_table.devdocs.json | 27 +- api_docs/kbn_unified_data_table.mdx | 4 +- api_docs/kbn_unified_doc_viewer.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_unsaved_changes_badge.mdx | 2 +- api_docs/kbn_use_tracked_promise.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_visualization_ui_components.mdx | 2 +- api_docs/kbn_visualization_utils.mdx | 2 +- api_docs/kbn_xstate_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kbn_zod_helpers.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.devdocs.json | 16 +- 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/links.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/logs_data_access.mdx | 2 +- api_docs/logs_explorer.mdx | 2 +- api_docs/logs_shared.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.devdocs.json | 16 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/metrics_data_access.mdx | 2 +- api_docs/ml.devdocs.json | 16 +- api_docs/ml.mdx | 2 +- api_docs/mock_idp_plugin.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/no_data_page.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/observability_a_i_assistant.mdx | 2 +- api_docs/observability_a_i_assistant_app.mdx | 2 +- .../observability_ai_assistant_management.mdx | 2 +- api_docs/observability_logs_explorer.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/painless_lab.mdx | 2 +- api_docs/plugin_directory.mdx | 28 +- api_docs/presentation_panel.mdx | 2 +- api_docs/presentation_util.devdocs.json | 4 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/profiling_data_access.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/search_connectors.mdx | 2 +- api_docs/search_notebooks.mdx | 2 +- api_docs/search_playground.mdx | 2 +- api_docs/security.devdocs.json | 22 + api_docs/security.mdx | 4 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/slo.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_doc_viewer.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/uptime.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 715 files changed, 2919 insertions(+), 901 deletions(-) create mode 100644 api_docs/esql_data_grid.devdocs.json create mode 100644 api_docs/esql_data_grid.mdx create mode 100644 api_docs/fields_metadata.devdocs.json create mode 100644 api_docs/fields_metadata.mdx diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index c1f3d4c99134c..831353b6d3494 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: 2024-06-05 +date: 2024-06-06 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 003ab0a6453bf..d137092af9487 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index 2993e35c0a789..a852618dd6af9 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 8e8cddfe04935..6036c1650e040 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index fa9bd039a12a6..9516eb5e76c61 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: 2024-06-05 +date: 2024-06-06 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 d4a59b3abe1de..66c8eefc0e896 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index 79827c128f768..6686687b9b209 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 1504ac4f9d59a..eadedadcca608 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/assets_data_access.mdx b/api_docs/assets_data_access.mdx index 795c4e6acc12b..d4c1b9f7cff5b 100644 --- a/api_docs/assets_data_access.mdx +++ b/api_docs/assets_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetsDataAccess title: "assetsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the assetsDataAccess plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetsDataAccess'] --- import assetsDataAccessObj from './assets_data_access.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 957beda2a5783..288d4854e2b96 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: 2024-06-05 +date: 2024-06-06 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 95898336db303..2aa52c937c75e 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: 2024-06-05 +date: 2024-06-06 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 c1d46f6c174a3..c7b4a492469ed 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: 2024-06-05 +date: 2024-06-06 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 5834da01597e4..29f8ee91d77ba 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: 2024-06-05 +date: 2024-06-06 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 0aee0d5e7ed68..2dc3bc3b1e3a5 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: 2024-06-05 +date: 2024-06-06 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 018cb0dd7b2f4..9c6d74d6f3d72 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index d9b6b5a0a8ece..903c3cfb52635 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: 2024-06-05 +date: 2024-06-06 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 1e4e2b20487dc..e56f2446d7539 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: 2024-06-05 +date: 2024-06-06 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 73572f24cb119..f8a4841588a83 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: 2024-06-05 +date: 2024-06-06 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 0ea7308d29106..5194834b05454 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: 2024-06-05 +date: 2024-06-06 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 6dfbc40675e49..221aed330d108 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: 2024-06-05 +date: 2024-06-06 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 bf48f5d3ce9d7..fc7619e1f3d57 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.devdocs.json b/api_docs/controls.devdocs.json index 999f42ac6d3c0..06a783deb4ac9 100644 --- a/api_docs/controls.devdocs.json +++ b/api_docs/controls.devdocs.json @@ -196,7 +196,13 @@ " | undefined) => void; setControlStyle: (payload: ", "ControlStyle", ") => void; setChainingSystem: (payload: ", - "ControlGroupChainingSystem", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupChainingSystem", + "text": "ControlGroupChainingSystem" + }, ") => void; setDefaultControlWidth: (payload: ", { "pluginId": "controls", @@ -1432,6 +1438,38 @@ ], "returnComment": [] }, + { + "parentPluginId": "controls", + "id": "def-public.ControlGroupContainer.removePanel", + "type": "Function", + "tags": [], + "label": "removePanel", + "description": [], + "signature": [ + "(id: string) => void" + ], + "path": "src/plugins/controls/public/control_group/embeddable/control_group_container.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-public.ControlGroupContainer.removePanel.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/controls/public/control_group/embeddable/control_group_container.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "controls", "id": "def-public.ControlGroupContainer.onRemoveEmbeddable", @@ -2111,10 +2149,13 @@ "text": "ControlOutput" }, ", any> implements ", - "IClearableControl", - "<", - "ControlInput", - ">" + { + "pluginId": "controls", + "scope": "public", + "docId": "kibControlsPluginApi", + "section": "def-public.CanClearSelections", + "text": "CanClearSelections" + } ], "path": "src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx", "deprecated": false, @@ -2913,7 +2954,7 @@ { "parentPluginId": "controls", "id": "def-public.OptionsListEmbeddableFactory.presaveTransformFunction.$2", - "type": "CompoundType", + "type": "Object", "tags": [], "label": "embeddable", "description": [], @@ -3296,10 +3337,13 @@ "text": "ControlOutput" }, ", any> implements ", - "IClearableControl", - "<", - "ControlInput", - ">" + { + "pluginId": "controls", + "scope": "public", + "docId": "kibControlsPluginApi", + "section": "def-public.CanClearSelections", + "text": "CanClearSelections" + } ], "path": "src/plugins/controls/public/range_slider/embeddable/range_slider_embeddable.tsx", "deprecated": false, @@ -4206,7 +4250,7 @@ { "parentPluginId": "controls", "id": "def-public.RangeSliderEmbeddableFactory.presaveTransformFunction.$2", - "type": "CompoundType", + "type": "Object", "tags": [], "label": "embeddable", "description": [], @@ -4574,6 +4618,36 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-public.CanClearSelections", + "type": "Interface", + "tags": [], + "label": "CanClearSelections", + "description": [], + "path": "src/plugins/controls/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-public.CanClearSelections.clearSelections", + "type": "Function", + "tags": [], + "label": "clearSelections", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/controls/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-public.ControlEditorProps", @@ -4687,6 +4761,104 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-public.ControlEmbeddable", + "type": "Interface", + "tags": [], + "label": "ControlEmbeddable", + "description": [], + "signature": [ + { + "pluginId": "controls", + "scope": "public", + "docId": "kibControlsPluginApi", + "section": "def-public.ControlEmbeddable", + "text": "ControlEmbeddable" + }, + " extends ", + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.IEmbeddable", + "text": "IEmbeddable" + }, + "" + ], + "path": "src/plugins/controls/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-public.ControlEmbeddable.isChained", + "type": "Function", + "tags": [], + "label": "isChained", + "description": [], + "signature": [ + "(() => boolean) | undefined" + ], + "path": "src/plugins/controls/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "controls", + "id": "def-public.ControlEmbeddable.renderPrepend", + "type": "Function", + "tags": [], + "label": "renderPrepend", + "description": [], + "signature": [ + "(() => React.ReactNode) | undefined" + ], + "path": "src/plugins/controls/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "controls", + "id": "def-public.ControlEmbeddable.selectionsToFilters", + "type": "Function", + "tags": [], + "label": "selectionsToFilters", + "description": [], + "signature": [ + "((input: Partial) => Promise<", + "ControlGroupFilterOutput", + ">) | undefined" + ], + "path": "src/plugins/controls/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-public.ControlEmbeddable.selectionsToFilters.$1", + "type": "Object", + "tags": [], + "label": "input", + "description": [], + "signature": [ + "Partial" + ], + "path": "src/plugins/controls/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-public.ControlGroupInput", @@ -5245,7 +5417,7 @@ { "parentPluginId": "controls", "id": "def-public.IEditableControlFactory.presaveTransformFunction.$2", - "type": "CompoundType", + "type": "Object", "tags": [], "label": "embeddable", "description": [], @@ -5787,24 +5959,15 @@ }, { "parentPluginId": "controls", - "id": "def-public.ControlEmbeddable", - "type": "Type", + "id": "def-public.CONTROL_WIDTH_OPTIONS", + "type": "Array", "tags": [], - "label": "ControlEmbeddable", + "label": "CONTROL_WIDTH_OPTIONS", "description": [], "signature": [ - { - "pluginId": "embeddable", - "scope": "public", - "docId": "kibEmbeddablePluginApi", - "section": "def-public.IEmbeddable", - "text": "IEmbeddable" - }, - " & { isChained?: (() => boolean) | undefined; renderPrepend?: (() => React.ReactNode) | undefined; selectionsToFilters?: ((input: Partial) => Promise<", - "ControlGroupFilterOutput", - ">) | undefined; }" + "{ id: string; 'data-test-subj': string; label: string; }[]" ], - "path": "src/plugins/controls/public/types.ts", + "path": "src/plugins/controls/public/control_group/editor/editor_constants.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -6624,7 +6787,13 @@ "; ignoreParentSettings?: ", "ParentIgnoreSettings", " | undefined; chainingSystem: ", - "ControlGroupChainingSystem", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupChainingSystem", + "text": "ControlGroupChainingSystem" + }, "; showApplySelections?: boolean | undefined; } | undefined" ], "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", @@ -7551,6 +7720,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-common.ControlGroupChainingSystem", + "type": "Type", + "tags": [], + "label": "ControlGroupChainingSystem", + "description": [], + "signature": [ + "\"HIERARCHICAL\" | \"NONE\"" + ], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.ControlInputTransform", @@ -7667,6 +7851,18 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-common.DEFAULT_CONTROL_GROW", + "type": "boolean", + "tags": [], + "label": "DEFAULT_CONTROL_GROW", + "description": [], + "path": "src/plugins/controls/common/control_group/control_group_constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.DEFAULT_CONTROL_STYLE", @@ -7733,7 +7929,13 @@ "text": "ControlsPanels" }, "; chainingSystem: ", - "ControlGroupChainingSystem", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupChainingSystem", + "text": "ControlGroupChainingSystem" + }, "; showApplySelections?: boolean | undefined; }" ], "path": "src/plugins/controls/common/control_group/types.ts", diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index c00477f026e18..c8c3ad0661eaa 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 340 | 0 | 332 | 20 | +| 351 | 0 | 343 | 18 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index fc4edd705a70a..a25fd1f0fcb0b 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.devdocs.json b/api_docs/dashboard.devdocs.json index 12884642b3c5d..5a58dd9a28026 100644 --- a/api_docs/dashboard.devdocs.json +++ b/api_docs/dashboard.devdocs.json @@ -212,23 +212,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", @@ -306,23 +298,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", @@ -858,23 +842,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 639cd78257519..47579feee7a5c 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: 2024-06-05 +date: 2024-06-06 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 693696334d15a..4961ce4d394af 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 918ca014877dd..fd3ce12357125 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_quality.mdx b/api_docs/data_quality.mdx index 9d38bf46ade7a..7e33b9e915b50 100644 --- a/api_docs/data_quality.mdx +++ b/api_docs/data_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataQuality title: "dataQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the dataQuality plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataQuality'] --- import dataQualityObj from './data_quality.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 1bf03818e17d0..fb0078694dd4d 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 3a31da74eba39..660143527ee4b 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 9eb7339dd8dc0..5715bf59b4f42 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: 2024-06-05 +date: 2024-06-06 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 a11489a7fe725..86f30dc8db931 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: 2024-06-05 +date: 2024-06-06 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 2eeec04c6e998..d60627a240454 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 59dd3f2b905f1..eff9071cd9783 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index d9bd128006a0e..506587ae36934 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index fd761717cd3eb..0454dbdc976da 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index b51a8ebd93b91..012d5ec04b548 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 538da386fe47d..17738be06f5b8 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 2e76022ee377b..6f0507a83fcc5 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 8252ff6115dab..7fcee6515d7a6 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: 2024-06-05 +date: 2024-06-06 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 25da2f30949ac..5fe1ce61f7e5b 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: 2024-06-05 +date: 2024-06-06 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 73c356c969b49..6b89700428deb 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/discover_shared.mdx b/api_docs/discover_shared.mdx index 64db9e7ca8175..f5cdb04be276a 100644 --- a/api_docs/discover_shared.mdx +++ b/api_docs/discover_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverShared title: "discoverShared" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverShared plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverShared'] --- import discoverSharedObj from './discover_shared.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 6a2fbe60f1cd6..beff6b515b4d3 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index f747b69145ed4..4b564120c22ef 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index 9b90be202d337..929b5fdefe5ed 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -12900,7 +12900,7 @@ ], "signature": [ "(initialState: RuntimeState, buildApi: (apiRegistration: ", - "ReactEmbeddableApiRegistration", + "BuildReactEmbeddableApiRegistration", ", comparators: ", { "pluginId": "@kbn/presentation-publishing", @@ -12909,7 +12909,9 @@ "section": "def-common.StateComparators", "text": "StateComparators" }, - ") => Api, uuid: string, parentApi?: unknown) => Promise<{ Component: React.FC<{}>; api: Api; }>" + ") => Api, uuid: string, parentApi: unknown, setApi: (api: ", + "SetReactEmbeddableApiRegistration", + ") => Api) => Promise<{ Component: React.FC<{}>; api: Api; }>" ], "path": "src/plugins/embeddable/public/react_embeddable_system/types.ts", "deprecated": false, @@ -12939,7 +12941,7 @@ "description": [], "signature": [ "(apiRegistration: ", - "ReactEmbeddableApiRegistration", + "BuildReactEmbeddableApiRegistration", ", comparators: ", { "pluginId": "@kbn/presentation-publishing", @@ -12984,6 +12986,23 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "embeddable", + "id": "def-public.ReactEmbeddableFactory.buildEmbeddable.$5", + "type": "Function", + "tags": [], + "label": "setApi", + "description": [], + "signature": [ + "(api: ", + "SetReactEmbeddableApiRegistration", + ") => Api" + ], + "path": "src/plugins/embeddable/public/react_embeddable_system/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 20d0bb8050c31..afdb88fcd88ba 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 556 | 1 | 446 | 8 | +| 557 | 1 | 447 | 9 | ## Client diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 2a36bc048ca31..ac4f81a223cec 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: 2024-06-05 +date: 2024-06-06 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 afe609755793f..44e6016bcf702 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: 2024-06-05 +date: 2024-06-06 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 40801bf27ebe6..84cd075bd48f2 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: 2024-06-05 +date: 2024-06-06 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 7e3cb69fc0f45..35c350116888b 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/esql_data_grid.devdocs.json b/api_docs/esql_data_grid.devdocs.json new file mode 100644 index 0000000000000..ea15ca5487f8b --- /dev/null +++ b/api_docs/esql_data_grid.devdocs.json @@ -0,0 +1,61 @@ +{ + "id": "esqlDataGrid", + "client": { + "classes": [], + "functions": [ + { + "parentPluginId": "esqlDataGrid", + "id": "def-public.ESQLDataGrid", + "type": "Function", + "tags": [], + "label": "ESQLDataGrid", + "description": [], + "signature": [ + "(props: ESQLDataGridProps) => JSX.Element" + ], + "path": "src/plugins/esql_datagrid/public/create_datagrid.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "esqlDataGrid", + "id": "def-public.ESQLDataGrid.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "ESQLDataGridProps" + ], + "path": "src/plugins/esql_datagrid/public/create_datagrid.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/esql_data_grid.mdx b/api_docs/esql_data_grid.mdx new file mode 100644 index 0000000000000..039db9f9ef1e4 --- /dev/null +++ b/api_docs/esql_data_grid.mdx @@ -0,0 +1,30 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibEsqlDataGridPluginApi +slug: /kibana-dev-docs/api/esqlDataGrid +title: "esqlDataGrid" +image: https://source.unsplash.com/400x175/?github +description: API docs for the esqlDataGrid plugin +date: 2024-06-06 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esqlDataGrid'] +--- +import esqlDataGridObj from './esql_data_grid.devdocs.json'; + + + +Contact [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 2 | 0 | 2 | 0 | + +## Client + +### Functions + + diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index b093993ab0a63..99cfc2f27f983 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_annotation_listing.mdx b/api_docs/event_annotation_listing.mdx index 7d59a8f090d57..869eb08007491 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotationListing'] --- import eventAnnotationListingObj from './event_annotation_listing.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 17d9c45529df0..cd377b22d8f00 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: 2024-06-05 +date: 2024-06-06 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 b80a29a86de9b..f6470755965ac 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: 2024-06-05 +date: 2024-06-06 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 3d4a101e9cb87..7e33b6bb9a025 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: 2024-06-05 +date: 2024-06-06 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 d7e02c6fb9cab..d9a6dfcb91df3 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: 2024-06-05 +date: 2024-06-06 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 dedf1f356deb4..5e69f016743aa 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: 2024-06-05 +date: 2024-06-06 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 655e185d46512..804514ae674e9 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: 2024-06-05 +date: 2024-06-06 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 d2aadd6444fc3..dabcdb2854a77 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: 2024-06-05 +date: 2024-06-06 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 92389c0ec92ae..ffb3d622d9a5d 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: 2024-06-05 +date: 2024-06-06 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 e3169d31d1f67..2876a3617c019 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: 2024-06-05 +date: 2024-06-06 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 85afebfd437ed..21c8c3655f0b7 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: 2024-06-05 +date: 2024-06-06 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 b04ac01380260..c61c88babacb4 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: 2024-06-05 +date: 2024-06-06 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 ade52e9096a8c..a16db7043647c 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: 2024-06-05 +date: 2024-06-06 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 cda8d9a5002c2..b3c04451c0dcd 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: 2024-06-05 +date: 2024-06-06 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 c76b87e1b619a..41822e6678792 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: 2024-06-05 +date: 2024-06-06 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 6a24838acafda..01f5b56b41639 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: 2024-06-05 +date: 2024-06-06 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 2ed920680bb2f..61403d8eed4bc 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: 2024-06-05 +date: 2024-06-06 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 044719c404618..d8573459557de 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: 2024-06-05 +date: 2024-06-06 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 e532a3ed81b67..376991a8e5e35 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/fields_metadata.devdocs.json b/api_docs/fields_metadata.devdocs.json new file mode 100644 index 0000000000000..63ccdbaad3943 --- /dev/null +++ b/api_docs/fields_metadata.devdocs.json @@ -0,0 +1,762 @@ +{ + "id": "fieldsMetadata", + "client": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicSetupDeps", + "type": "Interface", + "tags": [], + "label": "FieldsMetadataPublicSetupDeps", + "description": [], + "path": "x-pack/plugins/fields_metadata/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicStartDeps", + "type": "Interface", + "tags": [], + "label": "FieldsMetadataPublicStartDeps", + "description": [], + "path": "x-pack/plugins/fields_metadata/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [], + "objects": [], + "setup": { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicSetup", + "type": "Interface", + "tags": [], + "label": "FieldsMetadataPublicSetup", + "description": [], + "path": "x-pack/plugins/fields_metadata/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "lifecycle": "setup", + "initialIsOpen": true + }, + "start": { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicStart", + "type": "Interface", + "tags": [], + "label": "FieldsMetadataPublicStart", + "description": [], + "path": "x-pack/plugins/fields_metadata/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicStart.getClient", + "type": "Function", + "tags": [], + "label": "getClient", + "description": [], + "signature": [ + "() => Promise<", + "IFieldsMetadataClient", + ">" + ], + "path": "x-pack/plugins/fields_metadata/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [] + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicStart.useFieldsMetadata", + "type": "Function", + "tags": [], + "label": "useFieldsMetadata", + "description": [], + "signature": [ + "(params?: ", + "FindFieldsMetadataRequestQuery", + " | undefined, deps?: React.DependencyList | undefined) => ", + "UseFieldsMetadataReturnType" + ], + "path": "x-pack/plugins/fields_metadata/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicStart.useFieldsMetadata.$1", + "type": "CompoundType", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "FindFieldsMetadataRequestQuery", + " | undefined" + ], + "path": "x-pack/plugins/fields_metadata/public/hooks/use_fields_metadata/use_fields_metadata.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-public.FieldsMetadataPublicStart.useFieldsMetadata.$2", + "type": "Object", + "tags": [], + "label": "deps", + "description": [], + "signature": [ + "React.DependencyList | undefined" + ], + "path": "x-pack/plugins/fields_metadata/public/hooks/use_fields_metadata/use_fields_metadata.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "lifecycle": "start", + "initialIsOpen": true + } + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.DatasetName", + "type": "Type", + "tags": [], + "label": "DatasetName", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fields_metadata/server/services/fields_metadata/repositories/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.ExtractedDatasetFields", + "type": "Type", + "tags": [], + "label": "ExtractedDatasetFields", + "description": [], + "signature": [ + "{ [x: string]: { name: string; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }; }" + ], + "path": "x-pack/plugins/fields_metadata/server/services/fields_metadata/repositories/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.ExtractedIntegrationFields", + "type": "Type", + "tags": [], + "label": "ExtractedIntegrationFields", + "description": [], + "signature": [ + "{ [x: string]: ", + { + "pluginId": "fieldsMetadata", + "scope": "server", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-server.ExtractedDatasetFields", + "text": "ExtractedDatasetFields" + }, + "; }" + ], + "path": "x-pack/plugins/fields_metadata/server/services/fields_metadata/repositories/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.IntegrationName", + "type": "Type", + "tags": [], + "label": "IntegrationName", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fields_metadata/server/services/fields_metadata/repositories/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [], + "setup": { + "parentPluginId": "fieldsMetadata", + "id": "def-server.FieldsMetadataServerSetup", + "type": "Interface", + "tags": [], + "label": "FieldsMetadataServerSetup", + "description": [], + "path": "x-pack/plugins/fields_metadata/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.FieldsMetadataServerSetup.registerIntegrationFieldsExtractor", + "type": "Function", + "tags": [], + "label": "registerIntegrationFieldsExtractor", + "description": [], + "signature": [ + "(extractor: ", + "IntegrationFieldsExtractor", + ") => void" + ], + "path": "x-pack/plugins/fields_metadata/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.FieldsMetadataServerSetup.registerIntegrationFieldsExtractor.$1", + "type": "Function", + "tags": [], + "label": "extractor", + "description": [], + "signature": [ + "(params: ", + "IntegrationFieldsSearchParams", + ") => Promise<", + { + "pluginId": "fieldsMetadata", + "scope": "server", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-server.ExtractedIntegrationFields", + "text": "ExtractedIntegrationFields" + }, + ">" + ], + "path": "x-pack/plugins/fields_metadata/server/services/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.FieldsMetadataServerSetup.registerIntegrationFieldsExtractor.$1.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "IntegrationFieldsSearchParams" + ], + "path": "x-pack/plugins/fields_metadata/server/services/fields_metadata/repositories/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ] + } + ], + "lifecycle": "setup", + "initialIsOpen": true + }, + "start": { + "parentPluginId": "fieldsMetadata", + "id": "def-server.FieldsMetadataServerStart", + "type": "Interface", + "tags": [], + "label": "FieldsMetadataServerStart", + "description": [], + "path": "x-pack/plugins/fields_metadata/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-server.FieldsMetadataServerStart.getClient", + "type": "Function", + "tags": [], + "label": "getClient", + "description": [], + "signature": [ + "() => ", + "IFieldsMetadataClient" + ], + "path": "x-pack/plugins/fields_metadata/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [] + } + ], + "lifecycle": "start", + "initialIsOpen": true + } + }, + "common": { + "classes": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadata", + "type": "Class", + "tags": [], + "label": "FieldMetadata", + "description": [], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/field_metadata.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadata.pick", + "type": "Function", + "tags": [], + "label": "pick", + "description": [], + "signature": [ + "(props: (\"source\" | \"type\" | \"normalize\" | \"short\" | \"format\" | \"name\" | \"index\" | \"pattern\" | \"description\" | \"doc_values\" | \"ignore_above\" | \"beta\" | \"required\" | \"level\" | \"allowed_values\" | \"dashed_name\" | \"example\" | \"expected_values\" | \"flat_name\" | \"input_format\" | \"multi_fields\" | \"object_type\" | \"original_fieldset\" | \"output_format\" | \"output_precision\" | \"scaling_factor\")[]) => { name?: string | undefined; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/field_metadata.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadata.pick.$1", + "type": "Array", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "(\"source\" | \"type\" | \"normalize\" | \"short\" | \"format\" | \"name\" | \"index\" | \"pattern\" | \"description\" | \"doc_values\" | \"ignore_above\" | \"beta\" | \"required\" | \"level\" | \"allowed_values\" | \"dashed_name\" | \"example\" | \"expected_values\" | \"flat_name\" | \"input_format\" | \"multi_fields\" | \"object_type\" | \"original_fieldset\" | \"output_format\" | \"output_precision\" | \"scaling_factor\")[]" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/field_metadata.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadata.toPlain", + "type": "Function", + "tags": [], + "label": "toPlain", + "description": [], + "signature": [ + "() => { name: string; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/field_metadata.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadata.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [], + "signature": [ + "(fieldMetadata: { name: string; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }) => ", + { + "pluginId": "fieldsMetadata", + "scope": "common", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-common.FieldMetadata", + "text": "FieldMetadata" + } + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/field_metadata.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadata.create.$1", + "type": "CompoundType", + "tags": [], + "label": "fieldMetadata", + "description": [], + "signature": [ + "{ name: string; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/field_metadata.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldsMetadataDictionary", + "type": "Class", + "tags": [], + "label": "FieldsMetadataDictionary", + "description": [], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/fields_metadata_dictionary.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldsMetadataDictionary.pick", + "type": "Function", + "tags": [], + "label": "pick", + "description": [], + "signature": [ + "(attributes: (\"source\" | \"type\" | \"normalize\" | \"short\" | \"format\" | \"name\" | \"index\" | \"pattern\" | \"description\" | \"doc_values\" | \"ignore_above\" | \"beta\" | \"required\" | \"level\" | \"allowed_values\" | \"dashed_name\" | \"example\" | \"expected_values\" | \"flat_name\" | \"input_format\" | \"multi_fields\" | \"object_type\" | \"original_fieldset\" | \"output_format\" | \"output_precision\" | \"scaling_factor\")[]) => Record" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/fields_metadata_dictionary.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldsMetadataDictionary.pick.$1", + "type": "Array", + "tags": [], + "label": "attributes", + "description": [], + "signature": [ + "(\"source\" | \"type\" | \"normalize\" | \"short\" | \"format\" | \"name\" | \"index\" | \"pattern\" | \"description\" | \"doc_values\" | \"ignore_above\" | \"beta\" | \"required\" | \"level\" | \"allowed_values\" | \"dashed_name\" | \"example\" | \"expected_values\" | \"flat_name\" | \"input_format\" | \"multi_fields\" | \"object_type\" | \"original_fieldset\" | \"output_format\" | \"output_precision\" | \"scaling_factor\")[]" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/fields_metadata_dictionary.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldsMetadataDictionary.toPlain", + "type": "Function", + "tags": [], + "label": "toPlain", + "description": [], + "signature": [ + "() => Record" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/fields_metadata_dictionary.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldsMetadataDictionary.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [], + "signature": [ + "(fields: ", + "FieldsMetadataMap", + ") => ", + { + "pluginId": "fieldsMetadata", + "scope": "common", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-common.FieldsMetadataDictionary", + "text": "FieldsMetadataDictionary" + } + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/fields_metadata_dictionary.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldsMetadataDictionary.create.$1", + "type": "Object", + "tags": [], + "label": "fields", + "description": [], + "signature": [ + "FieldsMetadataMap" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/fields_metadata_dictionary.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [], + "interfaces": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadata", + "type": "Interface", + "tags": [], + "label": "FieldMetadata", + "description": [], + "signature": [ + { + "pluginId": "fieldsMetadata", + "scope": "common", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-common.FieldMetadata", + "text": "FieldMetadata" + }, + " extends { name: string; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/models/field_metadata.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.EcsFieldName", + "type": "Type", + "tags": [], + "label": "EcsFieldName", + "description": [], + "signature": [ + "\"@timestamp\" | \"event.sequence\" | \"event.start\" | \"event.end\" | \"event.provider\" | \"event.duration\" | \"event.action\" | \"message\" | \"event.outcome\" | \"tags\" | \"event.kind\" | \"agent.name\" | \"container.id\" | \"host.name\" | \"labels\" | \"service.environment\" | \"service.name\" | \"ecs.version\" | \"agent.build.original\" | \"agent.ephemeral_id\" | \"agent.id\" | \"agent.type\" | \"agent.version\" | \"client.address\" | \"client.as.number\" | \"client.as.organization.name\" | \"client.bytes\" | \"client.domain\" | \"client.geo.city_name\" | \"client.geo.continent_code\" | \"client.geo.continent_name\" | \"client.geo.country_iso_code\" | \"client.geo.country_name\" | \"client.geo.location\" | \"client.geo.name\" | \"client.geo.postal_code\" | \"client.geo.region_iso_code\" | \"client.geo.region_name\" | \"client.geo.timezone\" | \"client.ip\" | \"client.mac\" | \"client.nat.ip\" | \"client.nat.port\" | \"client.packets\" | \"client.port\" | \"client.registered_domain\" | \"client.subdomain\" | \"client.top_level_domain\" | \"client.user.domain\" | \"client.user.email\" | \"client.user.full_name\" | \"client.user.group.domain\" | \"client.user.group.id\" | \"client.user.group.name\" | \"client.user.hash\" | \"client.user.id\" | \"client.user.name\" | \"client.user.roles\" | \"cloud.account.id\" | \"cloud.account.name\" | \"cloud.availability_zone\" | \"cloud.instance.id\" | \"cloud.instance.name\" | \"cloud.machine.type\" | \"cloud.origin.account.id\" | \"cloud.origin.account.name\" | \"cloud.origin.availability_zone\" | \"cloud.origin.instance.id\" | \"cloud.origin.instance.name\" | \"cloud.origin.machine.type\" | \"cloud.origin.project.id\" | \"cloud.origin.project.name\" | \"cloud.origin.provider\" | \"cloud.origin.region\" | \"cloud.origin.service.name\" | \"cloud.project.id\" | \"cloud.project.name\" | \"cloud.provider\" | \"cloud.region\" | \"cloud.service.name\" | \"cloud.target.account.id\" | \"cloud.target.account.name\" | \"cloud.target.availability_zone\" | \"cloud.target.instance.id\" | \"cloud.target.instance.name\" | \"cloud.target.machine.type\" | \"cloud.target.project.id\" | \"cloud.target.project.name\" | \"cloud.target.provider\" | \"cloud.target.region\" | \"cloud.target.service.name\" | \"container.cpu.usage\" | \"container.disk.read.bytes\" | \"container.disk.write.bytes\" | \"container.image.hash.all\" | \"container.image.name\" | \"container.image.tag\" | \"container.labels\" | \"container.memory.usage\" | \"container.name\" | \"container.network.egress.bytes\" | \"container.network.ingress.bytes\" | \"container.runtime\" | \"container.security_context.privileged\" | \"destination.address\" | \"destination.as.number\" | \"destination.as.organization.name\" | \"destination.bytes\" | \"destination.domain\" | \"destination.geo.city_name\" | \"destination.geo.continent_code\" | \"destination.geo.continent_name\" | \"destination.geo.country_iso_code\" | \"destination.geo.country_name\" | \"destination.geo.location\" | \"destination.geo.name\" | \"destination.geo.postal_code\" | \"destination.geo.region_iso_code\" | \"destination.geo.region_name\" | \"destination.geo.timezone\" | \"destination.ip\" | \"destination.mac\" | \"destination.nat.ip\" | \"destination.nat.port\" | \"destination.packets\" | \"destination.port\" | \"destination.registered_domain\" | \"destination.subdomain\" | \"destination.top_level_domain\" | \"destination.user.domain\" | \"destination.user.email\" | \"destination.user.full_name\" | \"destination.user.group.domain\" | \"destination.user.group.id\" | \"destination.user.group.name\" | \"destination.user.hash\" | \"destination.user.id\" | \"destination.user.name\" | \"destination.user.roles\" | \"device.id\" | \"device.manufacturer\" | \"device.model.identifier\" | \"device.model.name\" | \"dll.code_signature.digest_algorithm\" | \"dll.code_signature.exists\" | \"dll.code_signature.signing_id\" | \"dll.code_signature.status\" | \"dll.code_signature.subject_name\" | \"dll.code_signature.team_id\" | \"dll.code_signature.timestamp\" | \"dll.code_signature.trusted\" | \"dll.code_signature.valid\" | \"dll.hash.md5\" | \"dll.hash.sha1\" | \"dll.hash.sha256\" | \"dll.hash.sha384\" | \"dll.hash.sha512\" | \"dll.hash.ssdeep\" | \"dll.hash.tlsh\" | \"dll.name\" | \"dll.path\" | \"dll.pe.architecture\" | \"dll.pe.company\" | \"dll.pe.description\" | \"dll.pe.file_version\" | \"dll.pe.go_import_hash\" | \"dll.pe.go_imports\" | \"dll.pe.go_imports_names_entropy\" | \"dll.pe.go_imports_names_var_entropy\" | \"dll.pe.go_stripped\" | \"dll.pe.imphash\" | \"dll.pe.import_hash\" | \"dll.pe.imports\" | \"dll.pe.imports_names_entropy\" | \"dll.pe.imports_names_var_entropy\" | \"dll.pe.original_file_name\" | \"dll.pe.pehash\" | \"dll.pe.product\" | \"dll.pe.sections\" | \"dns.answers\" | \"dns.header_flags\" | \"dns.id\" | \"dns.op_code\" | \"dns.question.class\" | \"dns.question.name\" | \"dns.question.registered_domain\" | \"dns.question.subdomain\" | \"dns.question.top_level_domain\" | \"dns.question.type\" | \"dns.resolved_ip\" | \"dns.response_code\" | \"dns.type\" | \"email.attachments\" | \"file.extension\" | \"file.hash.md5\" | \"file.hash.sha1\" | \"file.hash.sha256\" | \"file.hash.sha384\" | \"file.hash.sha512\" | \"file.hash.ssdeep\" | \"file.hash.tlsh\" | \"file.mime_type\" | \"file.name\" | \"file.size\" | \"email.bcc.address\" | \"email.cc.address\" | \"email.content_type\" | \"email.delivery_timestamp\" | \"email.direction\" | \"email.from.address\" | \"email.local_id\" | \"email.message_id\" | \"email.origination_timestamp\" | \"email.reply_to.address\" | \"email.sender.address\" | \"email.subject\" | \"email.to.address\" | \"email.x_mailer\" | \"error.code\" | \"error.id\" | \"error.message\" | \"error.stack_trace\" | \"error.type\" | \"event.agent_id_status\" | \"event.category\" | \"event.code\" | \"event.created\" | \"event.dataset\" | \"event.hash\" | \"event.id\" | \"event.ingested\" | \"event.module\" | \"event.original\" | \"event.reason\" | \"event.reference\" | \"event.risk_score\" | \"event.risk_score_norm\" | \"event.severity\" | \"event.timezone\" | \"event.type\" | \"event.url\" | \"faas.coldstart\" | \"faas.execution\" | \"faas.id\" | \"faas.name\" | \"faas.version\" | \"file.accessed\" | \"file.attributes\" | \"file.code_signature.digest_algorithm\" | \"file.code_signature.exists\" | \"file.code_signature.signing_id\" | \"file.code_signature.status\" | \"file.code_signature.subject_name\" | \"file.code_signature.team_id\" | \"file.code_signature.timestamp\" | \"file.code_signature.trusted\" | \"file.code_signature.valid\" | \"file.created\" | \"file.ctime\" | \"file.device\" | \"file.directory\" | \"file.drive_letter\" | \"file.elf.architecture\" | \"file.elf.byte_order\" | \"file.elf.cpu_type\" | \"file.elf.creation_date\" | \"file.elf.exports\" | \"file.elf.go_import_hash\" | \"file.elf.go_imports\" | \"file.elf.go_imports_names_entropy\" | \"file.elf.go_imports_names_var_entropy\" | \"file.elf.go_stripped\" | \"file.elf.header.abi_version\" | \"file.elf.header.class\" | \"file.elf.header.data\" | \"file.elf.header.entrypoint\" | \"file.elf.header.object_version\" | \"file.elf.header.os_abi\" | \"file.elf.header.type\" | \"file.elf.header.version\" | \"file.elf.import_hash\" | \"file.elf.imports\" | \"file.elf.imports_names_entropy\" | \"file.elf.imports_names_var_entropy\" | \"file.elf.sections\" | \"file.elf.segments\" | \"file.elf.shared_libraries\" | \"file.elf.telfhash\" | \"file.fork_name\" | \"file.gid\" | \"file.group\" | \"file.inode\" | \"file.macho.go_import_hash\" | \"file.macho.go_imports\" | \"file.macho.go_imports_names_entropy\" | \"file.macho.go_imports_names_var_entropy\" | \"file.macho.go_stripped\" | \"file.macho.import_hash\" | \"file.macho.imports\" | \"file.macho.imports_names_entropy\" | \"file.macho.imports_names_var_entropy\" | \"file.macho.sections\" | \"file.macho.symhash\" | \"file.mode\" | \"file.mtime\" | \"file.owner\" | \"file.path\" | \"file.pe.architecture\" | \"file.pe.company\" | \"file.pe.description\" | \"file.pe.file_version\" | \"file.pe.go_import_hash\" | \"file.pe.go_imports\" | \"file.pe.go_imports_names_entropy\" | \"file.pe.go_imports_names_var_entropy\" | \"file.pe.go_stripped\" | \"file.pe.imphash\" | \"file.pe.import_hash\" | \"file.pe.imports\" | \"file.pe.imports_names_entropy\" | \"file.pe.imports_names_var_entropy\" | \"file.pe.original_file_name\" | \"file.pe.pehash\" | \"file.pe.product\" | \"file.pe.sections\" | \"file.target_path\" | \"file.type\" | \"file.uid\" | \"file.x509.alternative_names\" | \"file.x509.issuer.common_name\" | \"file.x509.issuer.country\" | \"file.x509.issuer.distinguished_name\" | \"file.x509.issuer.locality\" | \"file.x509.issuer.organization\" | \"file.x509.issuer.organizational_unit\" | \"file.x509.issuer.state_or_province\" | \"file.x509.not_after\" | \"file.x509.not_before\" | \"file.x509.public_key_algorithm\" | \"file.x509.public_key_curve\" | \"file.x509.public_key_exponent\" | \"file.x509.public_key_size\" | \"file.x509.serial_number\" | \"file.x509.signature_algorithm\" | \"file.x509.subject.common_name\" | \"file.x509.subject.country\" | \"file.x509.subject.distinguished_name\" | \"file.x509.subject.locality\" | \"file.x509.subject.organization\" | \"file.x509.subject.organizational_unit\" | \"file.x509.subject.state_or_province\" | \"file.x509.version_number\" | \"group.domain\" | \"group.id\" | \"group.name\" | \"host.architecture\" | \"host.boot.id\" | \"host.cpu.usage\" | \"host.disk.read.bytes\" | \"host.disk.write.bytes\" | \"host.domain\" | \"host.geo.city_name\" | \"host.geo.continent_code\" | \"host.geo.continent_name\" | \"host.geo.country_iso_code\" | \"host.geo.country_name\" | \"host.geo.location\" | \"host.geo.name\" | \"host.geo.postal_code\" | \"host.geo.region_iso_code\" | \"host.geo.region_name\" | \"host.geo.timezone\" | \"host.hostname\" | \"host.id\" | \"host.ip\" | \"host.mac\" | \"host.network.egress.bytes\" | \"host.network.egress.packets\" | \"host.network.ingress.bytes\" | \"host.network.ingress.packets\" | \"host.os.family\" | \"host.os.full\" | \"host.os.kernel\" | \"host.os.name\" | \"host.os.platform\" | \"host.os.type\" | \"host.os.version\" | \"host.pid_ns_ino\" | \"host.risk.calculated_level\" | \"host.risk.calculated_score\" | \"host.risk.calculated_score_norm\" | \"host.risk.static_level\" | \"host.risk.static_score\" | \"host.risk.static_score_norm\" | \"host.type\" | \"host.uptime\" | \"http.request.body.bytes\" | \"http.request.body.content\" | \"http.request.bytes\" | \"http.request.id\" | \"http.request.method\" | \"http.request.mime_type\" | \"http.request.referrer\" | \"http.response.body.bytes\" | \"http.response.body.content\" | \"http.response.bytes\" | \"http.response.mime_type\" | \"http.response.status_code\" | \"http.version\" | \"log.file.path\" | \"log.level\" | \"log.logger\" | \"log.origin.file.line\" | \"log.origin.file.name\" | \"log.origin.function\" | \"log.syslog\" | \"network.application\" | \"network.bytes\" | \"network.community_id\" | \"network.direction\" | \"network.forwarded_ip\" | \"network.iana_number\" | \"network.inner\" | \"network.name\" | \"network.packets\" | \"network.protocol\" | \"network.transport\" | \"network.type\" | \"network.vlan.id\" | \"network.vlan.name\" | \"observer.egress\" | \"observer.geo.city_name\" | \"observer.geo.continent_code\" | \"observer.geo.continent_name\" | \"observer.geo.country_iso_code\" | \"observer.geo.country_name\" | \"observer.geo.location\" | \"observer.geo.name\" | \"observer.geo.postal_code\" | \"observer.geo.region_iso_code\" | \"observer.geo.region_name\" | \"observer.geo.timezone\" | \"observer.hostname\" | \"observer.ingress\" | \"observer.ip\" | \"observer.mac\" | \"observer.name\" | \"observer.os.family\" | \"observer.os.full\" | \"observer.os.kernel\" | \"observer.os.name\" | \"observer.os.platform\" | \"observer.os.type\" | \"observer.os.version\" | \"observer.product\" | \"observer.serial_number\" | \"observer.type\" | \"observer.vendor\" | \"observer.version\" | \"orchestrator.api_version\" | \"orchestrator.cluster.id\" | \"orchestrator.cluster.name\" | \"orchestrator.cluster.url\" | \"orchestrator.cluster.version\" | \"orchestrator.namespace\" | \"orchestrator.organization\" | \"orchestrator.resource.annotation\" | \"orchestrator.resource.id\" | \"orchestrator.resource.ip\" | \"orchestrator.resource.label\" | \"orchestrator.resource.name\" | \"orchestrator.resource.parent.type\" | \"orchestrator.resource.type\" | \"orchestrator.type\" | \"organization.id\" | \"organization.name\" | \"package.architecture\" | \"package.build_version\" | \"package.checksum\" | \"package.description\" | \"package.install_scope\" | \"package.installed\" | \"package.license\" | \"package.name\" | \"package.path\" | \"package.reference\" | \"package.size\" | \"package.type\" | \"package.version\" | \"process.args\" | \"process.args_count\" | \"process.code_signature.digest_algorithm\" | \"process.code_signature.exists\" | \"process.code_signature.signing_id\" | \"process.code_signature.status\" | \"process.code_signature.subject_name\" | \"process.code_signature.team_id\" | \"process.code_signature.timestamp\" | \"process.code_signature.trusted\" | \"process.code_signature.valid\" | \"process.command_line\" | \"process.elf.architecture\" | \"process.elf.byte_order\" | \"process.elf.cpu_type\" | \"process.elf.creation_date\" | \"process.elf.exports\" | \"process.elf.go_import_hash\" | \"process.elf.go_imports\" | \"process.elf.go_imports_names_entropy\" | \"process.elf.go_imports_names_var_entropy\" | \"process.elf.go_stripped\" | \"process.elf.header.abi_version\" | \"process.elf.header.class\" | \"process.elf.header.data\" | \"process.elf.header.entrypoint\" | \"process.elf.header.object_version\" | \"process.elf.header.os_abi\" | \"process.elf.header.type\" | \"process.elf.header.version\" | \"process.elf.import_hash\" | \"process.elf.imports\" | \"process.elf.imports_names_entropy\" | \"process.elf.imports_names_var_entropy\" | \"process.elf.sections\" | \"process.elf.segments\" | \"process.elf.shared_libraries\" | \"process.elf.telfhash\" | \"process.end\" | \"process.entity_id\" | \"process.entry_leader.args\" | \"process.entry_leader.args_count\" | \"process.entry_leader.attested_groups.name\" | \"process.entry_leader.attested_user.id\" | \"process.entry_leader.attested_user.name\" | \"process.entry_leader.command_line\" | \"process.entry_leader.entity_id\" | \"process.entry_leader.entry_meta.source.ip\" | \"process.entry_leader.entry_meta.type\" | \"process.entry_leader.executable\" | \"process.entry_leader.group.id\" | \"process.entry_leader.group.name\" | \"process.entry_leader.interactive\" | \"process.entry_leader.name\" | \"process.entry_leader.parent.entity_id\" | \"process.entry_leader.parent.pid\" | \"process.entry_leader.parent.session_leader.entity_id\" | \"process.entry_leader.parent.session_leader.pid\" | \"process.entry_leader.parent.session_leader.start\" | \"process.entry_leader.parent.session_leader.vpid\" | \"process.entry_leader.parent.start\" | \"process.entry_leader.parent.vpid\" | \"process.entry_leader.pid\" | \"process.entry_leader.real_group.id\" | \"process.entry_leader.real_group.name\" | \"process.entry_leader.real_user.id\" | \"process.entry_leader.real_user.name\" | \"process.entry_leader.same_as_process\" | \"process.entry_leader.saved_group.id\" | \"process.entry_leader.saved_group.name\" | \"process.entry_leader.saved_user.id\" | \"process.entry_leader.saved_user.name\" | \"process.entry_leader.start\" | \"process.entry_leader.supplemental_groups.id\" | \"process.entry_leader.supplemental_groups.name\" | \"process.entry_leader.tty\" | \"process.entry_leader.user.id\" | \"process.entry_leader.user.name\" | \"process.entry_leader.vpid\" | \"process.entry_leader.working_directory\" | \"process.env_vars\" | \"process.executable\" | \"process.exit_code\" | \"process.group_leader.args\" | \"process.group_leader.args_count\" | \"process.group_leader.command_line\" | \"process.group_leader.entity_id\" | \"process.group_leader.executable\" | \"process.group_leader.group.id\" | \"process.group_leader.group.name\" | \"process.group_leader.interactive\" | \"process.group_leader.name\" | \"process.group_leader.pid\" | \"process.group_leader.real_group.id\" | \"process.group_leader.real_group.name\" | \"process.group_leader.real_user.id\" | \"process.group_leader.real_user.name\" | \"process.group_leader.same_as_process\" | \"process.group_leader.saved_group.id\" | \"process.group_leader.saved_group.name\" | \"process.group_leader.saved_user.id\" | \"process.group_leader.saved_user.name\" | \"process.group_leader.start\" | \"process.group_leader.supplemental_groups.id\" | \"process.group_leader.supplemental_groups.name\" | \"process.group_leader.tty\" | \"process.group_leader.user.id\" | \"process.group_leader.user.name\" | \"process.group_leader.vpid\" | \"process.group_leader.working_directory\" | \"process.hash.md5\" | \"process.hash.sha1\" | \"process.hash.sha256\" | \"process.hash.sha384\" | \"process.hash.sha512\" | \"process.hash.ssdeep\" | \"process.hash.tlsh\" | \"process.interactive\" | \"process.io\" | \"process.macho.go_import_hash\" | \"process.macho.go_imports\" | \"process.macho.go_imports_names_entropy\" | \"process.macho.go_imports_names_var_entropy\" | \"process.macho.go_stripped\" | \"process.macho.import_hash\" | \"process.macho.imports\" | \"process.macho.imports_names_entropy\" | \"process.macho.imports_names_var_entropy\" | \"process.macho.sections\" | \"process.macho.symhash\" | \"process.name\" | \"process.parent.args\" | \"process.parent.args_count\" | \"process.parent.code_signature.digest_algorithm\" | \"process.parent.code_signature.exists\" | \"process.parent.code_signature.signing_id\" | \"process.parent.code_signature.status\" | \"process.parent.code_signature.subject_name\" | \"process.parent.code_signature.team_id\" | \"process.parent.code_signature.timestamp\" | \"process.parent.code_signature.trusted\" | \"process.parent.code_signature.valid\" | \"process.parent.command_line\" | \"process.parent.elf.architecture\" | \"process.parent.elf.byte_order\" | \"process.parent.elf.cpu_type\" | \"process.parent.elf.creation_date\" | \"process.parent.elf.exports\" | \"process.parent.elf.go_import_hash\" | \"process.parent.elf.go_imports\" | \"process.parent.elf.go_imports_names_entropy\" | \"process.parent.elf.go_imports_names_var_entropy\" | \"process.parent.elf.go_stripped\" | \"process.parent.elf.header.abi_version\" | \"process.parent.elf.header.class\" | \"process.parent.elf.header.data\" | \"process.parent.elf.header.entrypoint\" | \"process.parent.elf.header.object_version\" | \"process.parent.elf.header.os_abi\" | \"process.parent.elf.header.type\" | \"process.parent.elf.header.version\" | \"process.parent.elf.import_hash\" | \"process.parent.elf.imports\" | \"process.parent.elf.imports_names_entropy\" | \"process.parent.elf.imports_names_var_entropy\" | \"process.parent.elf.sections\" | \"process.parent.elf.segments\" | \"process.parent.elf.shared_libraries\" | \"process.parent.elf.telfhash\" | \"process.parent.end\" | \"process.parent.entity_id\" | \"process.parent.executable\" | \"process.parent.exit_code\" | \"process.parent.group.id\" | \"process.parent.group.name\" | \"process.parent.group_leader.entity_id\" | \"process.parent.group_leader.pid\" | \"process.parent.group_leader.start\" | \"process.parent.group_leader.vpid\" | \"process.parent.hash.md5\" | \"process.parent.hash.sha1\" | \"process.parent.hash.sha256\" | \"process.parent.hash.sha384\" | \"process.parent.hash.sha512\" | \"process.parent.hash.ssdeep\" | \"process.parent.hash.tlsh\" | \"process.parent.interactive\" | \"process.parent.macho.go_import_hash\" | \"process.parent.macho.go_imports\" | \"process.parent.macho.go_imports_names_entropy\" | \"process.parent.macho.go_imports_names_var_entropy\" | \"process.parent.macho.go_stripped\" | \"process.parent.macho.import_hash\" | \"process.parent.macho.imports\" | \"process.parent.macho.imports_names_entropy\" | \"process.parent.macho.imports_names_var_entropy\" | \"process.parent.macho.sections\" | \"process.parent.macho.symhash\" | \"process.parent.name\" | \"process.parent.pe.architecture\" | \"process.parent.pe.company\" | \"process.parent.pe.description\" | \"process.parent.pe.file_version\" | \"process.parent.pe.go_import_hash\" | \"process.parent.pe.go_imports\" | \"process.parent.pe.go_imports_names_entropy\" | \"process.parent.pe.go_imports_names_var_entropy\" | \"process.parent.pe.go_stripped\" | \"process.parent.pe.imphash\" | \"process.parent.pe.import_hash\" | \"process.parent.pe.imports\" | \"process.parent.pe.imports_names_entropy\" | \"process.parent.pe.imports_names_var_entropy\" | \"process.parent.pe.original_file_name\" | \"process.parent.pe.pehash\" | \"process.parent.pe.product\" | \"process.parent.pe.sections\" | \"process.parent.pgid\" | \"process.parent.pid\" | \"process.parent.real_group.id\" | \"process.parent.real_group.name\" | \"process.parent.real_user.id\" | \"process.parent.real_user.name\" | \"process.parent.saved_group.id\" | \"process.parent.saved_group.name\" | \"process.parent.saved_user.id\" | \"process.parent.saved_user.name\" | \"process.parent.start\" | \"process.parent.supplemental_groups.id\" | \"process.parent.supplemental_groups.name\" | \"process.parent.thread.capabilities.effective\" | \"process.parent.thread.capabilities.permitted\" | \"process.parent.thread.id\" | \"process.parent.thread.name\" | \"process.parent.title\" | \"process.parent.tty\" | \"process.parent.uptime\" | \"process.parent.user.id\" | \"process.parent.user.name\" | \"process.parent.vpid\" | \"process.parent.working_directory\" | \"process.pe.architecture\" | \"process.pe.company\" | \"process.pe.description\" | \"process.pe.file_version\" | \"process.pe.go_import_hash\" | \"process.pe.go_imports\" | \"process.pe.go_imports_names_entropy\" | \"process.pe.go_imports_names_var_entropy\" | \"process.pe.go_stripped\" | \"process.pe.imphash\" | \"process.pe.import_hash\" | \"process.pe.imports\" | \"process.pe.imports_names_entropy\" | \"process.pe.imports_names_var_entropy\" | \"process.pe.original_file_name\" | \"process.pe.pehash\" | \"process.pe.product\" | \"process.pe.sections\" | \"process.pgid\" | \"process.pid\" | \"process.previous.args\" | \"process.previous.args_count\" | \"process.previous.executable\" | \"process.real_group.id\" | \"process.real_group.name\" | \"process.real_user.id\" | \"process.real_user.name\" | \"process.saved_group.id\" | \"process.saved_group.name\" | \"process.saved_user.id\" | \"process.saved_user.name\" | \"process.session_leader.args\" | \"process.session_leader.args_count\" | \"process.session_leader.command_line\" | \"process.session_leader.entity_id\" | \"process.session_leader.executable\" | \"process.session_leader.group.id\" | \"process.session_leader.group.name\" | \"process.session_leader.interactive\" | \"process.session_leader.name\" | \"process.session_leader.parent.entity_id\" | \"process.session_leader.parent.pid\" | \"process.session_leader.parent.session_leader.entity_id\" | \"process.session_leader.parent.session_leader.pid\" | \"process.session_leader.parent.session_leader.start\" | \"process.session_leader.parent.session_leader.vpid\" | \"process.session_leader.parent.start\" | \"process.session_leader.parent.vpid\" | \"process.session_leader.pid\" | \"process.session_leader.real_group.id\" | \"process.session_leader.real_group.name\" | \"process.session_leader.real_user.id\" | \"process.session_leader.real_user.name\" | \"process.session_leader.same_as_process\" | \"process.session_leader.saved_group.id\" | \"process.session_leader.saved_group.name\" | \"process.session_leader.saved_user.id\" | \"process.session_leader.saved_user.name\" | \"process.session_leader.start\" | \"process.session_leader.supplemental_groups.id\" | \"process.session_leader.supplemental_groups.name\" | \"process.session_leader.tty\" | \"process.session_leader.user.id\" | \"process.session_leader.user.name\" | \"process.session_leader.vpid\" | \"process.session_leader.working_directory\" | \"process.start\" | \"process.supplemental_groups.id\" | \"process.supplemental_groups.name\" | \"process.thread.capabilities.effective\" | \"process.thread.capabilities.permitted\" | \"process.thread.id\" | \"process.thread.name\" | \"process.title\" | \"process.tty\" | \"process.uptime\" | \"process.user.id\" | \"process.user.name\" | \"process.vpid\" | \"process.working_directory\" | \"registry.data.bytes\" | \"registry.data.strings\" | \"registry.data.type\" | \"registry.hive\" | \"registry.key\" | \"registry.path\" | \"registry.value\" | \"related.hash\" | \"related.hosts\" | \"related.ip\" | \"related.user\" | \"rule.author\" | \"rule.category\" | \"rule.description\" | \"rule.id\" | \"rule.license\" | \"rule.name\" | \"rule.reference\" | \"rule.ruleset\" | \"rule.uuid\" | \"rule.version\" | \"server.address\" | \"server.as.number\" | \"server.as.organization.name\" | \"server.bytes\" | \"server.domain\" | \"server.geo.city_name\" | \"server.geo.continent_code\" | \"server.geo.continent_name\" | \"server.geo.country_iso_code\" | \"server.geo.country_name\" | \"server.geo.location\" | \"server.geo.name\" | \"server.geo.postal_code\" | \"server.geo.region_iso_code\" | \"server.geo.region_name\" | \"server.geo.timezone\" | \"server.ip\" | \"server.mac\" | \"server.nat.ip\" | \"server.nat.port\" | \"server.packets\" | \"server.port\" | \"server.registered_domain\" | \"server.subdomain\" | \"server.top_level_domain\" | \"server.user.domain\" | \"server.user.email\" | \"server.user.full_name\" | \"server.user.group.domain\" | \"server.user.group.id\" | \"server.user.group.name\" | \"server.user.hash\" | \"server.user.id\" | \"server.user.name\" | \"server.user.roles\" | \"service.address\" | \"service.ephemeral_id\" | \"service.id\" | \"service.node.name\" | \"service.node.role\" | \"service.node.roles\" | \"service.origin.address\" | \"service.origin.environment\" | \"service.origin.ephemeral_id\" | \"service.origin.id\" | \"service.origin.name\" | \"service.origin.node.name\" | \"service.origin.node.role\" | \"service.origin.node.roles\" | \"service.origin.state\" | \"service.origin.type\" | \"service.origin.version\" | \"service.state\" | \"service.target.address\" | \"service.target.environment\" | \"service.target.ephemeral_id\" | \"service.target.id\" | \"service.target.name\" | \"service.target.node.name\" | \"service.target.node.role\" | \"service.target.node.roles\" | \"service.target.state\" | \"service.target.type\" | \"service.target.version\" | \"service.type\" | \"service.version\" | \"source.address\" | \"source.as.number\" | \"source.as.organization.name\" | \"source.bytes\" | \"source.domain\" | \"source.geo.city_name\" | \"source.geo.continent_code\" | \"source.geo.continent_name\" | \"source.geo.country_iso_code\" | \"source.geo.country_name\" | \"source.geo.location\" | \"source.geo.name\" | \"source.geo.postal_code\" | \"source.geo.region_iso_code\" | \"source.geo.region_name\" | \"source.geo.timezone\" | \"source.ip\" | \"source.mac\" | \"source.nat.ip\" | \"source.nat.port\" | \"source.packets\" | \"source.port\" | \"source.registered_domain\" | \"source.subdomain\" | \"source.top_level_domain\" | \"source.user.domain\" | \"source.user.email\" | \"source.user.full_name\" | \"source.user.group.domain\" | \"source.user.group.id\" | \"source.user.group.name\" | \"source.user.hash\" | \"source.user.id\" | \"source.user.name\" | \"source.user.roles\" | \"span.id\" | \"threat.enrichments\" | \"threat.feed.dashboard_id\" | \"threat.feed.description\" | \"threat.feed.name\" | \"threat.feed.reference\" | \"threat.framework\" | \"threat.group.alias\" | \"threat.group.id\" | \"threat.group.name\" | \"threat.group.reference\" | \"threat.indicator.as.number\" | \"threat.indicator.as.organization.name\" | \"threat.indicator.confidence\" | \"threat.indicator.description\" | \"threat.indicator.email.address\" | \"threat.indicator.file.accessed\" | \"threat.indicator.file.attributes\" | \"threat.indicator.file.code_signature.digest_algorithm\" | \"threat.indicator.file.code_signature.exists\" | \"threat.indicator.file.code_signature.signing_id\" | \"threat.indicator.file.code_signature.status\" | \"threat.indicator.file.code_signature.subject_name\" | \"threat.indicator.file.code_signature.team_id\" | \"threat.indicator.file.code_signature.timestamp\" | \"threat.indicator.file.code_signature.trusted\" | \"threat.indicator.file.code_signature.valid\" | \"threat.indicator.file.created\" | \"threat.indicator.file.ctime\" | \"threat.indicator.file.device\" | \"threat.indicator.file.directory\" | \"threat.indicator.file.drive_letter\" | \"threat.indicator.file.elf.architecture\" | \"threat.indicator.file.elf.byte_order\" | \"threat.indicator.file.elf.cpu_type\" | \"threat.indicator.file.elf.creation_date\" | \"threat.indicator.file.elf.exports\" | \"threat.indicator.file.elf.go_import_hash\" | \"threat.indicator.file.elf.go_imports\" | \"threat.indicator.file.elf.go_imports_names_entropy\" | \"threat.indicator.file.elf.go_imports_names_var_entropy\" | \"threat.indicator.file.elf.go_stripped\" | \"threat.indicator.file.elf.header.abi_version\" | \"threat.indicator.file.elf.header.class\" | \"threat.indicator.file.elf.header.data\" | \"threat.indicator.file.elf.header.entrypoint\" | \"threat.indicator.file.elf.header.object_version\" | \"threat.indicator.file.elf.header.os_abi\" | \"threat.indicator.file.elf.header.type\" | \"threat.indicator.file.elf.header.version\" | \"threat.indicator.file.elf.import_hash\" | \"threat.indicator.file.elf.imports\" | \"threat.indicator.file.elf.imports_names_entropy\" | \"threat.indicator.file.elf.imports_names_var_entropy\" | \"threat.indicator.file.elf.sections\" | \"threat.indicator.file.elf.segments\" | \"threat.indicator.file.elf.shared_libraries\" | \"threat.indicator.file.elf.telfhash\" | \"threat.indicator.file.extension\" | \"threat.indicator.file.fork_name\" | \"threat.indicator.file.gid\" | \"threat.indicator.file.group\" | \"threat.indicator.file.hash.md5\" | \"threat.indicator.file.hash.sha1\" | \"threat.indicator.file.hash.sha256\" | \"threat.indicator.file.hash.sha384\" | \"threat.indicator.file.hash.sha512\" | \"threat.indicator.file.hash.ssdeep\" | \"threat.indicator.file.hash.tlsh\" | \"threat.indicator.file.inode\" | \"threat.indicator.file.mime_type\" | \"threat.indicator.file.mode\" | \"threat.indicator.file.mtime\" | \"threat.indicator.file.name\" | \"threat.indicator.file.owner\" | \"threat.indicator.file.path\" | \"threat.indicator.file.pe.architecture\" | \"threat.indicator.file.pe.company\" | \"threat.indicator.file.pe.description\" | \"threat.indicator.file.pe.file_version\" | \"threat.indicator.file.pe.go_import_hash\" | \"threat.indicator.file.pe.go_imports\" | \"threat.indicator.file.pe.go_imports_names_entropy\" | \"threat.indicator.file.pe.go_imports_names_var_entropy\" | \"threat.indicator.file.pe.go_stripped\" | \"threat.indicator.file.pe.imphash\" | \"threat.indicator.file.pe.import_hash\" | \"threat.indicator.file.pe.imports\" | \"threat.indicator.file.pe.imports_names_entropy\" | \"threat.indicator.file.pe.imports_names_var_entropy\" | \"threat.indicator.file.pe.original_file_name\" | \"threat.indicator.file.pe.pehash\" | \"threat.indicator.file.pe.product\" | \"threat.indicator.file.pe.sections\" | \"threat.indicator.file.size\" | \"threat.indicator.file.target_path\" | \"threat.indicator.file.type\" | \"threat.indicator.file.uid\" | \"threat.indicator.file.x509.alternative_names\" | \"threat.indicator.file.x509.issuer.common_name\" | \"threat.indicator.file.x509.issuer.country\" | \"threat.indicator.file.x509.issuer.distinguished_name\" | \"threat.indicator.file.x509.issuer.locality\" | \"threat.indicator.file.x509.issuer.organization\" | \"threat.indicator.file.x509.issuer.organizational_unit\" | \"threat.indicator.file.x509.issuer.state_or_province\" | \"threat.indicator.file.x509.not_after\" | \"threat.indicator.file.x509.not_before\" | \"threat.indicator.file.x509.public_key_algorithm\" | \"threat.indicator.file.x509.public_key_curve\" | \"threat.indicator.file.x509.public_key_exponent\" | \"threat.indicator.file.x509.public_key_size\" | \"threat.indicator.file.x509.serial_number\" | \"threat.indicator.file.x509.signature_algorithm\" | \"threat.indicator.file.x509.subject.common_name\" | \"threat.indicator.file.x509.subject.country\" | \"threat.indicator.file.x509.subject.distinguished_name\" | \"threat.indicator.file.x509.subject.locality\" | \"threat.indicator.file.x509.subject.organization\" | \"threat.indicator.file.x509.subject.organizational_unit\" | \"threat.indicator.file.x509.subject.state_or_province\" | \"threat.indicator.file.x509.version_number\" | \"threat.indicator.first_seen\" | \"threat.indicator.geo.city_name\" | \"threat.indicator.geo.continent_code\" | \"threat.indicator.geo.continent_name\" | \"threat.indicator.geo.country_iso_code\" | \"threat.indicator.geo.country_name\" | \"threat.indicator.geo.location\" | \"threat.indicator.geo.name\" | \"threat.indicator.geo.postal_code\" | \"threat.indicator.geo.region_iso_code\" | \"threat.indicator.geo.region_name\" | \"threat.indicator.geo.timezone\" | \"threat.indicator.ip\" | \"threat.indicator.last_seen\" | \"threat.indicator.marking.tlp\" | \"threat.indicator.marking.tlp_version\" | \"threat.indicator.modified_at\" | \"threat.indicator.name\" | \"threat.indicator.port\" | \"threat.indicator.provider\" | \"threat.indicator.reference\" | \"threat.indicator.registry.data.bytes\" | \"threat.indicator.registry.data.strings\" | \"threat.indicator.registry.data.type\" | \"threat.indicator.registry.hive\" | \"threat.indicator.registry.key\" | \"threat.indicator.registry.path\" | \"threat.indicator.registry.value\" | \"threat.indicator.scanner_stats\" | \"threat.indicator.sightings\" | \"threat.indicator.type\" | \"threat.indicator.url.domain\" | \"threat.indicator.url.extension\" | \"threat.indicator.url.fragment\" | \"threat.indicator.url.full\" | \"threat.indicator.url.original\" | \"threat.indicator.url.password\" | \"threat.indicator.url.path\" | \"threat.indicator.url.port\" | \"threat.indicator.url.query\" | \"threat.indicator.url.registered_domain\" | \"threat.indicator.url.scheme\" | \"threat.indicator.url.subdomain\" | \"threat.indicator.url.top_level_domain\" | \"threat.indicator.url.username\" | \"threat.indicator.x509.alternative_names\" | \"threat.indicator.x509.issuer.common_name\" | \"threat.indicator.x509.issuer.country\" | \"threat.indicator.x509.issuer.distinguished_name\" | \"threat.indicator.x509.issuer.locality\" | \"threat.indicator.x509.issuer.organization\" | \"threat.indicator.x509.issuer.organizational_unit\" | \"threat.indicator.x509.issuer.state_or_province\" | \"threat.indicator.x509.not_after\" | \"threat.indicator.x509.not_before\" | \"threat.indicator.x509.public_key_algorithm\" | \"threat.indicator.x509.public_key_curve\" | \"threat.indicator.x509.public_key_exponent\" | \"threat.indicator.x509.public_key_size\" | \"threat.indicator.x509.serial_number\" | \"threat.indicator.x509.signature_algorithm\" | \"threat.indicator.x509.subject.common_name\" | \"threat.indicator.x509.subject.country\" | \"threat.indicator.x509.subject.distinguished_name\" | \"threat.indicator.x509.subject.locality\" | \"threat.indicator.x509.subject.organization\" | \"threat.indicator.x509.subject.organizational_unit\" | \"threat.indicator.x509.subject.state_or_province\" | \"threat.indicator.x509.version_number\" | \"threat.software.alias\" | \"threat.software.id\" | \"threat.software.name\" | \"threat.software.platforms\" | \"threat.software.reference\" | \"threat.software.type\" | \"threat.tactic.id\" | \"threat.tactic.name\" | \"threat.tactic.reference\" | \"threat.technique.id\" | \"threat.technique.name\" | \"threat.technique.reference\" | \"threat.technique.subtechnique.id\" | \"threat.technique.subtechnique.name\" | \"threat.technique.subtechnique.reference\" | \"tls.cipher\" | \"tls.client.certificate\" | \"tls.client.certificate_chain\" | \"tls.client.hash.md5\" | \"tls.client.hash.sha1\" | \"tls.client.hash.sha256\" | \"tls.client.issuer\" | \"tls.client.ja3\" | \"tls.client.not_after\" | \"tls.client.not_before\" | \"tls.client.server_name\" | \"tls.client.subject\" | \"tls.client.supported_ciphers\" | \"tls.client.x509.alternative_names\" | \"tls.client.x509.issuer.common_name\" | \"tls.client.x509.issuer.country\" | \"tls.client.x509.issuer.distinguished_name\" | \"tls.client.x509.issuer.locality\" | \"tls.client.x509.issuer.organization\" | \"tls.client.x509.issuer.organizational_unit\" | \"tls.client.x509.issuer.state_or_province\" | \"tls.client.x509.not_after\" | \"tls.client.x509.not_before\" | \"tls.client.x509.public_key_algorithm\" | \"tls.client.x509.public_key_curve\" | \"tls.client.x509.public_key_exponent\" | \"tls.client.x509.public_key_size\" | \"tls.client.x509.serial_number\" | \"tls.client.x509.signature_algorithm\" | \"tls.client.x509.subject.common_name\" | \"tls.client.x509.subject.country\" | \"tls.client.x509.subject.distinguished_name\" | \"tls.client.x509.subject.locality\" | \"tls.client.x509.subject.organization\" | \"tls.client.x509.subject.organizational_unit\" | \"tls.client.x509.subject.state_or_province\" | \"tls.client.x509.version_number\" | \"tls.curve\" | \"tls.established\" | \"tls.next_protocol\" | \"tls.resumed\" | \"tls.server.certificate\" | \"tls.server.certificate_chain\" | \"tls.server.hash.md5\" | \"tls.server.hash.sha1\" | \"tls.server.hash.sha256\" | \"tls.server.issuer\" | \"tls.server.ja3s\" | \"tls.server.not_after\" | \"tls.server.not_before\" | \"tls.server.subject\" | \"tls.server.x509.alternative_names\" | \"tls.server.x509.issuer.common_name\" | \"tls.server.x509.issuer.country\" | \"tls.server.x509.issuer.distinguished_name\" | \"tls.server.x509.issuer.locality\" | \"tls.server.x509.issuer.organization\" | \"tls.server.x509.issuer.organizational_unit\" | \"tls.server.x509.issuer.state_or_province\" | \"tls.server.x509.not_after\" | \"tls.server.x509.not_before\" | \"tls.server.x509.public_key_algorithm\" | \"tls.server.x509.public_key_curve\" | \"tls.server.x509.public_key_exponent\" | \"tls.server.x509.public_key_size\" | \"tls.server.x509.serial_number\" | \"tls.server.x509.signature_algorithm\" | \"tls.server.x509.subject.common_name\" | \"tls.server.x509.subject.country\" | \"tls.server.x509.subject.distinguished_name\" | \"tls.server.x509.subject.locality\" | \"tls.server.x509.subject.organization\" | \"tls.server.x509.subject.organizational_unit\" | \"tls.server.x509.subject.state_or_province\" | \"tls.server.x509.version_number\" | \"tls.version\" | \"tls.version_protocol\" | \"trace.id\" | \"transaction.id\" | \"url.domain\" | \"url.extension\" | \"url.fragment\" | \"url.full\" | \"url.original\" | \"url.password\" | \"url.path\" | \"url.port\" | \"url.query\" | \"url.registered_domain\" | \"url.scheme\" | \"url.subdomain\" | \"url.top_level_domain\" | \"url.username\" | \"user.changes.domain\" | \"user.changes.email\" | \"user.changes.full_name\" | \"user.changes.group.domain\" | \"user.changes.group.id\" | \"user.changes.group.name\" | \"user.changes.hash\" | \"user.changes.id\" | \"user.changes.name\" | \"user.changes.roles\" | \"user.domain\" | \"user.effective.domain\" | \"user.effective.email\" | \"user.effective.full_name\" | \"user.effective.group.domain\" | \"user.effective.group.id\" | \"user.effective.group.name\" | \"user.effective.hash\" | \"user.effective.id\" | \"user.effective.name\" | \"user.effective.roles\" | \"user.email\" | \"user.full_name\" | \"user.group.domain\" | \"user.group.id\" | \"user.group.name\" | \"user.hash\" | \"user.id\" | \"user.name\" | \"user.risk.calculated_level\" | \"user.risk.calculated_score\" | \"user.risk.calculated_score_norm\" | \"user.risk.static_level\" | \"user.risk.static_score\" | \"user.risk.static_score_norm\" | \"user.roles\" | \"user.target.domain\" | \"user.target.email\" | \"user.target.full_name\" | \"user.target.group.domain\" | \"user.target.group.id\" | \"user.target.group.name\" | \"user.target.hash\" | \"user.target.id\" | \"user.target.name\" | \"user.target.roles\" | \"user_agent.device.name\" | \"user_agent.name\" | \"user_agent.original\" | \"user_agent.os.family\" | \"user_agent.os.full\" | \"user_agent.os.kernel\" | \"user_agent.os.name\" | \"user_agent.os.platform\" | \"user_agent.os.type\" | \"user_agent.os.version\" | \"user_agent.version\" | \"vulnerability.category\" | \"vulnerability.classification\" | \"vulnerability.description\" | \"vulnerability.enumeration\" | \"vulnerability.id\" | \"vulnerability.reference\" | \"vulnerability.report_id\" | \"vulnerability.scanner.vendor\" | \"vulnerability.score.base\" | \"vulnerability.score.environmental\" | \"vulnerability.score.temporal\" | \"vulnerability.score.version\" | \"vulnerability.severity\" | \"data_stream.dataset\" | \"data_stream.namespace\" | \"data_stream.type\" | \"dll.pe.sections.entropy\" | \"dll.pe.sections.name\" | \"dll.pe.sections.physical_size\" | \"dll.pe.sections.var_entropy\" | \"dll.pe.sections.virtual_size\" | \"dns.answers.class\" | \"dns.answers.data\" | \"dns.answers.name\" | \"dns.answers.ttl\" | \"dns.answers.type\" | \"email.attachments.file.extension\" | \"email.attachments.file.hash.md5\" | \"email.attachments.file.hash.sha1\" | \"email.attachments.file.hash.sha256\" | \"email.attachments.file.hash.sha384\" | \"email.attachments.file.hash.sha512\" | \"email.attachments.file.hash.ssdeep\" | \"email.attachments.file.hash.tlsh\" | \"email.attachments.file.mime_type\" | \"email.attachments.file.name\" | \"email.attachments.file.size\" | \"faas.trigger.request_id\" | \"faas.trigger.type\" | \"file.elf.sections.chi2\" | \"file.elf.sections.entropy\" | \"file.elf.sections.flags\" | \"file.elf.sections.name\" | \"file.elf.sections.physical_offset\" | \"file.elf.sections.physical_size\" | \"file.elf.sections.type\" | \"file.elf.sections.var_entropy\" | \"file.elf.sections.virtual_address\" | \"file.elf.sections.virtual_size\" | \"file.elf.segments.sections\" | \"file.elf.segments.type\" | \"file.macho.sections.entropy\" | \"file.macho.sections.name\" | \"file.macho.sections.physical_size\" | \"file.macho.sections.var_entropy\" | \"file.macho.sections.virtual_size\" | \"file.pe.sections.entropy\" | \"file.pe.sections.name\" | \"file.pe.sections.physical_size\" | \"file.pe.sections.var_entropy\" | \"file.pe.sections.virtual_size\" | \"log.syslog.appname\" | \"log.syslog.facility.code\" | \"log.syslog.facility.name\" | \"log.syslog.hostname\" | \"log.syslog.msgid\" | \"log.syslog.priority\" | \"log.syslog.procid\" | \"log.syslog.severity.code\" | \"log.syslog.severity.name\" | \"log.syslog.structured_data\" | \"log.syslog.version\" | \"network.inner.vlan.id\" | \"network.inner.vlan.name\" | \"observer.egress.interface.alias\" | \"observer.egress.interface.id\" | \"observer.egress.interface.name\" | \"observer.egress.vlan.id\" | \"observer.egress.vlan.name\" | \"observer.egress.zone\" | \"observer.ingress.interface.alias\" | \"observer.ingress.interface.id\" | \"observer.ingress.interface.name\" | \"observer.ingress.vlan.id\" | \"observer.ingress.vlan.name\" | \"observer.ingress.zone\" | \"process.elf.sections.chi2\" | \"process.elf.sections.entropy\" | \"process.elf.sections.flags\" | \"process.elf.sections.name\" | \"process.elf.sections.physical_offset\" | \"process.elf.sections.physical_size\" | \"process.elf.sections.type\" | \"process.elf.sections.var_entropy\" | \"process.elf.sections.virtual_address\" | \"process.elf.sections.virtual_size\" | \"process.elf.segments.sections\" | \"process.elf.segments.type\" | \"process.entry_leader.tty.char_device.major\" | \"process.entry_leader.tty.char_device.minor\" | \"process.group_leader.tty.char_device.major\" | \"process.group_leader.tty.char_device.minor\" | \"process.io.bytes_skipped\" | \"process.io.bytes_skipped.length\" | \"process.io.bytes_skipped.offset\" | \"process.io.max_bytes_per_process_exceeded\" | \"process.io.text\" | \"process.io.total_bytes_captured\" | \"process.io.total_bytes_skipped\" | \"process.io.type\" | \"process.macho.sections.entropy\" | \"process.macho.sections.name\" | \"process.macho.sections.physical_size\" | \"process.macho.sections.var_entropy\" | \"process.macho.sections.virtual_size\" | \"process.parent.elf.sections.chi2\" | \"process.parent.elf.sections.entropy\" | \"process.parent.elf.sections.flags\" | \"process.parent.elf.sections.name\" | \"process.parent.elf.sections.physical_offset\" | \"process.parent.elf.sections.physical_size\" | \"process.parent.elf.sections.type\" | \"process.parent.elf.sections.var_entropy\" | \"process.parent.elf.sections.virtual_address\" | \"process.parent.elf.sections.virtual_size\" | \"process.parent.elf.segments.sections\" | \"process.parent.elf.segments.type\" | \"process.parent.macho.sections.entropy\" | \"process.parent.macho.sections.name\" | \"process.parent.macho.sections.physical_size\" | \"process.parent.macho.sections.var_entropy\" | \"process.parent.macho.sections.virtual_size\" | \"process.parent.pe.sections.entropy\" | \"process.parent.pe.sections.name\" | \"process.parent.pe.sections.physical_size\" | \"process.parent.pe.sections.var_entropy\" | \"process.parent.pe.sections.virtual_size\" | \"process.parent.tty.char_device.major\" | \"process.parent.tty.char_device.minor\" | \"process.pe.sections.entropy\" | \"process.pe.sections.name\" | \"process.pe.sections.physical_size\" | \"process.pe.sections.var_entropy\" | \"process.pe.sections.virtual_size\" | \"process.session_leader.tty.char_device.major\" | \"process.session_leader.tty.char_device.minor\" | \"process.tty.char_device.major\" | \"process.tty.char_device.minor\" | \"process.tty.columns\" | \"process.tty.rows\" | \"threat.enrichments.indicator\" | \"threat.enrichments.indicator.as.number\" | \"threat.enrichments.indicator.as.organization.name\" | \"threat.enrichments.indicator.confidence\" | \"threat.enrichments.indicator.description\" | \"threat.enrichments.indicator.email.address\" | \"threat.enrichments.indicator.file.accessed\" | \"threat.enrichments.indicator.file.attributes\" | \"threat.enrichments.indicator.file.code_signature.digest_algorithm\" | \"threat.enrichments.indicator.file.code_signature.exists\" | \"threat.enrichments.indicator.file.code_signature.signing_id\" | \"threat.enrichments.indicator.file.code_signature.status\" | \"threat.enrichments.indicator.file.code_signature.subject_name\" | \"threat.enrichments.indicator.file.code_signature.team_id\" | \"threat.enrichments.indicator.file.code_signature.timestamp\" | \"threat.enrichments.indicator.file.code_signature.trusted\" | \"threat.enrichments.indicator.file.code_signature.valid\" | \"threat.enrichments.indicator.file.created\" | \"threat.enrichments.indicator.file.ctime\" | \"threat.enrichments.indicator.file.device\" | \"threat.enrichments.indicator.file.directory\" | \"threat.enrichments.indicator.file.drive_letter\" | \"threat.enrichments.indicator.file.elf.architecture\" | \"threat.enrichments.indicator.file.elf.byte_order\" | \"threat.enrichments.indicator.file.elf.cpu_type\" | \"threat.enrichments.indicator.file.elf.creation_date\" | \"threat.enrichments.indicator.file.elf.exports\" | \"threat.enrichments.indicator.file.elf.go_import_hash\" | \"threat.enrichments.indicator.file.elf.go_imports\" | \"threat.enrichments.indicator.file.elf.go_imports_names_entropy\" | \"threat.enrichments.indicator.file.elf.go_imports_names_var_entropy\" | \"threat.enrichments.indicator.file.elf.go_stripped\" | \"threat.enrichments.indicator.file.elf.header.abi_version\" | \"threat.enrichments.indicator.file.elf.header.class\" | \"threat.enrichments.indicator.file.elf.header.data\" | \"threat.enrichments.indicator.file.elf.header.entrypoint\" | \"threat.enrichments.indicator.file.elf.header.object_version\" | \"threat.enrichments.indicator.file.elf.header.os_abi\" | \"threat.enrichments.indicator.file.elf.header.type\" | \"threat.enrichments.indicator.file.elf.header.version\" | \"threat.enrichments.indicator.file.elf.import_hash\" | \"threat.enrichments.indicator.file.elf.imports\" | \"threat.enrichments.indicator.file.elf.imports_names_entropy\" | \"threat.enrichments.indicator.file.elf.imports_names_var_entropy\" | \"threat.enrichments.indicator.file.elf.sections\" | \"threat.enrichments.indicator.file.elf.sections.chi2\" | \"threat.enrichments.indicator.file.elf.sections.entropy\" | \"threat.enrichments.indicator.file.elf.sections.flags\" | \"threat.enrichments.indicator.file.elf.sections.name\" | \"threat.enrichments.indicator.file.elf.sections.physical_offset\" | \"threat.enrichments.indicator.file.elf.sections.physical_size\" | \"threat.enrichments.indicator.file.elf.sections.type\" | \"threat.enrichments.indicator.file.elf.sections.var_entropy\" | \"threat.enrichments.indicator.file.elf.sections.virtual_address\" | \"threat.enrichments.indicator.file.elf.sections.virtual_size\" | \"threat.enrichments.indicator.file.elf.segments\" | \"threat.enrichments.indicator.file.elf.segments.sections\" | \"threat.enrichments.indicator.file.elf.segments.type\" | \"threat.enrichments.indicator.file.elf.shared_libraries\" | \"threat.enrichments.indicator.file.elf.telfhash\" | \"threat.enrichments.indicator.file.extension\" | \"threat.enrichments.indicator.file.fork_name\" | \"threat.enrichments.indicator.file.gid\" | \"threat.enrichments.indicator.file.group\" | \"threat.enrichments.indicator.file.hash.md5\" | \"threat.enrichments.indicator.file.hash.sha1\" | \"threat.enrichments.indicator.file.hash.sha256\" | \"threat.enrichments.indicator.file.hash.sha384\" | \"threat.enrichments.indicator.file.hash.sha512\" | \"threat.enrichments.indicator.file.hash.ssdeep\" | \"threat.enrichments.indicator.file.hash.tlsh\" | \"threat.enrichments.indicator.file.inode\" | \"threat.enrichments.indicator.file.mime_type\" | \"threat.enrichments.indicator.file.mode\" | \"threat.enrichments.indicator.file.mtime\" | \"threat.enrichments.indicator.file.name\" | \"threat.enrichments.indicator.file.owner\" | \"threat.enrichments.indicator.file.path\" | \"threat.enrichments.indicator.file.pe.architecture\" | \"threat.enrichments.indicator.file.pe.company\" | \"threat.enrichments.indicator.file.pe.description\" | \"threat.enrichments.indicator.file.pe.file_version\" | \"threat.enrichments.indicator.file.pe.go_import_hash\" | \"threat.enrichments.indicator.file.pe.go_imports\" | \"threat.enrichments.indicator.file.pe.go_imports_names_entropy\" | \"threat.enrichments.indicator.file.pe.go_imports_names_var_entropy\" | \"threat.enrichments.indicator.file.pe.go_stripped\" | \"threat.enrichments.indicator.file.pe.imphash\" | \"threat.enrichments.indicator.file.pe.import_hash\" | \"threat.enrichments.indicator.file.pe.imports\" | \"threat.enrichments.indicator.file.pe.imports_names_entropy\" | \"threat.enrichments.indicator.file.pe.imports_names_var_entropy\" | \"threat.enrichments.indicator.file.pe.original_file_name\" | \"threat.enrichments.indicator.file.pe.pehash\" | \"threat.enrichments.indicator.file.pe.product\" | \"threat.enrichments.indicator.file.pe.sections\" | \"threat.enrichments.indicator.file.pe.sections.entropy\" | \"threat.enrichments.indicator.file.pe.sections.name\" | \"threat.enrichments.indicator.file.pe.sections.physical_size\" | \"threat.enrichments.indicator.file.pe.sections.var_entropy\" | \"threat.enrichments.indicator.file.pe.sections.virtual_size\" | \"threat.enrichments.indicator.file.size\" | \"threat.enrichments.indicator.file.target_path\" | \"threat.enrichments.indicator.file.type\" | \"threat.enrichments.indicator.file.uid\" | \"threat.enrichments.indicator.file.x509.alternative_names\" | \"threat.enrichments.indicator.file.x509.issuer.common_name\" | \"threat.enrichments.indicator.file.x509.issuer.country\" | \"threat.enrichments.indicator.file.x509.issuer.distinguished_name\" | \"threat.enrichments.indicator.file.x509.issuer.locality\" | \"threat.enrichments.indicator.file.x509.issuer.organization\" | \"threat.enrichments.indicator.file.x509.issuer.organizational_unit\" | \"threat.enrichments.indicator.file.x509.issuer.state_or_province\" | \"threat.enrichments.indicator.file.x509.not_after\" | \"threat.enrichments.indicator.file.x509.not_before\" | \"threat.enrichments.indicator.file.x509.public_key_algorithm\" | \"threat.enrichments.indicator.file.x509.public_key_curve\" | \"threat.enrichments.indicator.file.x509.public_key_exponent\" | \"threat.enrichments.indicator.file.x509.public_key_size\" | \"threat.enrichments.indicator.file.x509.serial_number\" | \"threat.enrichments.indicator.file.x509.signature_algorithm\" | \"threat.enrichments.indicator.file.x509.subject.common_name\" | \"threat.enrichments.indicator.file.x509.subject.country\" | \"threat.enrichments.indicator.file.x509.subject.distinguished_name\" | \"threat.enrichments.indicator.file.x509.subject.locality\" | \"threat.enrichments.indicator.file.x509.subject.organization\" | \"threat.enrichments.indicator.file.x509.subject.organizational_unit\" | \"threat.enrichments.indicator.file.x509.subject.state_or_province\" | \"threat.enrichments.indicator.file.x509.version_number\" | \"threat.enrichments.indicator.first_seen\" | \"threat.enrichments.indicator.geo.city_name\" | \"threat.enrichments.indicator.geo.continent_code\" | \"threat.enrichments.indicator.geo.continent_name\" | \"threat.enrichments.indicator.geo.country_iso_code\" | \"threat.enrichments.indicator.geo.country_name\" | \"threat.enrichments.indicator.geo.location\" | \"threat.enrichments.indicator.geo.name\" | \"threat.enrichments.indicator.geo.postal_code\" | \"threat.enrichments.indicator.geo.region_iso_code\" | \"threat.enrichments.indicator.geo.region_name\" | \"threat.enrichments.indicator.geo.timezone\" | \"threat.enrichments.indicator.ip\" | \"threat.enrichments.indicator.last_seen\" | \"threat.enrichments.indicator.marking.tlp\" | \"threat.enrichments.indicator.marking.tlp_version\" | \"threat.enrichments.indicator.modified_at\" | \"threat.enrichments.indicator.name\" | \"threat.enrichments.indicator.port\" | \"threat.enrichments.indicator.provider\" | \"threat.enrichments.indicator.reference\" | \"threat.enrichments.indicator.registry.data.bytes\" | \"threat.enrichments.indicator.registry.data.strings\" | \"threat.enrichments.indicator.registry.data.type\" | \"threat.enrichments.indicator.registry.hive\" | \"threat.enrichments.indicator.registry.key\" | \"threat.enrichments.indicator.registry.path\" | \"threat.enrichments.indicator.registry.value\" | \"threat.enrichments.indicator.scanner_stats\" | \"threat.enrichments.indicator.sightings\" | \"threat.enrichments.indicator.type\" | \"threat.enrichments.indicator.url.domain\" | \"threat.enrichments.indicator.url.extension\" | \"threat.enrichments.indicator.url.fragment\" | \"threat.enrichments.indicator.url.full\" | \"threat.enrichments.indicator.url.original\" | \"threat.enrichments.indicator.url.password\" | \"threat.enrichments.indicator.url.path\" | \"threat.enrichments.indicator.url.port\" | \"threat.enrichments.indicator.url.query\" | \"threat.enrichments.indicator.url.registered_domain\" | \"threat.enrichments.indicator.url.scheme\" | \"threat.enrichments.indicator.url.subdomain\" | \"threat.enrichments.indicator.url.top_level_domain\" | \"threat.enrichments.indicator.url.username\" | \"threat.enrichments.indicator.x509.alternative_names\" | \"threat.enrichments.indicator.x509.issuer.common_name\" | \"threat.enrichments.indicator.x509.issuer.country\" | \"threat.enrichments.indicator.x509.issuer.distinguished_name\" | \"threat.enrichments.indicator.x509.issuer.locality\" | \"threat.enrichments.indicator.x509.issuer.organization\" | \"threat.enrichments.indicator.x509.issuer.organizational_unit\" | \"threat.enrichments.indicator.x509.issuer.state_or_province\" | \"threat.enrichments.indicator.x509.not_after\" | \"threat.enrichments.indicator.x509.not_before\" | \"threat.enrichments.indicator.x509.public_key_algorithm\" | \"threat.enrichments.indicator.x509.public_key_curve\" | \"threat.enrichments.indicator.x509.public_key_exponent\" | \"threat.enrichments.indicator.x509.public_key_size\" | \"threat.enrichments.indicator.x509.serial_number\" | \"threat.enrichments.indicator.x509.signature_algorithm\" | \"threat.enrichments.indicator.x509.subject.common_name\" | \"threat.enrichments.indicator.x509.subject.country\" | \"threat.enrichments.indicator.x509.subject.distinguished_name\" | \"threat.enrichments.indicator.x509.subject.locality\" | \"threat.enrichments.indicator.x509.subject.organization\" | \"threat.enrichments.indicator.x509.subject.organizational_unit\" | \"threat.enrichments.indicator.x509.subject.state_or_province\" | \"threat.enrichments.indicator.x509.version_number\" | \"threat.enrichments.matched.atomic\" | \"threat.enrichments.matched.field\" | \"threat.enrichments.matched.id\" | \"threat.enrichments.matched.index\" | \"threat.enrichments.matched.occurred\" | \"threat.enrichments.matched.type\" | \"threat.indicator.file.elf.sections.chi2\" | \"threat.indicator.file.elf.sections.entropy\" | \"threat.indicator.file.elf.sections.flags\" | \"threat.indicator.file.elf.sections.name\" | \"threat.indicator.file.elf.sections.physical_offset\" | \"threat.indicator.file.elf.sections.physical_size\" | \"threat.indicator.file.elf.sections.type\" | \"threat.indicator.file.elf.sections.var_entropy\" | \"threat.indicator.file.elf.sections.virtual_address\" | \"threat.indicator.file.elf.sections.virtual_size\" | \"threat.indicator.file.elf.segments.sections\" | \"threat.indicator.file.elf.segments.type\" | \"threat.indicator.file.pe.sections.entropy\" | \"threat.indicator.file.pe.sections.name\" | \"threat.indicator.file.pe.sections.physical_size\" | \"threat.indicator.file.pe.sections.var_entropy\" | \"threat.indicator.file.pe.sections.virtual_size\"" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldAttribute", + "type": "Type", + "tags": [], + "label": "FieldAttribute", + "description": [], + "signature": [ + "\"source\" | \"type\" | \"normalize\" | \"short\" | \"format\" | \"name\" | \"index\" | \"pattern\" | \"description\" | \"doc_values\" | \"ignore_above\" | \"beta\" | \"required\" | \"level\" | \"allowed_values\" | \"dashed_name\" | \"example\" | \"expected_values\" | \"flat_name\" | \"input_format\" | \"multi_fields\" | \"object_type\" | \"original_fieldset\" | \"output_format\" | \"output_precision\" | \"scaling_factor\"" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldMetadataPlain", + "type": "Type", + "tags": [], + "label": "FieldMetadataPlain", + "description": [], + "signature": [ + "{ name: string; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.FieldName", + "type": "Type", + "tags": [], + "label": "FieldName", + "description": [], + "signature": [ + "\"@timestamp\" | \"event.sequence\" | \"event.start\" | \"event.end\" | \"event.provider\" | \"event.duration\" | \"event.action\" | \"message\" | \"event.outcome\" | \"tags\" | \"event.kind\" | \"agent.name\" | \"container.id\" | \"host.name\" | \"labels\" | \"service.environment\" | \"service.name\" | \"ecs.version\" | \"agent.build.original\" | \"agent.ephemeral_id\" | \"agent.id\" | \"agent.type\" | \"agent.version\" | \"client.address\" | \"client.as.number\" | \"client.as.organization.name\" | \"client.bytes\" | \"client.domain\" | \"client.geo.city_name\" | \"client.geo.continent_code\" | \"client.geo.continent_name\" | \"client.geo.country_iso_code\" | \"client.geo.country_name\" | \"client.geo.location\" | \"client.geo.name\" | \"client.geo.postal_code\" | \"client.geo.region_iso_code\" | \"client.geo.region_name\" | \"client.geo.timezone\" | \"client.ip\" | \"client.mac\" | \"client.nat.ip\" | \"client.nat.port\" | \"client.packets\" | \"client.port\" | \"client.registered_domain\" | \"client.subdomain\" | \"client.top_level_domain\" | \"client.user.domain\" | \"client.user.email\" | \"client.user.full_name\" | \"client.user.group.domain\" | \"client.user.group.id\" | \"client.user.group.name\" | \"client.user.hash\" | \"client.user.id\" | \"client.user.name\" | \"client.user.roles\" | \"cloud.account.id\" | \"cloud.account.name\" | \"cloud.availability_zone\" | \"cloud.instance.id\" | \"cloud.instance.name\" | \"cloud.machine.type\" | \"cloud.origin.account.id\" | \"cloud.origin.account.name\" | \"cloud.origin.availability_zone\" | \"cloud.origin.instance.id\" | \"cloud.origin.instance.name\" | \"cloud.origin.machine.type\" | \"cloud.origin.project.id\" | \"cloud.origin.project.name\" | \"cloud.origin.provider\" | \"cloud.origin.region\" | \"cloud.origin.service.name\" | \"cloud.project.id\" | \"cloud.project.name\" | \"cloud.provider\" | \"cloud.region\" | \"cloud.service.name\" | \"cloud.target.account.id\" | \"cloud.target.account.name\" | \"cloud.target.availability_zone\" | \"cloud.target.instance.id\" | \"cloud.target.instance.name\" | \"cloud.target.machine.type\" | \"cloud.target.project.id\" | \"cloud.target.project.name\" | \"cloud.target.provider\" | \"cloud.target.region\" | \"cloud.target.service.name\" | \"container.cpu.usage\" | \"container.disk.read.bytes\" | \"container.disk.write.bytes\" | \"container.image.hash.all\" | \"container.image.name\" | \"container.image.tag\" | \"container.labels\" | \"container.memory.usage\" | \"container.name\" | \"container.network.egress.bytes\" | \"container.network.ingress.bytes\" | \"container.runtime\" | \"container.security_context.privileged\" | \"destination.address\" | \"destination.as.number\" | \"destination.as.organization.name\" | \"destination.bytes\" | \"destination.domain\" | \"destination.geo.city_name\" | \"destination.geo.continent_code\" | \"destination.geo.continent_name\" | \"destination.geo.country_iso_code\" | \"destination.geo.country_name\" | \"destination.geo.location\" | \"destination.geo.name\" | \"destination.geo.postal_code\" | \"destination.geo.region_iso_code\" | \"destination.geo.region_name\" | \"destination.geo.timezone\" | \"destination.ip\" | \"destination.mac\" | \"destination.nat.ip\" | \"destination.nat.port\" | \"destination.packets\" | \"destination.port\" | \"destination.registered_domain\" | \"destination.subdomain\" | \"destination.top_level_domain\" | \"destination.user.domain\" | \"destination.user.email\" | \"destination.user.full_name\" | \"destination.user.group.domain\" | \"destination.user.group.id\" | \"destination.user.group.name\" | \"destination.user.hash\" | \"destination.user.id\" | \"destination.user.name\" | \"destination.user.roles\" | \"device.id\" | \"device.manufacturer\" | \"device.model.identifier\" | \"device.model.name\" | \"dll.code_signature.digest_algorithm\" | \"dll.code_signature.exists\" | \"dll.code_signature.signing_id\" | \"dll.code_signature.status\" | \"dll.code_signature.subject_name\" | \"dll.code_signature.team_id\" | \"dll.code_signature.timestamp\" | \"dll.code_signature.trusted\" | \"dll.code_signature.valid\" | \"dll.hash.md5\" | \"dll.hash.sha1\" | \"dll.hash.sha256\" | \"dll.hash.sha384\" | \"dll.hash.sha512\" | \"dll.hash.ssdeep\" | \"dll.hash.tlsh\" | \"dll.name\" | \"dll.path\" | \"dll.pe.architecture\" | \"dll.pe.company\" | \"dll.pe.description\" | \"dll.pe.file_version\" | \"dll.pe.go_import_hash\" | \"dll.pe.go_imports\" | \"dll.pe.go_imports_names_entropy\" | \"dll.pe.go_imports_names_var_entropy\" | \"dll.pe.go_stripped\" | \"dll.pe.imphash\" | \"dll.pe.import_hash\" | \"dll.pe.imports\" | \"dll.pe.imports_names_entropy\" | \"dll.pe.imports_names_var_entropy\" | \"dll.pe.original_file_name\" | \"dll.pe.pehash\" | \"dll.pe.product\" | \"dll.pe.sections\" | \"dns.answers\" | \"dns.header_flags\" | \"dns.id\" | \"dns.op_code\" | \"dns.question.class\" | \"dns.question.name\" | \"dns.question.registered_domain\" | \"dns.question.subdomain\" | \"dns.question.top_level_domain\" | \"dns.question.type\" | \"dns.resolved_ip\" | \"dns.response_code\" | \"dns.type\" | \"email.attachments\" | \"file.extension\" | \"file.hash.md5\" | \"file.hash.sha1\" | \"file.hash.sha256\" | \"file.hash.sha384\" | \"file.hash.sha512\" | \"file.hash.ssdeep\" | \"file.hash.tlsh\" | \"file.mime_type\" | \"file.name\" | \"file.size\" | \"email.bcc.address\" | \"email.cc.address\" | \"email.content_type\" | \"email.delivery_timestamp\" | \"email.direction\" | \"email.from.address\" | \"email.local_id\" | \"email.message_id\" | \"email.origination_timestamp\" | \"email.reply_to.address\" | \"email.sender.address\" | \"email.subject\" | \"email.to.address\" | \"email.x_mailer\" | \"error.code\" | \"error.id\" | \"error.message\" | \"error.stack_trace\" | \"error.type\" | \"event.agent_id_status\" | \"event.category\" | \"event.code\" | \"event.created\" | \"event.dataset\" | \"event.hash\" | \"event.id\" | \"event.ingested\" | \"event.module\" | \"event.original\" | \"event.reason\" | \"event.reference\" | \"event.risk_score\" | \"event.risk_score_norm\" | \"event.severity\" | \"event.timezone\" | \"event.type\" | \"event.url\" | \"faas.coldstart\" | \"faas.execution\" | \"faas.id\" | \"faas.name\" | \"faas.version\" | \"file.accessed\" | \"file.attributes\" | \"file.code_signature.digest_algorithm\" | \"file.code_signature.exists\" | \"file.code_signature.signing_id\" | \"file.code_signature.status\" | \"file.code_signature.subject_name\" | \"file.code_signature.team_id\" | \"file.code_signature.timestamp\" | \"file.code_signature.trusted\" | \"file.code_signature.valid\" | \"file.created\" | \"file.ctime\" | \"file.device\" | \"file.directory\" | \"file.drive_letter\" | \"file.elf.architecture\" | \"file.elf.byte_order\" | \"file.elf.cpu_type\" | \"file.elf.creation_date\" | \"file.elf.exports\" | \"file.elf.go_import_hash\" | \"file.elf.go_imports\" | \"file.elf.go_imports_names_entropy\" | \"file.elf.go_imports_names_var_entropy\" | \"file.elf.go_stripped\" | \"file.elf.header.abi_version\" | \"file.elf.header.class\" | \"file.elf.header.data\" | \"file.elf.header.entrypoint\" | \"file.elf.header.object_version\" | \"file.elf.header.os_abi\" | \"file.elf.header.type\" | \"file.elf.header.version\" | \"file.elf.import_hash\" | \"file.elf.imports\" | \"file.elf.imports_names_entropy\" | \"file.elf.imports_names_var_entropy\" | \"file.elf.sections\" | \"file.elf.segments\" | \"file.elf.shared_libraries\" | \"file.elf.telfhash\" | \"file.fork_name\" | \"file.gid\" | \"file.group\" | \"file.inode\" | \"file.macho.go_import_hash\" | \"file.macho.go_imports\" | \"file.macho.go_imports_names_entropy\" | \"file.macho.go_imports_names_var_entropy\" | \"file.macho.go_stripped\" | \"file.macho.import_hash\" | \"file.macho.imports\" | \"file.macho.imports_names_entropy\" | \"file.macho.imports_names_var_entropy\" | \"file.macho.sections\" | \"file.macho.symhash\" | \"file.mode\" | \"file.mtime\" | \"file.owner\" | \"file.path\" | \"file.pe.architecture\" | \"file.pe.company\" | \"file.pe.description\" | \"file.pe.file_version\" | \"file.pe.go_import_hash\" | \"file.pe.go_imports\" | \"file.pe.go_imports_names_entropy\" | \"file.pe.go_imports_names_var_entropy\" | \"file.pe.go_stripped\" | \"file.pe.imphash\" | \"file.pe.import_hash\" | \"file.pe.imports\" | \"file.pe.imports_names_entropy\" | \"file.pe.imports_names_var_entropy\" | \"file.pe.original_file_name\" | \"file.pe.pehash\" | \"file.pe.product\" | \"file.pe.sections\" | \"file.target_path\" | \"file.type\" | \"file.uid\" | \"file.x509.alternative_names\" | \"file.x509.issuer.common_name\" | \"file.x509.issuer.country\" | \"file.x509.issuer.distinguished_name\" | \"file.x509.issuer.locality\" | \"file.x509.issuer.organization\" | \"file.x509.issuer.organizational_unit\" | \"file.x509.issuer.state_or_province\" | \"file.x509.not_after\" | \"file.x509.not_before\" | \"file.x509.public_key_algorithm\" | \"file.x509.public_key_curve\" | \"file.x509.public_key_exponent\" | \"file.x509.public_key_size\" | \"file.x509.serial_number\" | \"file.x509.signature_algorithm\" | \"file.x509.subject.common_name\" | \"file.x509.subject.country\" | \"file.x509.subject.distinguished_name\" | \"file.x509.subject.locality\" | \"file.x509.subject.organization\" | \"file.x509.subject.organizational_unit\" | \"file.x509.subject.state_or_province\" | \"file.x509.version_number\" | \"group.domain\" | \"group.id\" | \"group.name\" | \"host.architecture\" | \"host.boot.id\" | \"host.cpu.usage\" | \"host.disk.read.bytes\" | \"host.disk.write.bytes\" | \"host.domain\" | \"host.geo.city_name\" | \"host.geo.continent_code\" | \"host.geo.continent_name\" | \"host.geo.country_iso_code\" | \"host.geo.country_name\" | \"host.geo.location\" | \"host.geo.name\" | \"host.geo.postal_code\" | \"host.geo.region_iso_code\" | \"host.geo.region_name\" | \"host.geo.timezone\" | \"host.hostname\" | \"host.id\" | \"host.ip\" | \"host.mac\" | \"host.network.egress.bytes\" | \"host.network.egress.packets\" | \"host.network.ingress.bytes\" | \"host.network.ingress.packets\" | \"host.os.family\" | \"host.os.full\" | \"host.os.kernel\" | \"host.os.name\" | \"host.os.platform\" | \"host.os.type\" | \"host.os.version\" | \"host.pid_ns_ino\" | \"host.risk.calculated_level\" | \"host.risk.calculated_score\" | \"host.risk.calculated_score_norm\" | \"host.risk.static_level\" | \"host.risk.static_score\" | \"host.risk.static_score_norm\" | \"host.type\" | \"host.uptime\" | \"http.request.body.bytes\" | \"http.request.body.content\" | \"http.request.bytes\" | \"http.request.id\" | \"http.request.method\" | \"http.request.mime_type\" | \"http.request.referrer\" | \"http.response.body.bytes\" | \"http.response.body.content\" | \"http.response.bytes\" | \"http.response.mime_type\" | \"http.response.status_code\" | \"http.version\" | \"log.file.path\" | \"log.level\" | \"log.logger\" | \"log.origin.file.line\" | \"log.origin.file.name\" | \"log.origin.function\" | \"log.syslog\" | \"network.application\" | \"network.bytes\" | \"network.community_id\" | \"network.direction\" | \"network.forwarded_ip\" | \"network.iana_number\" | \"network.inner\" | \"network.name\" | \"network.packets\" | \"network.protocol\" | \"network.transport\" | \"network.type\" | \"network.vlan.id\" | \"network.vlan.name\" | \"observer.egress\" | \"observer.geo.city_name\" | \"observer.geo.continent_code\" | \"observer.geo.continent_name\" | \"observer.geo.country_iso_code\" | \"observer.geo.country_name\" | \"observer.geo.location\" | \"observer.geo.name\" | \"observer.geo.postal_code\" | \"observer.geo.region_iso_code\" | \"observer.geo.region_name\" | \"observer.geo.timezone\" | \"observer.hostname\" | \"observer.ingress\" | \"observer.ip\" | \"observer.mac\" | \"observer.name\" | \"observer.os.family\" | \"observer.os.full\" | \"observer.os.kernel\" | \"observer.os.name\" | \"observer.os.platform\" | \"observer.os.type\" | \"observer.os.version\" | \"observer.product\" | \"observer.serial_number\" | \"observer.type\" | \"observer.vendor\" | \"observer.version\" | \"orchestrator.api_version\" | \"orchestrator.cluster.id\" | \"orchestrator.cluster.name\" | \"orchestrator.cluster.url\" | \"orchestrator.cluster.version\" | \"orchestrator.namespace\" | \"orchestrator.organization\" | \"orchestrator.resource.annotation\" | \"orchestrator.resource.id\" | \"orchestrator.resource.ip\" | \"orchestrator.resource.label\" | \"orchestrator.resource.name\" | \"orchestrator.resource.parent.type\" | \"orchestrator.resource.type\" | \"orchestrator.type\" | \"organization.id\" | \"organization.name\" | \"package.architecture\" | \"package.build_version\" | \"package.checksum\" | \"package.description\" | \"package.install_scope\" | \"package.installed\" | \"package.license\" | \"package.name\" | \"package.path\" | \"package.reference\" | \"package.size\" | \"package.type\" | \"package.version\" | \"process.args\" | \"process.args_count\" | \"process.code_signature.digest_algorithm\" | \"process.code_signature.exists\" | \"process.code_signature.signing_id\" | \"process.code_signature.status\" | \"process.code_signature.subject_name\" | \"process.code_signature.team_id\" | \"process.code_signature.timestamp\" | \"process.code_signature.trusted\" | \"process.code_signature.valid\" | \"process.command_line\" | \"process.elf.architecture\" | \"process.elf.byte_order\" | \"process.elf.cpu_type\" | \"process.elf.creation_date\" | \"process.elf.exports\" | \"process.elf.go_import_hash\" | \"process.elf.go_imports\" | \"process.elf.go_imports_names_entropy\" | \"process.elf.go_imports_names_var_entropy\" | \"process.elf.go_stripped\" | \"process.elf.header.abi_version\" | \"process.elf.header.class\" | \"process.elf.header.data\" | \"process.elf.header.entrypoint\" | \"process.elf.header.object_version\" | \"process.elf.header.os_abi\" | \"process.elf.header.type\" | \"process.elf.header.version\" | \"process.elf.import_hash\" | \"process.elf.imports\" | \"process.elf.imports_names_entropy\" | \"process.elf.imports_names_var_entropy\" | \"process.elf.sections\" | \"process.elf.segments\" | \"process.elf.shared_libraries\" | \"process.elf.telfhash\" | \"process.end\" | \"process.entity_id\" | \"process.entry_leader.args\" | \"process.entry_leader.args_count\" | \"process.entry_leader.attested_groups.name\" | \"process.entry_leader.attested_user.id\" | \"process.entry_leader.attested_user.name\" | \"process.entry_leader.command_line\" | \"process.entry_leader.entity_id\" | \"process.entry_leader.entry_meta.source.ip\" | \"process.entry_leader.entry_meta.type\" | \"process.entry_leader.executable\" | \"process.entry_leader.group.id\" | \"process.entry_leader.group.name\" | \"process.entry_leader.interactive\" | \"process.entry_leader.name\" | \"process.entry_leader.parent.entity_id\" | \"process.entry_leader.parent.pid\" | \"process.entry_leader.parent.session_leader.entity_id\" | \"process.entry_leader.parent.session_leader.pid\" | \"process.entry_leader.parent.session_leader.start\" | \"process.entry_leader.parent.session_leader.vpid\" | \"process.entry_leader.parent.start\" | \"process.entry_leader.parent.vpid\" | \"process.entry_leader.pid\" | \"process.entry_leader.real_group.id\" | \"process.entry_leader.real_group.name\" | \"process.entry_leader.real_user.id\" | \"process.entry_leader.real_user.name\" | \"process.entry_leader.same_as_process\" | \"process.entry_leader.saved_group.id\" | \"process.entry_leader.saved_group.name\" | \"process.entry_leader.saved_user.id\" | \"process.entry_leader.saved_user.name\" | \"process.entry_leader.start\" | \"process.entry_leader.supplemental_groups.id\" | \"process.entry_leader.supplemental_groups.name\" | \"process.entry_leader.tty\" | \"process.entry_leader.user.id\" | \"process.entry_leader.user.name\" | \"process.entry_leader.vpid\" | \"process.entry_leader.working_directory\" | \"process.env_vars\" | \"process.executable\" | \"process.exit_code\" | \"process.group_leader.args\" | \"process.group_leader.args_count\" | \"process.group_leader.command_line\" | \"process.group_leader.entity_id\" | \"process.group_leader.executable\" | \"process.group_leader.group.id\" | \"process.group_leader.group.name\" | \"process.group_leader.interactive\" | \"process.group_leader.name\" | \"process.group_leader.pid\" | \"process.group_leader.real_group.id\" | \"process.group_leader.real_group.name\" | \"process.group_leader.real_user.id\" | \"process.group_leader.real_user.name\" | \"process.group_leader.same_as_process\" | \"process.group_leader.saved_group.id\" | \"process.group_leader.saved_group.name\" | \"process.group_leader.saved_user.id\" | \"process.group_leader.saved_user.name\" | \"process.group_leader.start\" | \"process.group_leader.supplemental_groups.id\" | \"process.group_leader.supplemental_groups.name\" | \"process.group_leader.tty\" | \"process.group_leader.user.id\" | \"process.group_leader.user.name\" | \"process.group_leader.vpid\" | \"process.group_leader.working_directory\" | \"process.hash.md5\" | \"process.hash.sha1\" | \"process.hash.sha256\" | \"process.hash.sha384\" | \"process.hash.sha512\" | \"process.hash.ssdeep\" | \"process.hash.tlsh\" | \"process.interactive\" | \"process.io\" | \"process.macho.go_import_hash\" | \"process.macho.go_imports\" | \"process.macho.go_imports_names_entropy\" | \"process.macho.go_imports_names_var_entropy\" | \"process.macho.go_stripped\" | \"process.macho.import_hash\" | \"process.macho.imports\" | \"process.macho.imports_names_entropy\" | \"process.macho.imports_names_var_entropy\" | \"process.macho.sections\" | \"process.macho.symhash\" | \"process.name\" | \"process.parent.args\" | \"process.parent.args_count\" | \"process.parent.code_signature.digest_algorithm\" | \"process.parent.code_signature.exists\" | \"process.parent.code_signature.signing_id\" | \"process.parent.code_signature.status\" | \"process.parent.code_signature.subject_name\" | \"process.parent.code_signature.team_id\" | \"process.parent.code_signature.timestamp\" | \"process.parent.code_signature.trusted\" | \"process.parent.code_signature.valid\" | \"process.parent.command_line\" | \"process.parent.elf.architecture\" | \"process.parent.elf.byte_order\" | \"process.parent.elf.cpu_type\" | \"process.parent.elf.creation_date\" | \"process.parent.elf.exports\" | \"process.parent.elf.go_import_hash\" | \"process.parent.elf.go_imports\" | \"process.parent.elf.go_imports_names_entropy\" | \"process.parent.elf.go_imports_names_var_entropy\" | \"process.parent.elf.go_stripped\" | \"process.parent.elf.header.abi_version\" | \"process.parent.elf.header.class\" | \"process.parent.elf.header.data\" | \"process.parent.elf.header.entrypoint\" | \"process.parent.elf.header.object_version\" | \"process.parent.elf.header.os_abi\" | \"process.parent.elf.header.type\" | \"process.parent.elf.header.version\" | \"process.parent.elf.import_hash\" | \"process.parent.elf.imports\" | \"process.parent.elf.imports_names_entropy\" | \"process.parent.elf.imports_names_var_entropy\" | \"process.parent.elf.sections\" | \"process.parent.elf.segments\" | \"process.parent.elf.shared_libraries\" | \"process.parent.elf.telfhash\" | \"process.parent.end\" | \"process.parent.entity_id\" | \"process.parent.executable\" | \"process.parent.exit_code\" | \"process.parent.group.id\" | \"process.parent.group.name\" | \"process.parent.group_leader.entity_id\" | \"process.parent.group_leader.pid\" | \"process.parent.group_leader.start\" | \"process.parent.group_leader.vpid\" | \"process.parent.hash.md5\" | \"process.parent.hash.sha1\" | \"process.parent.hash.sha256\" | \"process.parent.hash.sha384\" | \"process.parent.hash.sha512\" | \"process.parent.hash.ssdeep\" | \"process.parent.hash.tlsh\" | \"process.parent.interactive\" | \"process.parent.macho.go_import_hash\" | \"process.parent.macho.go_imports\" | \"process.parent.macho.go_imports_names_entropy\" | \"process.parent.macho.go_imports_names_var_entropy\" | \"process.parent.macho.go_stripped\" | \"process.parent.macho.import_hash\" | \"process.parent.macho.imports\" | \"process.parent.macho.imports_names_entropy\" | \"process.parent.macho.imports_names_var_entropy\" | \"process.parent.macho.sections\" | \"process.parent.macho.symhash\" | \"process.parent.name\" | \"process.parent.pe.architecture\" | \"process.parent.pe.company\" | \"process.parent.pe.description\" | \"process.parent.pe.file_version\" | \"process.parent.pe.go_import_hash\" | \"process.parent.pe.go_imports\" | \"process.parent.pe.go_imports_names_entropy\" | \"process.parent.pe.go_imports_names_var_entropy\" | \"process.parent.pe.go_stripped\" | \"process.parent.pe.imphash\" | \"process.parent.pe.import_hash\" | \"process.parent.pe.imports\" | \"process.parent.pe.imports_names_entropy\" | \"process.parent.pe.imports_names_var_entropy\" | \"process.parent.pe.original_file_name\" | \"process.parent.pe.pehash\" | \"process.parent.pe.product\" | \"process.parent.pe.sections\" | \"process.parent.pgid\" | \"process.parent.pid\" | \"process.parent.real_group.id\" | \"process.parent.real_group.name\" | \"process.parent.real_user.id\" | \"process.parent.real_user.name\" | \"process.parent.saved_group.id\" | \"process.parent.saved_group.name\" | \"process.parent.saved_user.id\" | \"process.parent.saved_user.name\" | \"process.parent.start\" | \"process.parent.supplemental_groups.id\" | \"process.parent.supplemental_groups.name\" | \"process.parent.thread.capabilities.effective\" | \"process.parent.thread.capabilities.permitted\" | \"process.parent.thread.id\" | \"process.parent.thread.name\" | \"process.parent.title\" | \"process.parent.tty\" | \"process.parent.uptime\" | \"process.parent.user.id\" | \"process.parent.user.name\" | \"process.parent.vpid\" | \"process.parent.working_directory\" | \"process.pe.architecture\" | \"process.pe.company\" | \"process.pe.description\" | \"process.pe.file_version\" | \"process.pe.go_import_hash\" | \"process.pe.go_imports\" | \"process.pe.go_imports_names_entropy\" | \"process.pe.go_imports_names_var_entropy\" | \"process.pe.go_stripped\" | \"process.pe.imphash\" | \"process.pe.import_hash\" | \"process.pe.imports\" | \"process.pe.imports_names_entropy\" | \"process.pe.imports_names_var_entropy\" | \"process.pe.original_file_name\" | \"process.pe.pehash\" | \"process.pe.product\" | \"process.pe.sections\" | \"process.pgid\" | \"process.pid\" | \"process.previous.args\" | \"process.previous.args_count\" | \"process.previous.executable\" | \"process.real_group.id\" | \"process.real_group.name\" | \"process.real_user.id\" | \"process.real_user.name\" | \"process.saved_group.id\" | \"process.saved_group.name\" | \"process.saved_user.id\" | \"process.saved_user.name\" | \"process.session_leader.args\" | \"process.session_leader.args_count\" | \"process.session_leader.command_line\" | \"process.session_leader.entity_id\" | \"process.session_leader.executable\" | \"process.session_leader.group.id\" | \"process.session_leader.group.name\" | \"process.session_leader.interactive\" | \"process.session_leader.name\" | \"process.session_leader.parent.entity_id\" | \"process.session_leader.parent.pid\" | \"process.session_leader.parent.session_leader.entity_id\" | \"process.session_leader.parent.session_leader.pid\" | \"process.session_leader.parent.session_leader.start\" | \"process.session_leader.parent.session_leader.vpid\" | \"process.session_leader.parent.start\" | \"process.session_leader.parent.vpid\" | \"process.session_leader.pid\" | \"process.session_leader.real_group.id\" | \"process.session_leader.real_group.name\" | \"process.session_leader.real_user.id\" | \"process.session_leader.real_user.name\" | \"process.session_leader.same_as_process\" | \"process.session_leader.saved_group.id\" | \"process.session_leader.saved_group.name\" | \"process.session_leader.saved_user.id\" | \"process.session_leader.saved_user.name\" | \"process.session_leader.start\" | \"process.session_leader.supplemental_groups.id\" | \"process.session_leader.supplemental_groups.name\" | \"process.session_leader.tty\" | \"process.session_leader.user.id\" | \"process.session_leader.user.name\" | \"process.session_leader.vpid\" | \"process.session_leader.working_directory\" | \"process.start\" | \"process.supplemental_groups.id\" | \"process.supplemental_groups.name\" | \"process.thread.capabilities.effective\" | \"process.thread.capabilities.permitted\" | \"process.thread.id\" | \"process.thread.name\" | \"process.title\" | \"process.tty\" | \"process.uptime\" | \"process.user.id\" | \"process.user.name\" | \"process.vpid\" | \"process.working_directory\" | \"registry.data.bytes\" | \"registry.data.strings\" | \"registry.data.type\" | \"registry.hive\" | \"registry.key\" | \"registry.path\" | \"registry.value\" | \"related.hash\" | \"related.hosts\" | \"related.ip\" | \"related.user\" | \"rule.author\" | \"rule.category\" | \"rule.description\" | \"rule.id\" | \"rule.license\" | \"rule.name\" | \"rule.reference\" | \"rule.ruleset\" | \"rule.uuid\" | \"rule.version\" | \"server.address\" | \"server.as.number\" | \"server.as.organization.name\" | \"server.bytes\" | \"server.domain\" | \"server.geo.city_name\" | \"server.geo.continent_code\" | \"server.geo.continent_name\" | \"server.geo.country_iso_code\" | \"server.geo.country_name\" | \"server.geo.location\" | \"server.geo.name\" | \"server.geo.postal_code\" | \"server.geo.region_iso_code\" | \"server.geo.region_name\" | \"server.geo.timezone\" | \"server.ip\" | \"server.mac\" | \"server.nat.ip\" | \"server.nat.port\" | \"server.packets\" | \"server.port\" | \"server.registered_domain\" | \"server.subdomain\" | \"server.top_level_domain\" | \"server.user.domain\" | \"server.user.email\" | \"server.user.full_name\" | \"server.user.group.domain\" | \"server.user.group.id\" | \"server.user.group.name\" | \"server.user.hash\" | \"server.user.id\" | \"server.user.name\" | \"server.user.roles\" | \"service.address\" | \"service.ephemeral_id\" | \"service.id\" | \"service.node.name\" | \"service.node.role\" | \"service.node.roles\" | \"service.origin.address\" | \"service.origin.environment\" | \"service.origin.ephemeral_id\" | \"service.origin.id\" | \"service.origin.name\" | \"service.origin.node.name\" | \"service.origin.node.role\" | \"service.origin.node.roles\" | \"service.origin.state\" | \"service.origin.type\" | \"service.origin.version\" | \"service.state\" | \"service.target.address\" | \"service.target.environment\" | \"service.target.ephemeral_id\" | \"service.target.id\" | \"service.target.name\" | \"service.target.node.name\" | \"service.target.node.role\" | \"service.target.node.roles\" | \"service.target.state\" | \"service.target.type\" | \"service.target.version\" | \"service.type\" | \"service.version\" | \"source.address\" | \"source.as.number\" | \"source.as.organization.name\" | \"source.bytes\" | \"source.domain\" | \"source.geo.city_name\" | \"source.geo.continent_code\" | \"source.geo.continent_name\" | \"source.geo.country_iso_code\" | \"source.geo.country_name\" | \"source.geo.location\" | \"source.geo.name\" | \"source.geo.postal_code\" | \"source.geo.region_iso_code\" | \"source.geo.region_name\" | \"source.geo.timezone\" | \"source.ip\" | \"source.mac\" | \"source.nat.ip\" | \"source.nat.port\" | \"source.packets\" | \"source.port\" | \"source.registered_domain\" | \"source.subdomain\" | \"source.top_level_domain\" | \"source.user.domain\" | \"source.user.email\" | \"source.user.full_name\" | \"source.user.group.domain\" | \"source.user.group.id\" | \"source.user.group.name\" | \"source.user.hash\" | \"source.user.id\" | \"source.user.name\" | \"source.user.roles\" | \"span.id\" | \"threat.enrichments\" | \"threat.feed.dashboard_id\" | \"threat.feed.description\" | \"threat.feed.name\" | \"threat.feed.reference\" | \"threat.framework\" | \"threat.group.alias\" | \"threat.group.id\" | \"threat.group.name\" | \"threat.group.reference\" | \"threat.indicator.as.number\" | \"threat.indicator.as.organization.name\" | \"threat.indicator.confidence\" | \"threat.indicator.description\" | \"threat.indicator.email.address\" | \"threat.indicator.file.accessed\" | \"threat.indicator.file.attributes\" | \"threat.indicator.file.code_signature.digest_algorithm\" | \"threat.indicator.file.code_signature.exists\" | \"threat.indicator.file.code_signature.signing_id\" | \"threat.indicator.file.code_signature.status\" | \"threat.indicator.file.code_signature.subject_name\" | \"threat.indicator.file.code_signature.team_id\" | \"threat.indicator.file.code_signature.timestamp\" | \"threat.indicator.file.code_signature.trusted\" | \"threat.indicator.file.code_signature.valid\" | \"threat.indicator.file.created\" | \"threat.indicator.file.ctime\" | \"threat.indicator.file.device\" | \"threat.indicator.file.directory\" | \"threat.indicator.file.drive_letter\" | \"threat.indicator.file.elf.architecture\" | \"threat.indicator.file.elf.byte_order\" | \"threat.indicator.file.elf.cpu_type\" | \"threat.indicator.file.elf.creation_date\" | \"threat.indicator.file.elf.exports\" | \"threat.indicator.file.elf.go_import_hash\" | \"threat.indicator.file.elf.go_imports\" | \"threat.indicator.file.elf.go_imports_names_entropy\" | \"threat.indicator.file.elf.go_imports_names_var_entropy\" | \"threat.indicator.file.elf.go_stripped\" | \"threat.indicator.file.elf.header.abi_version\" | \"threat.indicator.file.elf.header.class\" | \"threat.indicator.file.elf.header.data\" | \"threat.indicator.file.elf.header.entrypoint\" | \"threat.indicator.file.elf.header.object_version\" | \"threat.indicator.file.elf.header.os_abi\" | \"threat.indicator.file.elf.header.type\" | \"threat.indicator.file.elf.header.version\" | \"threat.indicator.file.elf.import_hash\" | \"threat.indicator.file.elf.imports\" | \"threat.indicator.file.elf.imports_names_entropy\" | \"threat.indicator.file.elf.imports_names_var_entropy\" | \"threat.indicator.file.elf.sections\" | \"threat.indicator.file.elf.segments\" | \"threat.indicator.file.elf.shared_libraries\" | \"threat.indicator.file.elf.telfhash\" | \"threat.indicator.file.extension\" | \"threat.indicator.file.fork_name\" | \"threat.indicator.file.gid\" | \"threat.indicator.file.group\" | \"threat.indicator.file.hash.md5\" | \"threat.indicator.file.hash.sha1\" | \"threat.indicator.file.hash.sha256\" | \"threat.indicator.file.hash.sha384\" | \"threat.indicator.file.hash.sha512\" | \"threat.indicator.file.hash.ssdeep\" | \"threat.indicator.file.hash.tlsh\" | \"threat.indicator.file.inode\" | \"threat.indicator.file.mime_type\" | \"threat.indicator.file.mode\" | \"threat.indicator.file.mtime\" | \"threat.indicator.file.name\" | \"threat.indicator.file.owner\" | \"threat.indicator.file.path\" | \"threat.indicator.file.pe.architecture\" | \"threat.indicator.file.pe.company\" | \"threat.indicator.file.pe.description\" | \"threat.indicator.file.pe.file_version\" | \"threat.indicator.file.pe.go_import_hash\" | \"threat.indicator.file.pe.go_imports\" | \"threat.indicator.file.pe.go_imports_names_entropy\" | \"threat.indicator.file.pe.go_imports_names_var_entropy\" | \"threat.indicator.file.pe.go_stripped\" | \"threat.indicator.file.pe.imphash\" | \"threat.indicator.file.pe.import_hash\" | \"threat.indicator.file.pe.imports\" | \"threat.indicator.file.pe.imports_names_entropy\" | \"threat.indicator.file.pe.imports_names_var_entropy\" | \"threat.indicator.file.pe.original_file_name\" | \"threat.indicator.file.pe.pehash\" | \"threat.indicator.file.pe.product\" | \"threat.indicator.file.pe.sections\" | \"threat.indicator.file.size\" | \"threat.indicator.file.target_path\" | \"threat.indicator.file.type\" | \"threat.indicator.file.uid\" | \"threat.indicator.file.x509.alternative_names\" | \"threat.indicator.file.x509.issuer.common_name\" | \"threat.indicator.file.x509.issuer.country\" | \"threat.indicator.file.x509.issuer.distinguished_name\" | \"threat.indicator.file.x509.issuer.locality\" | \"threat.indicator.file.x509.issuer.organization\" | \"threat.indicator.file.x509.issuer.organizational_unit\" | \"threat.indicator.file.x509.issuer.state_or_province\" | \"threat.indicator.file.x509.not_after\" | \"threat.indicator.file.x509.not_before\" | \"threat.indicator.file.x509.public_key_algorithm\" | \"threat.indicator.file.x509.public_key_curve\" | \"threat.indicator.file.x509.public_key_exponent\" | \"threat.indicator.file.x509.public_key_size\" | \"threat.indicator.file.x509.serial_number\" | \"threat.indicator.file.x509.signature_algorithm\" | \"threat.indicator.file.x509.subject.common_name\" | \"threat.indicator.file.x509.subject.country\" | \"threat.indicator.file.x509.subject.distinguished_name\" | \"threat.indicator.file.x509.subject.locality\" | \"threat.indicator.file.x509.subject.organization\" | \"threat.indicator.file.x509.subject.organizational_unit\" | \"threat.indicator.file.x509.subject.state_or_province\" | \"threat.indicator.file.x509.version_number\" | \"threat.indicator.first_seen\" | \"threat.indicator.geo.city_name\" | \"threat.indicator.geo.continent_code\" | \"threat.indicator.geo.continent_name\" | \"threat.indicator.geo.country_iso_code\" | \"threat.indicator.geo.country_name\" | \"threat.indicator.geo.location\" | \"threat.indicator.geo.name\" | \"threat.indicator.geo.postal_code\" | \"threat.indicator.geo.region_iso_code\" | \"threat.indicator.geo.region_name\" | \"threat.indicator.geo.timezone\" | \"threat.indicator.ip\" | \"threat.indicator.last_seen\" | \"threat.indicator.marking.tlp\" | \"threat.indicator.marking.tlp_version\" | \"threat.indicator.modified_at\" | \"threat.indicator.name\" | \"threat.indicator.port\" | \"threat.indicator.provider\" | \"threat.indicator.reference\" | \"threat.indicator.registry.data.bytes\" | \"threat.indicator.registry.data.strings\" | \"threat.indicator.registry.data.type\" | \"threat.indicator.registry.hive\" | \"threat.indicator.registry.key\" | \"threat.indicator.registry.path\" | \"threat.indicator.registry.value\" | \"threat.indicator.scanner_stats\" | \"threat.indicator.sightings\" | \"threat.indicator.type\" | \"threat.indicator.url.domain\" | \"threat.indicator.url.extension\" | \"threat.indicator.url.fragment\" | \"threat.indicator.url.full\" | \"threat.indicator.url.original\" | \"threat.indicator.url.password\" | \"threat.indicator.url.path\" | \"threat.indicator.url.port\" | \"threat.indicator.url.query\" | \"threat.indicator.url.registered_domain\" | \"threat.indicator.url.scheme\" | \"threat.indicator.url.subdomain\" | \"threat.indicator.url.top_level_domain\" | \"threat.indicator.url.username\" | \"threat.indicator.x509.alternative_names\" | \"threat.indicator.x509.issuer.common_name\" | \"threat.indicator.x509.issuer.country\" | \"threat.indicator.x509.issuer.distinguished_name\" | \"threat.indicator.x509.issuer.locality\" | \"threat.indicator.x509.issuer.organization\" | \"threat.indicator.x509.issuer.organizational_unit\" | \"threat.indicator.x509.issuer.state_or_province\" | \"threat.indicator.x509.not_after\" | \"threat.indicator.x509.not_before\" | \"threat.indicator.x509.public_key_algorithm\" | \"threat.indicator.x509.public_key_curve\" | \"threat.indicator.x509.public_key_exponent\" | \"threat.indicator.x509.public_key_size\" | \"threat.indicator.x509.serial_number\" | \"threat.indicator.x509.signature_algorithm\" | \"threat.indicator.x509.subject.common_name\" | \"threat.indicator.x509.subject.country\" | \"threat.indicator.x509.subject.distinguished_name\" | \"threat.indicator.x509.subject.locality\" | \"threat.indicator.x509.subject.organization\" | \"threat.indicator.x509.subject.organizational_unit\" | \"threat.indicator.x509.subject.state_or_province\" | \"threat.indicator.x509.version_number\" | \"threat.software.alias\" | \"threat.software.id\" | \"threat.software.name\" | \"threat.software.platforms\" | \"threat.software.reference\" | \"threat.software.type\" | \"threat.tactic.id\" | \"threat.tactic.name\" | \"threat.tactic.reference\" | \"threat.technique.id\" | \"threat.technique.name\" | \"threat.technique.reference\" | \"threat.technique.subtechnique.id\" | \"threat.technique.subtechnique.name\" | \"threat.technique.subtechnique.reference\" | \"tls.cipher\" | \"tls.client.certificate\" | \"tls.client.certificate_chain\" | \"tls.client.hash.md5\" | \"tls.client.hash.sha1\" | \"tls.client.hash.sha256\" | \"tls.client.issuer\" | \"tls.client.ja3\" | \"tls.client.not_after\" | \"tls.client.not_before\" | \"tls.client.server_name\" | \"tls.client.subject\" | \"tls.client.supported_ciphers\" | \"tls.client.x509.alternative_names\" | \"tls.client.x509.issuer.common_name\" | \"tls.client.x509.issuer.country\" | \"tls.client.x509.issuer.distinguished_name\" | \"tls.client.x509.issuer.locality\" | \"tls.client.x509.issuer.organization\" | \"tls.client.x509.issuer.organizational_unit\" | \"tls.client.x509.issuer.state_or_province\" | \"tls.client.x509.not_after\" | \"tls.client.x509.not_before\" | \"tls.client.x509.public_key_algorithm\" | \"tls.client.x509.public_key_curve\" | \"tls.client.x509.public_key_exponent\" | \"tls.client.x509.public_key_size\" | \"tls.client.x509.serial_number\" | \"tls.client.x509.signature_algorithm\" | \"tls.client.x509.subject.common_name\" | \"tls.client.x509.subject.country\" | \"tls.client.x509.subject.distinguished_name\" | \"tls.client.x509.subject.locality\" | \"tls.client.x509.subject.organization\" | \"tls.client.x509.subject.organizational_unit\" | \"tls.client.x509.subject.state_or_province\" | \"tls.client.x509.version_number\" | \"tls.curve\" | \"tls.established\" | \"tls.next_protocol\" | \"tls.resumed\" | \"tls.server.certificate\" | \"tls.server.certificate_chain\" | \"tls.server.hash.md5\" | \"tls.server.hash.sha1\" | \"tls.server.hash.sha256\" | \"tls.server.issuer\" | \"tls.server.ja3s\" | \"tls.server.not_after\" | \"tls.server.not_before\" | \"tls.server.subject\" | \"tls.server.x509.alternative_names\" | \"tls.server.x509.issuer.common_name\" | \"tls.server.x509.issuer.country\" | \"tls.server.x509.issuer.distinguished_name\" | \"tls.server.x509.issuer.locality\" | \"tls.server.x509.issuer.organization\" | \"tls.server.x509.issuer.organizational_unit\" | \"tls.server.x509.issuer.state_or_province\" | \"tls.server.x509.not_after\" | \"tls.server.x509.not_before\" | \"tls.server.x509.public_key_algorithm\" | \"tls.server.x509.public_key_curve\" | \"tls.server.x509.public_key_exponent\" | \"tls.server.x509.public_key_size\" | \"tls.server.x509.serial_number\" | \"tls.server.x509.signature_algorithm\" | \"tls.server.x509.subject.common_name\" | \"tls.server.x509.subject.country\" | \"tls.server.x509.subject.distinguished_name\" | \"tls.server.x509.subject.locality\" | \"tls.server.x509.subject.organization\" | \"tls.server.x509.subject.organizational_unit\" | \"tls.server.x509.subject.state_or_province\" | \"tls.server.x509.version_number\" | \"tls.version\" | \"tls.version_protocol\" | \"trace.id\" | \"transaction.id\" | \"url.domain\" | \"url.extension\" | \"url.fragment\" | \"url.full\" | \"url.original\" | \"url.password\" | \"url.path\" | \"url.port\" | \"url.query\" | \"url.registered_domain\" | \"url.scheme\" | \"url.subdomain\" | \"url.top_level_domain\" | \"url.username\" | \"user.changes.domain\" | \"user.changes.email\" | \"user.changes.full_name\" | \"user.changes.group.domain\" | \"user.changes.group.id\" | \"user.changes.group.name\" | \"user.changes.hash\" | \"user.changes.id\" | \"user.changes.name\" | \"user.changes.roles\" | \"user.domain\" | \"user.effective.domain\" | \"user.effective.email\" | \"user.effective.full_name\" | \"user.effective.group.domain\" | \"user.effective.group.id\" | \"user.effective.group.name\" | \"user.effective.hash\" | \"user.effective.id\" | \"user.effective.name\" | \"user.effective.roles\" | \"user.email\" | \"user.full_name\" | \"user.group.domain\" | \"user.group.id\" | \"user.group.name\" | \"user.hash\" | \"user.id\" | \"user.name\" | \"user.risk.calculated_level\" | \"user.risk.calculated_score\" | \"user.risk.calculated_score_norm\" | \"user.risk.static_level\" | \"user.risk.static_score\" | \"user.risk.static_score_norm\" | \"user.roles\" | \"user.target.domain\" | \"user.target.email\" | \"user.target.full_name\" | \"user.target.group.domain\" | \"user.target.group.id\" | \"user.target.group.name\" | \"user.target.hash\" | \"user.target.id\" | \"user.target.name\" | \"user.target.roles\" | \"user_agent.device.name\" | \"user_agent.name\" | \"user_agent.original\" | \"user_agent.os.family\" | \"user_agent.os.full\" | \"user_agent.os.kernel\" | \"user_agent.os.name\" | \"user_agent.os.platform\" | \"user_agent.os.type\" | \"user_agent.os.version\" | \"user_agent.version\" | \"vulnerability.category\" | \"vulnerability.classification\" | \"vulnerability.description\" | \"vulnerability.enumeration\" | \"vulnerability.id\" | \"vulnerability.reference\" | \"vulnerability.report_id\" | \"vulnerability.scanner.vendor\" | \"vulnerability.score.base\" | \"vulnerability.score.environmental\" | \"vulnerability.score.temporal\" | \"vulnerability.score.version\" | \"vulnerability.severity\" | (string & {}) | \"data_stream.dataset\" | \"data_stream.namespace\" | \"data_stream.type\" | \"dll.pe.sections.entropy\" | \"dll.pe.sections.name\" | \"dll.pe.sections.physical_size\" | \"dll.pe.sections.var_entropy\" | \"dll.pe.sections.virtual_size\" | \"dns.answers.class\" | \"dns.answers.data\" | \"dns.answers.name\" | \"dns.answers.ttl\" | \"dns.answers.type\" | \"email.attachments.file.extension\" | \"email.attachments.file.hash.md5\" | \"email.attachments.file.hash.sha1\" | \"email.attachments.file.hash.sha256\" | \"email.attachments.file.hash.sha384\" | \"email.attachments.file.hash.sha512\" | \"email.attachments.file.hash.ssdeep\" | \"email.attachments.file.hash.tlsh\" | \"email.attachments.file.mime_type\" | \"email.attachments.file.name\" | \"email.attachments.file.size\" | \"faas.trigger.request_id\" | \"faas.trigger.type\" | \"file.elf.sections.chi2\" | \"file.elf.sections.entropy\" | \"file.elf.sections.flags\" | \"file.elf.sections.name\" | \"file.elf.sections.physical_offset\" | \"file.elf.sections.physical_size\" | \"file.elf.sections.type\" | \"file.elf.sections.var_entropy\" | \"file.elf.sections.virtual_address\" | \"file.elf.sections.virtual_size\" | \"file.elf.segments.sections\" | \"file.elf.segments.type\" | \"file.macho.sections.entropy\" | \"file.macho.sections.name\" | \"file.macho.sections.physical_size\" | \"file.macho.sections.var_entropy\" | \"file.macho.sections.virtual_size\" | \"file.pe.sections.entropy\" | \"file.pe.sections.name\" | \"file.pe.sections.physical_size\" | \"file.pe.sections.var_entropy\" | \"file.pe.sections.virtual_size\" | \"log.syslog.appname\" | \"log.syslog.facility.code\" | \"log.syslog.facility.name\" | \"log.syslog.hostname\" | \"log.syslog.msgid\" | \"log.syslog.priority\" | \"log.syslog.procid\" | \"log.syslog.severity.code\" | \"log.syslog.severity.name\" | \"log.syslog.structured_data\" | \"log.syslog.version\" | \"network.inner.vlan.id\" | \"network.inner.vlan.name\" | \"observer.egress.interface.alias\" | \"observer.egress.interface.id\" | \"observer.egress.interface.name\" | \"observer.egress.vlan.id\" | \"observer.egress.vlan.name\" | \"observer.egress.zone\" | \"observer.ingress.interface.alias\" | \"observer.ingress.interface.id\" | \"observer.ingress.interface.name\" | \"observer.ingress.vlan.id\" | \"observer.ingress.vlan.name\" | \"observer.ingress.zone\" | \"process.elf.sections.chi2\" | \"process.elf.sections.entropy\" | \"process.elf.sections.flags\" | \"process.elf.sections.name\" | \"process.elf.sections.physical_offset\" | \"process.elf.sections.physical_size\" | \"process.elf.sections.type\" | \"process.elf.sections.var_entropy\" | \"process.elf.sections.virtual_address\" | \"process.elf.sections.virtual_size\" | \"process.elf.segments.sections\" | \"process.elf.segments.type\" | \"process.entry_leader.tty.char_device.major\" | \"process.entry_leader.tty.char_device.minor\" | \"process.group_leader.tty.char_device.major\" | \"process.group_leader.tty.char_device.minor\" | \"process.io.bytes_skipped\" | \"process.io.bytes_skipped.length\" | \"process.io.bytes_skipped.offset\" | \"process.io.max_bytes_per_process_exceeded\" | \"process.io.text\" | \"process.io.total_bytes_captured\" | \"process.io.total_bytes_skipped\" | \"process.io.type\" | \"process.macho.sections.entropy\" | \"process.macho.sections.name\" | \"process.macho.sections.physical_size\" | \"process.macho.sections.var_entropy\" | \"process.macho.sections.virtual_size\" | \"process.parent.elf.sections.chi2\" | \"process.parent.elf.sections.entropy\" | \"process.parent.elf.sections.flags\" | \"process.parent.elf.sections.name\" | \"process.parent.elf.sections.physical_offset\" | \"process.parent.elf.sections.physical_size\" | \"process.parent.elf.sections.type\" | \"process.parent.elf.sections.var_entropy\" | \"process.parent.elf.sections.virtual_address\" | \"process.parent.elf.sections.virtual_size\" | \"process.parent.elf.segments.sections\" | \"process.parent.elf.segments.type\" | \"process.parent.macho.sections.entropy\" | \"process.parent.macho.sections.name\" | \"process.parent.macho.sections.physical_size\" | \"process.parent.macho.sections.var_entropy\" | \"process.parent.macho.sections.virtual_size\" | \"process.parent.pe.sections.entropy\" | \"process.parent.pe.sections.name\" | \"process.parent.pe.sections.physical_size\" | \"process.parent.pe.sections.var_entropy\" | \"process.parent.pe.sections.virtual_size\" | \"process.parent.tty.char_device.major\" | \"process.parent.tty.char_device.minor\" | \"process.pe.sections.entropy\" | \"process.pe.sections.name\" | \"process.pe.sections.physical_size\" | \"process.pe.sections.var_entropy\" | \"process.pe.sections.virtual_size\" | \"process.session_leader.tty.char_device.major\" | \"process.session_leader.tty.char_device.minor\" | \"process.tty.char_device.major\" | \"process.tty.char_device.minor\" | \"process.tty.columns\" | \"process.tty.rows\" | \"threat.enrichments.indicator\" | \"threat.enrichments.indicator.as.number\" | \"threat.enrichments.indicator.as.organization.name\" | \"threat.enrichments.indicator.confidence\" | \"threat.enrichments.indicator.description\" | \"threat.enrichments.indicator.email.address\" | \"threat.enrichments.indicator.file.accessed\" | \"threat.enrichments.indicator.file.attributes\" | \"threat.enrichments.indicator.file.code_signature.digest_algorithm\" | \"threat.enrichments.indicator.file.code_signature.exists\" | \"threat.enrichments.indicator.file.code_signature.signing_id\" | \"threat.enrichments.indicator.file.code_signature.status\" | \"threat.enrichments.indicator.file.code_signature.subject_name\" | \"threat.enrichments.indicator.file.code_signature.team_id\" | \"threat.enrichments.indicator.file.code_signature.timestamp\" | \"threat.enrichments.indicator.file.code_signature.trusted\" | \"threat.enrichments.indicator.file.code_signature.valid\" | \"threat.enrichments.indicator.file.created\" | \"threat.enrichments.indicator.file.ctime\" | \"threat.enrichments.indicator.file.device\" | \"threat.enrichments.indicator.file.directory\" | \"threat.enrichments.indicator.file.drive_letter\" | \"threat.enrichments.indicator.file.elf.architecture\" | \"threat.enrichments.indicator.file.elf.byte_order\" | \"threat.enrichments.indicator.file.elf.cpu_type\" | \"threat.enrichments.indicator.file.elf.creation_date\" | \"threat.enrichments.indicator.file.elf.exports\" | \"threat.enrichments.indicator.file.elf.go_import_hash\" | \"threat.enrichments.indicator.file.elf.go_imports\" | \"threat.enrichments.indicator.file.elf.go_imports_names_entropy\" | \"threat.enrichments.indicator.file.elf.go_imports_names_var_entropy\" | \"threat.enrichments.indicator.file.elf.go_stripped\" | \"threat.enrichments.indicator.file.elf.header.abi_version\" | \"threat.enrichments.indicator.file.elf.header.class\" | \"threat.enrichments.indicator.file.elf.header.data\" | \"threat.enrichments.indicator.file.elf.header.entrypoint\" | \"threat.enrichments.indicator.file.elf.header.object_version\" | \"threat.enrichments.indicator.file.elf.header.os_abi\" | \"threat.enrichments.indicator.file.elf.header.type\" | \"threat.enrichments.indicator.file.elf.header.version\" | \"threat.enrichments.indicator.file.elf.import_hash\" | \"threat.enrichments.indicator.file.elf.imports\" | \"threat.enrichments.indicator.file.elf.imports_names_entropy\" | \"threat.enrichments.indicator.file.elf.imports_names_var_entropy\" | \"threat.enrichments.indicator.file.elf.sections\" | \"threat.enrichments.indicator.file.elf.sections.chi2\" | \"threat.enrichments.indicator.file.elf.sections.entropy\" | \"threat.enrichments.indicator.file.elf.sections.flags\" | \"threat.enrichments.indicator.file.elf.sections.name\" | \"threat.enrichments.indicator.file.elf.sections.physical_offset\" | \"threat.enrichments.indicator.file.elf.sections.physical_size\" | \"threat.enrichments.indicator.file.elf.sections.type\" | \"threat.enrichments.indicator.file.elf.sections.var_entropy\" | \"threat.enrichments.indicator.file.elf.sections.virtual_address\" | \"threat.enrichments.indicator.file.elf.sections.virtual_size\" | \"threat.enrichments.indicator.file.elf.segments\" | \"threat.enrichments.indicator.file.elf.segments.sections\" | \"threat.enrichments.indicator.file.elf.segments.type\" | \"threat.enrichments.indicator.file.elf.shared_libraries\" | \"threat.enrichments.indicator.file.elf.telfhash\" | \"threat.enrichments.indicator.file.extension\" | \"threat.enrichments.indicator.file.fork_name\" | \"threat.enrichments.indicator.file.gid\" | \"threat.enrichments.indicator.file.group\" | \"threat.enrichments.indicator.file.hash.md5\" | \"threat.enrichments.indicator.file.hash.sha1\" | \"threat.enrichments.indicator.file.hash.sha256\" | \"threat.enrichments.indicator.file.hash.sha384\" | \"threat.enrichments.indicator.file.hash.sha512\" | \"threat.enrichments.indicator.file.hash.ssdeep\" | \"threat.enrichments.indicator.file.hash.tlsh\" | \"threat.enrichments.indicator.file.inode\" | \"threat.enrichments.indicator.file.mime_type\" | \"threat.enrichments.indicator.file.mode\" | \"threat.enrichments.indicator.file.mtime\" | \"threat.enrichments.indicator.file.name\" | \"threat.enrichments.indicator.file.owner\" | \"threat.enrichments.indicator.file.path\" | \"threat.enrichments.indicator.file.pe.architecture\" | \"threat.enrichments.indicator.file.pe.company\" | \"threat.enrichments.indicator.file.pe.description\" | \"threat.enrichments.indicator.file.pe.file_version\" | \"threat.enrichments.indicator.file.pe.go_import_hash\" | \"threat.enrichments.indicator.file.pe.go_imports\" | \"threat.enrichments.indicator.file.pe.go_imports_names_entropy\" | \"threat.enrichments.indicator.file.pe.go_imports_names_var_entropy\" | \"threat.enrichments.indicator.file.pe.go_stripped\" | \"threat.enrichments.indicator.file.pe.imphash\" | \"threat.enrichments.indicator.file.pe.import_hash\" | \"threat.enrichments.indicator.file.pe.imports\" | \"threat.enrichments.indicator.file.pe.imports_names_entropy\" | \"threat.enrichments.indicator.file.pe.imports_names_var_entropy\" | \"threat.enrichments.indicator.file.pe.original_file_name\" | \"threat.enrichments.indicator.file.pe.pehash\" | \"threat.enrichments.indicator.file.pe.product\" | \"threat.enrichments.indicator.file.pe.sections\" | \"threat.enrichments.indicator.file.pe.sections.entropy\" | \"threat.enrichments.indicator.file.pe.sections.name\" | \"threat.enrichments.indicator.file.pe.sections.physical_size\" | \"threat.enrichments.indicator.file.pe.sections.var_entropy\" | \"threat.enrichments.indicator.file.pe.sections.virtual_size\" | \"threat.enrichments.indicator.file.size\" | \"threat.enrichments.indicator.file.target_path\" | \"threat.enrichments.indicator.file.type\" | \"threat.enrichments.indicator.file.uid\" | \"threat.enrichments.indicator.file.x509.alternative_names\" | \"threat.enrichments.indicator.file.x509.issuer.common_name\" | \"threat.enrichments.indicator.file.x509.issuer.country\" | \"threat.enrichments.indicator.file.x509.issuer.distinguished_name\" | \"threat.enrichments.indicator.file.x509.issuer.locality\" | \"threat.enrichments.indicator.file.x509.issuer.organization\" | \"threat.enrichments.indicator.file.x509.issuer.organizational_unit\" | \"threat.enrichments.indicator.file.x509.issuer.state_or_province\" | \"threat.enrichments.indicator.file.x509.not_after\" | \"threat.enrichments.indicator.file.x509.not_before\" | \"threat.enrichments.indicator.file.x509.public_key_algorithm\" | \"threat.enrichments.indicator.file.x509.public_key_curve\" | \"threat.enrichments.indicator.file.x509.public_key_exponent\" | \"threat.enrichments.indicator.file.x509.public_key_size\" | \"threat.enrichments.indicator.file.x509.serial_number\" | \"threat.enrichments.indicator.file.x509.signature_algorithm\" | \"threat.enrichments.indicator.file.x509.subject.common_name\" | \"threat.enrichments.indicator.file.x509.subject.country\" | \"threat.enrichments.indicator.file.x509.subject.distinguished_name\" | \"threat.enrichments.indicator.file.x509.subject.locality\" | \"threat.enrichments.indicator.file.x509.subject.organization\" | \"threat.enrichments.indicator.file.x509.subject.organizational_unit\" | \"threat.enrichments.indicator.file.x509.subject.state_or_province\" | \"threat.enrichments.indicator.file.x509.version_number\" | \"threat.enrichments.indicator.first_seen\" | \"threat.enrichments.indicator.geo.city_name\" | \"threat.enrichments.indicator.geo.continent_code\" | \"threat.enrichments.indicator.geo.continent_name\" | \"threat.enrichments.indicator.geo.country_iso_code\" | \"threat.enrichments.indicator.geo.country_name\" | \"threat.enrichments.indicator.geo.location\" | \"threat.enrichments.indicator.geo.name\" | \"threat.enrichments.indicator.geo.postal_code\" | \"threat.enrichments.indicator.geo.region_iso_code\" | \"threat.enrichments.indicator.geo.region_name\" | \"threat.enrichments.indicator.geo.timezone\" | \"threat.enrichments.indicator.ip\" | \"threat.enrichments.indicator.last_seen\" | \"threat.enrichments.indicator.marking.tlp\" | \"threat.enrichments.indicator.marking.tlp_version\" | \"threat.enrichments.indicator.modified_at\" | \"threat.enrichments.indicator.name\" | \"threat.enrichments.indicator.port\" | \"threat.enrichments.indicator.provider\" | \"threat.enrichments.indicator.reference\" | \"threat.enrichments.indicator.registry.data.bytes\" | \"threat.enrichments.indicator.registry.data.strings\" | \"threat.enrichments.indicator.registry.data.type\" | \"threat.enrichments.indicator.registry.hive\" | \"threat.enrichments.indicator.registry.key\" | \"threat.enrichments.indicator.registry.path\" | \"threat.enrichments.indicator.registry.value\" | \"threat.enrichments.indicator.scanner_stats\" | \"threat.enrichments.indicator.sightings\" | \"threat.enrichments.indicator.type\" | \"threat.enrichments.indicator.url.domain\" | \"threat.enrichments.indicator.url.extension\" | \"threat.enrichments.indicator.url.fragment\" | \"threat.enrichments.indicator.url.full\" | \"threat.enrichments.indicator.url.original\" | \"threat.enrichments.indicator.url.password\" | \"threat.enrichments.indicator.url.path\" | \"threat.enrichments.indicator.url.port\" | \"threat.enrichments.indicator.url.query\" | \"threat.enrichments.indicator.url.registered_domain\" | \"threat.enrichments.indicator.url.scheme\" | \"threat.enrichments.indicator.url.subdomain\" | \"threat.enrichments.indicator.url.top_level_domain\" | \"threat.enrichments.indicator.url.username\" | \"threat.enrichments.indicator.x509.alternative_names\" | \"threat.enrichments.indicator.x509.issuer.common_name\" | \"threat.enrichments.indicator.x509.issuer.country\" | \"threat.enrichments.indicator.x509.issuer.distinguished_name\" | \"threat.enrichments.indicator.x509.issuer.locality\" | \"threat.enrichments.indicator.x509.issuer.organization\" | \"threat.enrichments.indicator.x509.issuer.organizational_unit\" | \"threat.enrichments.indicator.x509.issuer.state_or_province\" | \"threat.enrichments.indicator.x509.not_after\" | \"threat.enrichments.indicator.x509.not_before\" | \"threat.enrichments.indicator.x509.public_key_algorithm\" | \"threat.enrichments.indicator.x509.public_key_curve\" | \"threat.enrichments.indicator.x509.public_key_exponent\" | \"threat.enrichments.indicator.x509.public_key_size\" | \"threat.enrichments.indicator.x509.serial_number\" | \"threat.enrichments.indicator.x509.signature_algorithm\" | \"threat.enrichments.indicator.x509.subject.common_name\" | \"threat.enrichments.indicator.x509.subject.country\" | \"threat.enrichments.indicator.x509.subject.distinguished_name\" | \"threat.enrichments.indicator.x509.subject.locality\" | \"threat.enrichments.indicator.x509.subject.organization\" | \"threat.enrichments.indicator.x509.subject.organizational_unit\" | \"threat.enrichments.indicator.x509.subject.state_or_province\" | \"threat.enrichments.indicator.x509.version_number\" | \"threat.enrichments.matched.atomic\" | \"threat.enrichments.matched.field\" | \"threat.enrichments.matched.id\" | \"threat.enrichments.matched.index\" | \"threat.enrichments.matched.occurred\" | \"threat.enrichments.matched.type\" | \"threat.indicator.file.elf.sections.chi2\" | \"threat.indicator.file.elf.sections.entropy\" | \"threat.indicator.file.elf.sections.flags\" | \"threat.indicator.file.elf.sections.name\" | \"threat.indicator.file.elf.sections.physical_offset\" | \"threat.indicator.file.elf.sections.physical_size\" | \"threat.indicator.file.elf.sections.type\" | \"threat.indicator.file.elf.sections.var_entropy\" | \"threat.indicator.file.elf.sections.virtual_address\" | \"threat.indicator.file.elf.sections.virtual_size\" | \"threat.indicator.file.elf.segments.sections\" | \"threat.indicator.file.elf.segments.type\" | \"threat.indicator.file.pe.sections.entropy\" | \"threat.indicator.file.pe.sections.name\" | \"threat.indicator.file.pe.sections.physical_size\" | \"threat.indicator.file.pe.sections.var_entropy\" | \"threat.indicator.file.pe.sections.virtual_size\"" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.IntegrationFieldName", + "type": "Type", + "tags": [], + "label": "IntegrationFieldName", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.PartialFieldMetadataPlain", + "type": "Type", + "tags": [], + "label": "PartialFieldMetadataPlain", + "description": [], + "signature": [ + "{ name?: string | undefined; } & { allowed_values?: ({ description: string; name: string; } & { expected_event_types?: string[] | undefined; beta?: string | undefined; })[] | undefined; beta?: string | undefined; dashed_name?: string | undefined; description?: string | undefined; doc_values?: boolean | undefined; example?: unknown; expected_values?: string[] | undefined; flat_name?: string | undefined; format?: string | undefined; ignore_above?: number | undefined; index?: boolean | undefined; input_format?: string | undefined; level?: string | undefined; multi_fields?: { flat_name: string; name: string; type: string; }[] | undefined; normalize?: string[] | undefined; object_type?: string | undefined; original_fieldset?: string | undefined; output_format?: string | undefined; output_precision?: number | undefined; pattern?: string | undefined; required?: boolean | undefined; scaling_factor?: number | undefined; short?: string | undefined; source?: \"unknown\" | \"ecs\" | \"integration\" | undefined; type?: string | undefined; }" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.TEcsFields", + "type": "Type", + "tags": [], + "label": "TEcsFields", + "description": [], + "signature": [ + "{ '@timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; required: boolean; short: string; type: string; }; 'agent.build.original': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'agent.ephemeral_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'agent.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'agent.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'agent.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'agent.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.address': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.as.number': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.as.organization.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.mac': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; pattern: string; short: string; type: string; }; 'client.nat.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.nat.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.packets': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'client.user.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'client.user.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'cloud.account.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.account.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.availability_zone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.instance.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.instance.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.machine.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.origin.account.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.account.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.availability_zone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.instance.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.instance.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.machine.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.project.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.project.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.provider': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.region': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.origin.service.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.project.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.project.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.provider': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.region': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.service.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'cloud.target.account.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.account.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.availability_zone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.instance.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.instance.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.machine.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.project.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.project.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.provider': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.region': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'cloud.target.service.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'container.cpu.usage': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; scaling_factor: number; short: string; type: string; }; 'container.disk.read.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.disk.write.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.image.hash.all': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'container.image.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.image.tag': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'container.labels': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; object_type: string; short: string; type: string; }; 'container.memory.usage': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; scaling_factor: number; short: string; type: string; }; 'container.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.network.egress.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.network.ingress.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.runtime': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'container.security_context.privileged': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'data_stream.dataset': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'data_stream.namespace': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'data_stream.type': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.address': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.as.number': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.as.organization.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.mac': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; pattern: string; short: string; type: string; }; 'destination.nat.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.nat.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.packets': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'destination.user.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'destination.user.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'device.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'device.manufacturer': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'device.model.identifier': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'device.model.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dll.code_signature.digest_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.exists': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.signing_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.status': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.subject_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.team_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.trusted': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.code_signature.valid': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.hash.md5': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.hash.sha1': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.hash.sha256': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.hash.sha384': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.hash.sha512': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.hash.ssdeep': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.hash.tlsh': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dll.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dll.pe.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.company': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.file_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.imphash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.original_file_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.pehash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.product': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dll.pe.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'dns.answers': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'dns.answers.class': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.answers.data': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.answers.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.answers.ttl': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.answers.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.header_flags': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'dns.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.op_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.question.class': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.question.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.question.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.question.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.question.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.question.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.resolved_ip': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'dns.response_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'dns.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'ecs.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; required: boolean; short: string; type: string; }; 'email.attachments': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'email.attachments.file.extension': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.attachments.file.hash.md5': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'email.attachments.file.hash.sha1': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'email.attachments.file.hash.sha256': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'email.attachments.file.hash.sha384': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'email.attachments.file.hash.sha512': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'email.attachments.file.hash.ssdeep': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'email.attachments.file.hash.tlsh': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'email.attachments.file.mime_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.attachments.file.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.attachments.file.size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.bcc.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'email.cc.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'email.content_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.delivery_timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.direction': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.from.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'email.local_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.message_id': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.origination_timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.reply_to.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'email.sender.address': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'email.subject': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'email.to.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'email.x_mailer': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'error.code': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'error.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'error.message': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'error.stack_trace': { dashed_name: string; description: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'error.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.action': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.agent_id_status': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.category': { allowed_values: { description: string; expected_event_types: string[]; name: string; }[]; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'event.code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.created': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.dataset': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.duration': { dashed_name: string; description: string; flat_name: string; format: string; input_format: string; level: string; name: string; normalize: never[]; output_format: string; output_precision: number; short: string; type: string; }; 'event.end': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.ingested': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.kind': { allowed_values: ({ description: string; name: string; beta?: undefined; } | { beta: string; description: string; name: string; })[]; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.module': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.original': { dashed_name: string; description: string; doc_values: boolean; example: string; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.outcome': { allowed_values: { description: string; name: string; }[]; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.provider': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.reason': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.risk_score': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.risk_score_norm': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.sequence': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.severity': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.start': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.timezone': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'event.type': { allowed_values: { description: string; name: string; }[]; dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'event.url': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'faas.coldstart': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'faas.execution': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'faas.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'faas.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'faas.trigger.request_id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'faas.trigger.type': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'faas.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.accessed': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.attributes': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'file.code_signature.digest_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.exists': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.signing_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.status': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.subject_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.team_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.trusted': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.code_signature.valid': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.created': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.ctime': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.device': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.drive_letter': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.elf.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.byte_order': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.cpu_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.creation_date': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.exports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.elf.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.abi_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.class': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.data': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.entrypoint': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.object_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.os_abi': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.header.version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.elf.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.chi2': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.flags': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.physical_offset': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.virtual_address': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.segments': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.elf.segments.sections': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.segments.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.elf.shared_libraries': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.elf.telfhash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.extension': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.fork_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.gid': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.group': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.hash.md5': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.hash.sha1': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.hash.sha256': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.hash.sha384': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.hash.sha512': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.hash.ssdeep': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.hash.tlsh': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.inode': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.macho.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.macho.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.macho.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.macho.symhash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.mime_type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.mode': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.mtime': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.owner': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'file.pe.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.company': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.file_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.imphash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.pe.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.original_file_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.pehash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.product': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.pe.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.pe.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.target_path': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'file.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.uid': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'file.x509.alternative_names': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.issuer.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.issuer.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.issuer.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.issuer.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.issuer.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.issuer.organizational_unit': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.issuer.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.public_key_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.public_key_curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.public_key_exponent': { dashed_name: string; description: string; doc_values: boolean; example: number; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.public_key_size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.serial_number': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.signature_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.subject.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.subject.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.subject.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'file.x509.subject.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.subject.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.subject.organizational_unit': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.subject.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'file.x509.version_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.boot.id': { beta: string; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.cpu.usage': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; scaling_factor: number; short: string; type: string; }; 'host.disk.read.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.disk.write.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.hostname': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'host.mac': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; pattern: string; short: string; type: string; }; 'host.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.network.egress.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.network.egress.packets': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.network.ingress.bytes': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.network.ingress.packets': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.os.family': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.os.full': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.os.kernel': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.os.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.os.platform': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.os.type': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.os.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.pid_ns_ino': { beta: string; dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.risk.calculated_level': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.risk.calculated_score': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.risk.calculated_score_norm': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.risk.static_level': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.risk.static_score': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.risk.static_score_norm': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'host.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'host.uptime': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.request.body.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.request.body.content': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'http.request.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.request.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.request.method': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.request.mime_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.request.referrer': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.response.body.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.response.body.content': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'http.response.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.response.mime_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.response.status_code': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'http.version': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; labels: { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; object_type: string; short: string; type: string; }; 'log.file.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.level': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.logger': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.origin.file.line': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.origin.file.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.origin.function': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.appname': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.facility.code': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.facility.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.hostname': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.msgid': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.priority': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.procid': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.severity.code': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.severity.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.structured_data': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'log.syslog.version': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; message: { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.application': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.community_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.direction': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.forwarded_ip': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.iana_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.inner': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.inner.vlan.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'network.inner.vlan.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'network.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.packets': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.protocol': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.transport': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'network.vlan.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'network.vlan.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.egress': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.egress.interface.alias': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.egress.interface.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.egress.interface.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.egress.vlan.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.egress.vlan.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.egress.zone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.hostname': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.ingress': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.ingress.interface.alias': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.ingress.interface.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.ingress.interface.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.ingress.vlan.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.ingress.vlan.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.ingress.zone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'observer.mac': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; pattern: string; short: string; type: string; }; 'observer.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.os.family': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.os.full': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.os.kernel': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.os.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.os.platform': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.os.type': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.os.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'observer.product': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.serial_number': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.vendor': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'observer.version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.api_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.cluster.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.cluster.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.cluster.url': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.cluster.version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.namespace': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.resource.annotation': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'orchestrator.resource.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.resource.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'orchestrator.resource.label': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'orchestrator.resource.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.resource.parent.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.resource.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'orchestrator.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'organization.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'organization.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'package.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.build_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.checksum': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.install_scope': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.installed': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.license': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.size': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'package.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.args': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'process.args_count': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.code_signature.digest_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.exists': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.signing_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.status': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.subject_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.team_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.trusted': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.code_signature.valid': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.command_line': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'process.elf.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.byte_order': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.cpu_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.creation_date': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.exports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.elf.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.abi_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.class': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.data': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.entrypoint': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.object_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.os_abi': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.header.version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.elf.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.chi2': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.flags': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.physical_offset': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.virtual_address': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.segments': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.elf.segments.sections': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.segments.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.elf.shared_libraries': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.elf.telfhash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.end': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.entry_leader.args': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.args_count': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.attested_groups.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.attested_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.attested_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.command_line': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.entry_meta.source.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.entry_meta.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.executable': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.interactive': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.session_leader.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.session_leader.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.session_leader.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.session_leader.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.parent.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.real_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.real_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.real_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.real_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.same_as_process': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.saved_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.saved_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.saved_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.saved_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.supplemental_groups.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.supplemental_groups.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.tty': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.tty.char_device.major': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.tty.char_device.minor': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.entry_leader.working_directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.env_vars': { beta: string; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'process.executable': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'process.exit_code': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.group_leader.args': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.args_count': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.command_line': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.executable': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.interactive': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.real_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.real_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.real_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.real_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.same_as_process': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.saved_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.saved_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.saved_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.saved_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.supplemental_groups.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.supplemental_groups.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.tty': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.tty.char_device.major': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.tty.char_device.minor': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.group_leader.working_directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.hash.md5': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.hash.sha1': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.hash.sha256': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.hash.sha384': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.hash.sha512': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.hash.ssdeep': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.hash.tlsh': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.interactive': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io.bytes_skipped': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'process.io.bytes_skipped.length': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io.bytes_skipped.offset': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io.max_bytes_per_process_exceeded': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io.text': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io.total_bytes_captured': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io.total_bytes_skipped': { beta: string; dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.io.type': { beta: string; dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.macho.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.macho.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.macho.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.macho.symhash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'process.parent.args': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.args_count': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.digest_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.exists': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.signing_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.status': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.subject_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.team_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.trusted': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.code_signature.valid': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.command_line': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.byte_order': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.cpu_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.creation_date': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.exports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.abi_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.class': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.data': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.entrypoint': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.object_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.os_abi': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.header.version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.chi2': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.flags': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.physical_offset': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.virtual_address': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.segments': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.segments.sections': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.segments.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.shared_libraries': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.elf.telfhash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.end': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.executable': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.exit_code': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.group_leader.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.group_leader.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.group_leader.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.group_leader.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.hash.md5': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.hash.sha1': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.hash.sha256': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.hash.sha384': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.hash.sha512': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.hash.ssdeep': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.hash.tlsh': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.interactive': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.macho.symhash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.company': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.file_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.imphash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.original_file_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.pehash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.product': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pe.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pgid': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.real_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.real_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.real_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.real_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.saved_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.saved_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.saved_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.saved_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.supplemental_groups.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.supplemental_groups.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.thread.capabilities.effective': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; pattern: string; short: string; type: string; }; 'process.parent.thread.capabilities.permitted': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; pattern: string; short: string; type: string; }; 'process.parent.thread.id': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.thread.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.title': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.tty': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.tty.char_device.major': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.tty.char_device.minor': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.uptime': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.parent.working_directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.company': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.file_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.imphash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.pe.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.original_file_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.pehash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.product': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.pe.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pe.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.pgid': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.previous.args': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.previous.args_count': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.previous.executable': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.real_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.real_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.real_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.real_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.saved_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.saved_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.saved_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.saved_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.args': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.args_count': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.command_line': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.executable': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.interactive': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.session_leader.entity_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.session_leader.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.session_leader.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.session_leader.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.parent.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.pid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.real_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.real_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.real_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.real_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.same_as_process': { dashed_name: string; description: string; example: boolean; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.saved_group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.saved_group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.saved_user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.saved_user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.supplemental_groups.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.supplemental_groups.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.tty': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.tty.char_device.major': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.tty.char_device.minor': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.session_leader.working_directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.start': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.supplemental_groups.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.supplemental_groups.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.thread.capabilities.effective': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; pattern: string; short: string; type: string; }; 'process.thread.capabilities.permitted': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; pattern: string; short: string; type: string; }; 'process.thread.id': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.thread.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.title': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'process.tty': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.tty.char_device.major': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.tty.char_device.minor': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.tty.columns': { beta: string; dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.tty.rows': { beta: string; dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.uptime': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'process.vpid': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'process.working_directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'registry.data.bytes': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'registry.data.strings': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'registry.data.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'registry.hive': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'registry.key': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'registry.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'registry.value': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'related.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'related.hosts': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'related.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'related.user': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'rule.author': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'rule.category': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.license': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.ruleset': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.uuid': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'rule.version': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.address': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.as.number': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.as.organization.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.mac': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; pattern: string; short: string; type: string; }; 'server.nat.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.nat.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.packets': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'server.user.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'server.user.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'service.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.environment': { beta: string; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.ephemeral_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.node.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.node.role': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.node.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'service.origin.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.environment': { beta: string; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.ephemeral_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.node.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.node.role': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.node.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'service.origin.state': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.origin.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.state': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.target.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.environment': { beta: string; dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.ephemeral_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.node.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.node.role': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.node.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'service.target.state': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.target.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'service.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'service.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.address': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.as.number': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.as.organization.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.bytes': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.mac': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; pattern: string; short: string; type: string; }; 'source.nat.ip': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.nat.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.packets': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.port': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'source.user.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'source.user.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'span.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; tags: { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.enrichments': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.enrichments.indicator': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.as.number': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.as.organization.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.confidence': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.email.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.file.accessed': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.attributes': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.digest_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.exists': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.signing_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.status': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.subject_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.team_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.trusted': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.code_signature.valid': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.created': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.ctime': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.device': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.drive_letter': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.byte_order': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.cpu_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.creation_date': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.exports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.abi_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.class': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.data': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.entrypoint': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.object_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.os_abi': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.header.version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.chi2': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.flags': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.physical_offset': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.virtual_address': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.segments': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.segments.sections': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.segments.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.shared_libraries': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.elf.telfhash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.extension': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.fork_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.gid': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.group': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.hash.md5': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.hash.sha1': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.hash.sha256': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.hash.sha384': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.hash.sha512': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.hash.ssdeep': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.hash.tlsh': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.inode': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.mime_type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.mode': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.mtime': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.owner': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.company': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.file_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.imphash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.original_file_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.pehash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.product': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.pe.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.target_path': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.uid': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.alternative_names': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.issuer.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.issuer.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.issuer.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.issuer.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.issuer.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.issuer.organizational_unit': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.issuer.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.public_key_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.public_key_curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.public_key_exponent': { dashed_name: string; description: string; doc_values: boolean; example: number; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.public_key_size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.serial_number': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.signature_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.subject.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.subject.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.subject.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.subject.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.subject.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.subject.organizational_unit': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.subject.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.file.x509.version_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.first_seen': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.ip': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.last_seen': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.marking.tlp': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.marking.tlp_version': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.modified_at': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.port': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.provider': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.registry.data.bytes': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.registry.data.strings': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.registry.data.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.registry.hive': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.registry.key': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.registry.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.registry.value': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.scanner_stats': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.sightings': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.type': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.indicator.url.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.extension': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.fragment': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.full': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.original': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.password': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.path': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.port': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.query': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.scheme': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.url.username': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.alternative_names': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.issuer.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.issuer.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.issuer.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.issuer.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.issuer.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.issuer.organizational_unit': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.issuer.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.public_key_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.public_key_curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.public_key_exponent': { dashed_name: string; description: string; doc_values: boolean; example: number; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.public_key_size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.serial_number': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.signature_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.subject.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.subject.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.subject.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.subject.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.subject.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.subject.organizational_unit': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.subject.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.indicator.x509.version_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.enrichments.matched.atomic': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.matched.field': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.matched.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.matched.index': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.matched.occurred': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.enrichments.matched.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.feed.dashboard_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.feed.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.feed.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.feed.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.framework': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.group.alias': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.group.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.group.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.group.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.as.number': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.as.organization.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.confidence': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.email.address': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.file.accessed': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.attributes': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.digest_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.exists': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.signing_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.status': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.subject_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.team_id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.timestamp': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.trusted': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.code_signature.valid': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.created': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.ctime': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.device': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.directory': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.drive_letter': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.byte_order': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.cpu_type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.creation_date': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.exports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.abi_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.class': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.data': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.entrypoint': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.object_version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.os_abi': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.header.version': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.chi2': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.flags': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.physical_offset': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.virtual_address': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.segments': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.segments.sections': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.segments.type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.shared_libraries': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.elf.telfhash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.extension': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.fork_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.gid': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.group': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.hash.md5': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.hash.sha1': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.hash.sha256': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.hash.sha384': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.hash.sha512': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.hash.ssdeep': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.hash.tlsh': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.inode': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.mime_type': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.mode': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.mtime': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.owner': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.architecture': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.company': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.file_version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.go_import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.go_imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.go_imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.go_imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.go_stripped': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.imphash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.import_hash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.imports': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.imports_names_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.imports_names_var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.original_file_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.pehash': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.product': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.sections': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.sections.entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.sections.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.sections.physical_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.sections.var_entropy': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.pe.sections.virtual_size': { dashed_name: string; description: string; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.target_path': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.uid': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.alternative_names': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.issuer.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.issuer.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.issuer.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.issuer.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.issuer.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.issuer.organizational_unit': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.issuer.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.public_key_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.public_key_curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.public_key_exponent': { dashed_name: string; description: string; doc_values: boolean; example: number; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.public_key_size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.serial_number': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.signature_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.subject.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.subject.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.subject.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.subject.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.subject.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.subject.organizational_unit': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.subject.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.file.x509.version_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.first_seen': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.geo.city_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.continent_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.continent_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.country_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.country_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.location': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.postal_code': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.region_iso_code': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.region_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.geo.timezone': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.ip': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.last_seen': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.marking.tlp': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.marking.tlp_version': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.modified_at': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.port': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.provider': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.registry.data.bytes': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.registry.data.strings': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.registry.data.type': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.registry.hive': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.registry.key': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.registry.path': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.registry.value': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.scanner_stats': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.sightings': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.type': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.indicator.url.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.extension': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.fragment': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.full': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.original': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.password': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.path': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.port': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.query': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.scheme': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.url.username': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.alternative_names': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.issuer.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.issuer.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.issuer.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.issuer.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.issuer.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.issuer.organizational_unit': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.issuer.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.public_key_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.public_key_curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.public_key_exponent': { dashed_name: string; description: string; doc_values: boolean; example: number; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.public_key_size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.serial_number': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.signature_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.subject.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.subject.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.subject.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.subject.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.subject.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.subject.organizational_unit': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.subject.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'threat.indicator.x509.version_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'threat.software.alias': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.software.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.software.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.software.platforms': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.software.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.software.type': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'threat.tactic.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.tactic.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.tactic.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.technique.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.technique.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: string[]; short: string; type: string; }; 'threat.technique.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.technique.subtechnique.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'threat.technique.subtechnique.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: string[]; short: string; type: string; }; 'threat.technique.subtechnique.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'tls.cipher': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.certificate': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.certificate_chain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'tls.client.hash.md5': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.hash.sha1': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.hash.sha256': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.issuer': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.ja3': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.server_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.subject': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.client.supported_ciphers': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'tls.client.x509.alternative_names': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.issuer.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.issuer.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.issuer.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.issuer.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.issuer.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.issuer.organizational_unit': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.issuer.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.public_key_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.public_key_curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.public_key_exponent': { dashed_name: string; description: string; doc_values: boolean; example: number; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.public_key_size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.serial_number': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.signature_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.subject.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.subject.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.subject.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.subject.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.subject.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.subject.organizational_unit': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.subject.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.client.x509.version_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.established': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.next_protocol': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.resumed': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.certificate': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.certificate_chain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'tls.server.hash.md5': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.hash.sha1': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.hash.sha256': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.issuer': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.ja3s': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.subject': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.server.x509.alternative_names': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.issuer.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.issuer.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.issuer.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.issuer.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.issuer.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.issuer.organizational_unit': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.issuer.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.not_after': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.not_before': { dashed_name: string; description: string; example: string; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.public_key_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.public_key_curve': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.public_key_exponent': { dashed_name: string; description: string; doc_values: boolean; example: number; flat_name: string; index: boolean; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.public_key_size': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.serial_number': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.signature_algorithm': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.subject.common_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.subject.country': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.subject.distinguished_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.subject.locality': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.subject.organization': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.subject.organizational_unit': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.subject.state_or_province': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'tls.server.x509.version_number': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'tls.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'tls.version_protocol': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'trace.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'transaction.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.extension': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.fragment': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.full': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'url.original': { dashed_name: string; description: string; example: string; flat_name: string; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'url.password': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.path': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.port': { dashed_name: string; description: string; example: number; flat_name: string; format: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.query': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.registered_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.scheme': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.subdomain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.top_level_domain': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'url.username': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'user.changes.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.changes.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'user.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'user.effective.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.effective.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'user.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'user.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'user.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'user.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'user.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'user.risk.calculated_level': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.risk.calculated_score': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.risk.calculated_score_norm': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.risk.static_level': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.risk.static_score': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.risk.static_score_norm': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'user.target.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.email': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.full_name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.group.domain': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.group.id': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.group.name': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.hash': { dashed_name: string; description: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user.target.roles': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; original_fieldset: string; short: string; type: string; }; 'user_agent.device.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'user_agent.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'user_agent.original': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'user_agent.os.family': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user_agent.os.full': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user_agent.os.kernel': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user_agent.os.name': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user_agent.os.platform': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user_agent.os.type': { dashed_name: string; description: string; example: string; expected_values: string[]; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user_agent.os.version': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; original_fieldset: string; short: string; type: string; }; 'user_agent.version': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.category': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: string[]; short: string; type: string; }; 'vulnerability.classification': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.description': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; multi_fields: { flat_name: string; name: string; type: string; }[]; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.enumeration': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.id': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.reference': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.report_id': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.scanner.vendor': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.score.base': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.score.environmental': { dashed_name: string; description: string; example: number; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.score.temporal': { dashed_name: string; description: string; flat_name: string; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.score.version': { dashed_name: string; description: string; example: number; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; 'vulnerability.severity': { dashed_name: string; description: string; example: string; flat_name: string; ignore_above: number; level: string; name: string; normalize: never[]; short: string; type: string; }; }" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [ + { + "parentPluginId": "fieldsMetadata", + "id": "def-common.fieldMetadataPlainRT", + "type": "Object", + "tags": [], + "label": "fieldMetadataPlainRT", + "description": [], + "signature": [ + "IntersectionC", + "<[", + "TypeC", + "<{ name: ", + "StringC", + "; }>, ", + "PartialC", + "<{ allowed_values: ", + "ArrayC", + "<", + "IntersectionC", + "<[", + "TypeC", + "<{ description: ", + "StringC", + "; name: ", + "StringC", + "; }>, ", + "PartialC", + "<{ expected_event_types: ", + "ArrayC", + "<", + "StringC", + ">; beta: ", + "StringC", + "; }>]>>; beta: ", + "StringC", + "; dashed_name: ", + "StringC", + "; description: ", + "StringC", + "; doc_values: ", + "BooleanC", + "; example: ", + "UnknownC", + "; expected_values: ", + "ArrayC", + "<", + "StringC", + ">; flat_name: ", + "StringC", + "; format: ", + "StringC", + "; ignore_above: ", + "NumberC", + "; index: ", + "BooleanC", + "; input_format: ", + "StringC", + "; level: ", + "StringC", + "; multi_fields: ", + "ArrayC", + "<", + "TypeC", + "<{ flat_name: ", + "StringC", + "; name: ", + "StringC", + "; type: ", + "StringC", + "; }>>; normalize: ", + "ArrayC", + "<", + "StringC", + ">; object_type: ", + "StringC", + "; original_fieldset: ", + "StringC", + "; output_format: ", + "StringC", + "; output_precision: ", + "NumberC", + "; pattern: ", + "StringC", + "; required: ", + "BooleanC", + "; scaling_factor: ", + "NumberC", + "; short: ", + "StringC", + "; source: ", + "KeyofC", + "<{ ecs: null; integration: null; unknown: null; }>; type: ", + "StringC", + "; }>]>" + ], + "path": "x-pack/plugins/fields_metadata/common/fields_metadata/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ] + } +} \ No newline at end of file diff --git a/api_docs/fields_metadata.mdx b/api_docs/fields_metadata.mdx new file mode 100644 index 0000000000000..e8907fca5b10c --- /dev/null +++ b/api_docs/fields_metadata.mdx @@ -0,0 +1,61 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibFieldsMetadataPluginApi +slug: /kibana-dev-docs/api/fieldsMetadata +title: "fieldsMetadata" +image: https://source.unsplash.com/400x175/?github +description: API docs for the fieldsMetadata plugin +date: 2024-06-06 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldsMetadata'] +--- +import fieldsMetadataObj from './fields_metadata.devdocs.json'; + +Exposes services for async usage and search of fields metadata. + +Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 39 | 0 | 39 | 7 | + +## Client + +### Setup + + +### Start + + +### Interfaces + + +## Server + +### Setup + + +### Start + + +### Consts, variables and types + + +## Common + +### Objects + + +### Classes + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index dc94e0e07c876..2cb302c00a3af 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: 2024-06-05 +date: 2024-06-06 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 e1b00b3fefd77..1e712361ce570 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: 2024-06-05 +date: 2024-06-06 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 c607e70f12424..5e54d26dd3720 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index 4323df4ca5710..9a94c33392803 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -7480,6 +7480,26 @@ "path": "x-pack/plugins/fleet/server/plugin.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-server.FleetSetupDeps.fieldsMetadata", + "type": "Object", + "tags": [], + "label": "fieldsMetadata", + "description": [], + "signature": [ + { + "pluginId": "fieldsMetadata", + "scope": "server", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-server.FieldsMetadataServerSetup", + "text": "FieldsMetadataServerSetup" + } + ], + "path": "x-pack/plugins/fleet/server/plugin.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -8326,7 +8346,7 @@ "label": "getPackage", "description": [], "signature": [ - "(packageName: string, packageVersion: string) => Promise<{ packageInfo: ", + "(packageName: string, packageVersion: string, options?: { ignoreUnverified?: boolean | undefined; } | undefined) => Promise<{ paths: string[]; packageInfo: ", { "pluginId": "fleet", "scope": "common", @@ -8334,7 +8354,11 @@ "section": "def-common.ArchivePackage", "text": "ArchivePackage" }, - "; paths: string[]; }>" + "; assetsMap: ", + "AssetsMap", + "; verificationResult?: ", + "PackageVerificationResult", + " | undefined; }>" ], "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", "deprecated": false, @@ -8369,6 +8393,76 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackageClient.getPackage.$3", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "{ ignoreUnverified?: boolean | undefined; } | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackageClient.getPackageFieldsMetadata", + "type": "Function", + "tags": [], + "label": "getPackageFieldsMetadata", + "description": [], + "signature": [ + "(params: { packageName: string; datasetName?: string | undefined; }, options?: { excludedFieldsAssets?: string[] | undefined; } | undefined) => Promise<", + { + "pluginId": "fieldsMetadata", + "scope": "server", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-server.ExtractedIntegrationFields", + "text": "ExtractedIntegrationFields" + }, + ">" + ], + "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackageClient.getPackageFieldsMetadata.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "{ packageName: string; datasetName?: string | undefined; }" + ], + "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackageClient.getPackageFieldsMetadata.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "{ excludedFieldsAssets?: string[] | undefined; } | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [] @@ -19453,6 +19547,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "fleet", + "id": "def-common.AgentPolicy.space_id", + "type": "string", + "tags": [], + "label": "space_id", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/agent_policy.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "fleet", "id": "def-common.AgentPolicy.status", @@ -21158,6 +21266,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "fleet", + "id": "def-common.FullAgentPolicy.namespaces", + "type": "Array", + "tags": [], + "label": "namespaces", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/agent_policy.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "fleet", "id": "def-common.FullAgentPolicy.outputs", @@ -26400,21 +26522,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "fleet", - "id": "def-common.FLEET_SERVER_SERVERS_INDEX", - "type": "string", - "tags": [], - "label": "FLEET_SERVER_SERVERS_INDEX", - "description": [], - "signature": [ - "\".fleet-servers\"" - ], - "path": "x-pack/plugins/fleet/common/constants/index.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "fleet", "id": "def-common.FLEET_SYNTHETICS_PACKAGE", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index c70634c5c6b95..46ab5547e135b 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1329 | 5 | 1208 | 69 | +| 1335 | 5 | 1214 | 71 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 527ddc2cf51cd..db33ffce5d161 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: 2024-06-05 +date: 2024-06-06 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 cca990045a059..de3163d291ce2 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: 2024-06-05 +date: 2024-06-06 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 bd6531ba1ceb9..c474a65bab10e 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: 2024-06-05 +date: 2024-06-06 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 6f4d3fec1811b..cee062a239e1d 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: 2024-06-05 +date: 2024-06-06 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 dbc92c5cf922c..be4e0f89815d2 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: 2024-06-05 +date: 2024-06-06 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 46df890f8428a..55f95671f92f7 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: 2024-06-05 +date: 2024-06-06 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 a11b76955488c..25eca7c718271 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/ingest_pipelines.mdx b/api_docs/ingest_pipelines.mdx index b13b8b8dd1ff1..093e13defe8be 100644 --- a/api_docs/ingest_pipelines.mdx +++ b/api_docs/ingest_pipelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ingestPipelines title: "ingestPipelines" image: https://source.unsplash.com/400x175/?github description: API docs for the ingestPipelines plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ingestPipelines'] --- import ingestPipelinesObj from './ingest_pipelines.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 704ff05bd4208..49515f37cf2de 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: 2024-06-05 +date: 2024-06-06 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 81757417b0582..63b5d223fdf7a 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: 2024-06-05 +date: 2024-06-06 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 09fcaac9bf1dc..85e950d6e6424 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 007b242d32cc8..cce95321c94ed 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 55ed34bac5a33..49bf0e2f749e6 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_pattern_analysis.mdx b/api_docs/kbn_aiops_log_pattern_analysis.mdx index 3ab0a6163ac19..438ace7befe4c 100644 --- a/api_docs/kbn_aiops_log_pattern_analysis.mdx +++ b/api_docs/kbn_aiops_log_pattern_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-pattern-analysis title: "@kbn/aiops-log-pattern-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-pattern-analysis plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-pattern-analysis'] --- import kbnAiopsLogPatternAnalysisObj from './kbn_aiops_log_pattern_analysis.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_rate_analysis.mdx b/api_docs/kbn_aiops_log_rate_analysis.mdx index 4d102b95a8790..59a1c372ef75b 100644 --- a/api_docs/kbn_aiops_log_rate_analysis.mdx +++ b/api_docs/kbn_aiops_log_rate_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-rate-analysis title: "@kbn/aiops-log-rate-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-rate-analysis plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-rate-analysis'] --- import kbnAiopsLogRateAnalysisObj from './kbn_aiops_log_rate_analysis.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 791f048b956f8..0cdfe8935f838 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_comparators.mdx b/api_docs/kbn_alerting_comparators.mdx index b0b6955b0cc72..b3d39c3d6ec46 100644 --- a/api_docs/kbn_alerting_comparators.mdx +++ b/api_docs/kbn_alerting_comparators.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-comparators title: "@kbn/alerting-comparators" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-comparators plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-comparators'] --- import kbnAlertingComparatorsObj from './kbn_alerting_comparators.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 8a77d1f1499c3..cbd30df625f75 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index 8c85406acb3e8..ff5a6d8c22dcb 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 622df9ae1d281..500c6236e95fc 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: 2024-06-05 +date: 2024-06-06 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 2bd1dd6daaf2f..9c667b3522904 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: 2024-06-05 +date: 2024-06-06 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 85aba8bbda942..70e1b0b2dbc2f 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: 2024-06-05 +date: 2024-06-06 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 25a7c2f3293d9..df44979f314f7 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index ee876ddeb8cf4..8482f52521779 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.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 5a3e84257bb2b..9ce8481c30da5 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: 2024-06-05 +date: 2024-06-06 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 1475ce7b7e97d..8eb5fda7b929d 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: 2024-06-05 +date: 2024-06-06 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 e727292283797..e984adf2bebf2 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: 2024-06-05 +date: 2024-06-06 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 5555e035ed1dd..74c2781ab4482 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index b27b1e1d7641a..dda3f94651ab5 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: 2024-06-05 +date: 2024-06-06 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_data_view.mdx b/api_docs/kbn_apm_data_view.mdx index 95ef06f7d37ea..58ce0150f0329 100644 --- a/api_docs/kbn_apm_data_view.mdx +++ b/api_docs/kbn_apm_data_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-data-view title: "@kbn/apm-data-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-data-view plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-data-view'] --- import kbnApmDataViewObj from './kbn_apm_data_view.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 14e06148cf562..205b8fcc594f2 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: 2024-06-05 +date: 2024-06-06 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 942f6958c1230..74c7107084985 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: 2024-06-05 +date: 2024-06-06 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 1b7372452aca6..3a20094c648cb 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: 2024-06-05 +date: 2024-06-06 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 a94ecaebf13d2..064ff2a12ae48 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index d7c81979b51b6..2970d9800d9be 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index 2afa9e4e5da5f..6654928a90454 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index 01112cc4527a2..df124fbdfe9bb 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 594fc60c5df8e..7326dce204cbd 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: 2024-06-05 +date: 2024-06-06 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 c36ecdc5b7c8a..7697bacb81a9b 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: 2024-06-05 +date: 2024-06-06 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 85311473df631..3c27536c713e7 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: 2024-06-05 +date: 2024-06-06 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 833d92ba5f08a..bc58103b4dd8c 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: 2024-06-05 +date: 2024-06-06 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 55d63bb63651a..e4ba2f711cc18 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: 2024-06-05 +date: 2024-06-06 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 b3a603bd94f76..4231923343a18 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: 2024-06-05 +date: 2024-06-06 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 103c33d7f960e..8850c07f6481e 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: 2024-06-05 +date: 2024-06-06 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 1edc06f2e17d3..1927e2bed10fb 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: 2024-06-05 +date: 2024-06-06 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 beaa6c5ea38dc..feb6795e1a4da 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mock.mdx b/api_docs/kbn_code_editor_mock.mdx index 007cdd8e19495..028912c58cc79 100644 --- a/api_docs/kbn_code_editor_mock.mdx +++ b/api_docs/kbn_code_editor_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mock title: "@kbn/code-editor-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mock plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mock'] --- import kbnCodeEditorMockObj from './kbn_code_editor_mock.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index 68281cce07b8e..10218de434d8b 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 3a34d3d05ea0a..709559355773b 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: 2024-06-05 +date: 2024-06-06 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 06a88dcfd4e93..376468689feb4 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: 2024-06-05 +date: 2024-06-06 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 8d1dd41ce0365..6b2a88816993d 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: 2024-06-05 +date: 2024-06-06 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 35f66bce9fe8f..8ee3161ebfc2e 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: 2024-06-05 +date: 2024-06-06 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 11ec0c6169ca0..19c23a2b6c561 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: 2024-06-05 +date: 2024-06-06 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 486fc644ae073..252c492b32446 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: 2024-06-05 +date: 2024-06-06 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 8bc1ff20f5df7..f078cd4dd1170 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: 2024-06-05 +date: 2024-06-06 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_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index ede2219227138..b1762ebc509d2 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.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 4ba90b4dbee5b..4cad839e77967 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: 2024-06-05 +date: 2024-06-06 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 b7ec5313f9fb2..dde15fe10284a 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: 2024-06-05 +date: 2024-06-06 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 531dd243033ba..d4e27553bac9d 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: 2024-06-05 +date: 2024-06-06 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 3d123b2e7b5ea..7c6e56b192fc8 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: 2024-06-05 +date: 2024-06-06 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 8768cebe13710..fc75be5859b02 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: 2024-06-05 +date: 2024-06-06 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 39e66d12d319e..178955a658cfb 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: 2024-06-05 +date: 2024-06-06 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 916df560716ed..a59b562eb3e4a 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: 2024-06-05 +date: 2024-06-06 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 1f1b2610329e8..1dd2f9e32fda2 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: 2024-06-05 +date: 2024-06-06 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 ddb4211b42e7a..01f3431ac68c9 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: 2024-06-05 +date: 2024-06-06 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 d27030d6c60b2..c78440551baff 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: 2024-06-05 +date: 2024-06-06 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 31c815e0cdf58..51201c1965b7a 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: 2024-06-05 +date: 2024-06-06 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 c3cc070c247ee..bded4148954a3 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: 2024-06-05 +date: 2024-06-06 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 009d223be143a..35991368aa9d2 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: 2024-06-05 +date: 2024-06-06 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 b946ef578f474..f05501b894930 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: 2024-06-05 +date: 2024-06-06 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 8c4770b5346cf..6e1c945f25efd 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: 2024-06-05 +date: 2024-06-06 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 9fca022c70eb2..00ee2c16f0913 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: 2024-06-05 +date: 2024-06-06 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 ff891f1282f85..605bf086eeafc 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: 2024-06-05 +date: 2024-06-06 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 1d9828563610a..0e4ffa01786fe 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: 2024-06-05 +date: 2024-06-06 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 fd2531afc3455..9bb4110c0f9a0 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: 2024-06-05 +date: 2024-06-06 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 841c7b0ca57ad..14d150341fdc4 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: 2024-06-05 +date: 2024-06-06 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 58e1c780e1ae8..4ee71981d57d3 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: 2024-06-05 +date: 2024-06-06 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 3933c683eecc5..86c8d55e89ff7 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: 2024-06-05 +date: 2024-06-06 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 d747577ec3874..51b1e4c192d1f 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: 2024-06-05 +date: 2024-06-06 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 976115a72a0cc..1edf9458265b5 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: 2024-06-05 +date: 2024-06-06 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 b00aa99ccdaef..99ae5060f915f 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: 2024-06-05 +date: 2024-06-06 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 5ca0b6a51b1c8..2154a771e31cf 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: 2024-06-05 +date: 2024-06-06 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 b3709527cccd8..279f48304661b 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: 2024-06-05 +date: 2024-06-06 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 38a0eb7f49509..f8bd5f8ed9aeb 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: 2024-06-05 +date: 2024-06-06 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 127c0d3c884f2..c69b47542ac39 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: 2024-06-05 +date: 2024-06-06 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 35530b12d80f2..1eb0822fd1241 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: 2024-06-05 +date: 2024-06-06 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 8c0bd814c7298..5355271133437 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: 2024-06-05 +date: 2024-06-06 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 a2d5ac543f43d..90817c07bd280 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: 2024-06-05 +date: 2024-06-06 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 90ce3fefa61b8..3b719ec23fe5e 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: 2024-06-05 +date: 2024-06-06 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 2e1de4a80b7b1..70358fcbf98c0 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: 2024-06-05 +date: 2024-06-06 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 a71efbe4423bf..63504c0cf73c1 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: 2024-06-05 +date: 2024-06-06 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 a2fbe5ec762d4..82ab1368ec4eb 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: 2024-06-05 +date: 2024-06-06 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 a1af92782a76e..3dea741c7c6e6 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: 2024-06-05 +date: 2024-06-06 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 76a45e5231832..5beb921a71ddf 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: 2024-06-05 +date: 2024-06-06 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 81b296cabb4c6..79e130e95ece9 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: 2024-06-05 +date: 2024-06-06 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 8049ffa24ff49..ab4daeefb4eea 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: 2024-06-05 +date: 2024-06-06 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 d0c199a2d8513..eb8f9dab8154a 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: 2024-06-05 +date: 2024-06-06 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 f65db4920a0a3..e4e2056b71388 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: 2024-06-05 +date: 2024-06-06 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 871ed55b6b7da..00830ee60b2d2 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: 2024-06-05 +date: 2024-06-06 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 747835841ddb9..c9cb0975aacb1 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: 2024-06-05 +date: 2024-06-06 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 e7d06203595a3..1a077837893e8 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: 2024-06-05 +date: 2024-06-06 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 91604c9293c47..07ee5bc870dd4 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: 2024-06-05 +date: 2024-06-06 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 fd50465b9f4a9..0f9d38cf67764 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: 2024-06-05 +date: 2024-06-06 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 9b56a2878f875..17f8d2f7aa802 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: 2024-06-05 +date: 2024-06-06 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 1c4a5c2f48de5..7343d4c1eaf95 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: 2024-06-05 +date: 2024-06-06 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 a7ec2e4cf3484..037fe6b97844d 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: 2024-06-05 +date: 2024-06-06 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 922ae2f0e272c..d6f663dcec122 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: 2024-06-05 +date: 2024-06-06 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 fee7e84a3e301..9f79cdc3bac1a 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: 2024-06-05 +date: 2024-06-06 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 5d22fbdcc9f94..0f8bbbf74e2f5 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: 2024-06-05 +date: 2024-06-06 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 824691665b7ea..10660c180bd37 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: 2024-06-05 +date: 2024-06-06 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 0db8271c5a5f0..09d0bf2872258 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: 2024-06-05 +date: 2024-06-06 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 db52fbc8f205c..34293a467d3b4 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: 2024-06-05 +date: 2024-06-06 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 7405cff6c0d2a..a4766db8d8663 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: 2024-06-05 +date: 2024-06-06 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 db1c795663298..0d91cb66fbff2 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: 2024-06-05 +date: 2024-06-06 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 f26385e7c02f0..19e79559c277b 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: 2024-06-05 +date: 2024-06-06 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 f50a0138d9b55..8e5ee17c10bb4 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: 2024-06-05 +date: 2024-06-06 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 6b83912b12678..1a8eb0d274c17 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: 2024-06-05 +date: 2024-06-06 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 ad771681d50cc..2f4d538d3edba 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: 2024-06-05 +date: 2024-06-06 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 caade77662b7f..2b926c62b7197 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: 2024-06-05 +date: 2024-06-06 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 0a86916b26d4c..35b7592118496 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: 2024-06-05 +date: 2024-06-06 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 0fe2c527e34c9..6b1e8f7cc8709 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: 2024-06-05 +date: 2024-06-06 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 abb2deaf0913c..37fb139f01c15 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: 2024-06-05 +date: 2024-06-06 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 7f06c25213833..e16bd5187f033 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: 2024-06-05 +date: 2024-06-06 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 66ee6504c35c9..40cccc4a8db02 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: 2024-06-05 +date: 2024-06-06 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 01f2d45af626b..0d7fcb6c7efee 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: 2024-06-05 +date: 2024-06-06 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 c5c718d8f0cb5..12dcd7effb801 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: 2024-06-05 +date: 2024-06-06 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 c8a1f89c91ee3..0045c6b631c7b 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: 2024-06-05 +date: 2024-06-06 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.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index 79dd391fa119b..f3eff9964da8a 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -13984,6 +13984,10 @@ "plugin": "telemetry", "path": "src/plugins/telemetry/server/routes/telemetry_last_reported.ts" }, + { + "plugin": "fieldsMetadata", + "path": "x-pack/plugins/fields_metadata/server/routes/fields_metadata/find_fields_metadata.ts" + }, { "plugin": "fleet", "path": "x-pack/plugins/fleet/server/services/security/fleet_router.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 88214c19e1757..50f9fe6d0824a 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: 2024-06-05 +date: 2024-06-06 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 13a272ca13826..bbac5900dd663 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: 2024-06-05 +date: 2024-06-06 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 137aeb008d79d..ab056dc9de223 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: 2024-06-05 +date: 2024-06-06 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 522a9d33e5197..63676705354c4 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: 2024-06-05 +date: 2024-06-06 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 5ed6a37ed3f5b..b9069438abe0e 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: 2024-06-05 +date: 2024-06-06 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 b1791db464297..2b77d83e2823b 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: 2024-06-05 +date: 2024-06-06 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 49549ccfe8ee3..53bac42144476 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: 2024-06-05 +date: 2024-06-06 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 7094be1d84a05..286c38c1df469 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: 2024-06-05 +date: 2024-06-06 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 5b8bf93add9e4..4ec88a0041dc3 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: 2024-06-05 +date: 2024-06-06 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 28cff639fc30e..769c1c31a97ea 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: 2024-06-05 +date: 2024-06-06 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 d51f32973b4ff..de4727659517a 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: 2024-06-05 +date: 2024-06-06 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 f146263605819..2d284b67cae7c 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: 2024-06-05 +date: 2024-06-06 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 f82a9b10888cb..0cfc7ac404cc3 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: 2024-06-05 +date: 2024-06-06 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 69268e7f5bea6..a56a9a52f39cd 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: 2024-06-05 +date: 2024-06-06 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 87be5fa2ddc3c..f5fc717c37233 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: 2024-06-05 +date: 2024-06-06 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 48b67dce6f9fe..9889b8642595f 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: 2024-06-05 +date: 2024-06-06 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 5486c47a62ead..6910793d98892 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: 2024-06-05 +date: 2024-06-06 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 92bdf89d54a17..360d448b01d50 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: 2024-06-05 +date: 2024-06-06 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 02d70f12a426f..a81561b4c9287 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: 2024-06-05 +date: 2024-06-06 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 efba20139c497..bf066b8029e61 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: 2024-06-05 +date: 2024-06-06 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 2dcebc8f705d4..df9c61b7318dc 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: 2024-06-05 +date: 2024-06-06 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 d7e81cb16b81f..69c2b784713ba 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: 2024-06-05 +date: 2024-06-06 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 a2ed99543132c..dc439705586a2 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: 2024-06-05 +date: 2024-06-06 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 98afbcbd9032d..ec9034e044faa 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: 2024-06-05 +date: 2024-06-06 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 26d322b6f717b..27ad67647ffee 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: 2024-06-05 +date: 2024-06-06 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 91ec2e563d37f..f6f83d1211586 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: 2024-06-05 +date: 2024-06-06 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 3a4d1417757d6..e8fe1ff5b21fa 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: 2024-06-05 +date: 2024-06-06 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 3da7120d80faa..e7b9db77a355f 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: 2024-06-05 +date: 2024-06-06 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 74e6abb7a3837..4503e277f2666 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: 2024-06-05 +date: 2024-06-06 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 8285479dfb7a5..22b669f3a2678 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: 2024-06-05 +date: 2024-06-06 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 b2a54a8831547..b954bb10affea 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: 2024-06-05 +date: 2024-06-06 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 b568bf7a9d250..33ed0e3531c57 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: 2024-06-05 +date: 2024-06-06 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 ff572d075e081..fbbcbdcb461b6 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: 2024-06-05 +date: 2024-06-06 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 d4bd2a6eb52ce..8337ac3385699 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: 2024-06-05 +date: 2024-06-06 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 2e4215ac232e8..cb7a2e1a84280 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: 2024-06-05 +date: 2024-06-06 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 8c32261f432c2..f6f9a9bdb2d5f 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: 2024-06-05 +date: 2024-06-06 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 21e5c93587448..305584026b0a5 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: 2024-06-05 +date: 2024-06-06 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_contracts_browser.mdx b/api_docs/kbn_core_plugins_contracts_browser.mdx index b6c0b8167a1da..dbbc16ef7eda2 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-browser'] --- import kbnCorePluginsContractsBrowserObj from './kbn_core_plugins_contracts_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_server.mdx b/api_docs/kbn_core_plugins_contracts_server.mdx index af9aa19c3a5d0..dd98e8d7aeb7f 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-server'] --- import kbnCorePluginsContractsServerObj from './kbn_core_plugins_contracts_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 8caed749fb104..a66dba7c552a2 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: 2024-06-05 +date: 2024-06-06 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 dfc236c0e90bf..caec03a291c13 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: 2024-06-05 +date: 2024-06-06 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 810eb30ba8afa..6c5638bab7cb7 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: 2024-06-05 +date: 2024-06-06 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 94aadceac51e7..ca06a738fe79c 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: 2024-06-05 +date: 2024-06-06 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 50c618b952bd2..fdc9e94e6f694 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: 2024-06-05 +date: 2024-06-06 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 728fb29444dd4..76d80febd7280 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: 2024-06-05 +date: 2024-06-06 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 1ae9288341395..3bd8c24fcf985 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: 2024-06-05 +date: 2024-06-06 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 3a84584f63be8..085793e469ca0 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: 2024-06-05 +date: 2024-06-06 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 2ea7feb3e6e13..0ca6c5366c0e1 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: 2024-06-05 +date: 2024-06-06 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 86d6d1c3d158a..2dbdc9f4e068e 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: 2024-06-05 +date: 2024-06-06 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 8d3fee92f0531..84ede3fa1b7d5 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: 2024-06-05 +date: 2024-06-06 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 9d94a7899c7a7..b2e5f541a4108 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: 2024-06-05 +date: 2024-06-06 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 510af495000f5..dc3a5005c4430 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: 2024-06-05 +date: 2024-06-06 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 a50930627d63b..647d20de24018 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: 2024-06-05 +date: 2024-06-06 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 f16ade4e3aa79..f826658ed4e45 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: 2024-06-05 +date: 2024-06-06 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 3f1d9af8cf16d..5e826de2a9353 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index dc3ed71976258..005697e5808ec 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: 2024-06-05 +date: 2024-06-06 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 512e8a5cc98be..20de326e3ae0b 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: 2024-06-05 +date: 2024-06-06 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 10a57360fb3e0..b226dd828b662 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: 2024-06-05 +date: 2024-06-06 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 1209144c00d96..8e1ce7cd36664 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: 2024-06-05 +date: 2024-06-06 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 5c8f9ab7d8e97..ce9d721488141 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: 2024-06-05 +date: 2024-06-06 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 9404348e113a3..a74765e8dfd2d 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: 2024-06-05 +date: 2024-06-06 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 406bdb4117a16..61cac73b73599 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: 2024-06-05 +date: 2024-06-06 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 a4688633ef107..c51a3d559d27e 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: 2024-06-05 +date: 2024-06-06 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 ba5224cb2da31..13b937485b797 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: 2024-06-05 +date: 2024-06-06 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_security_browser.mdx b/api_docs/kbn_core_security_browser.mdx index 8d7c70bfcafeb..60f5af1d984bc 100644 --- a/api_docs/kbn_core_security_browser.mdx +++ b/api_docs/kbn_core_security_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser title: "@kbn/core-security-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser'] --- import kbnCoreSecurityBrowserObj from './kbn_core_security_browser.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_internal.mdx b/api_docs/kbn_core_security_browser_internal.mdx index f4b9c3aae6e73..57eb45503d600 100644 --- a/api_docs/kbn_core_security_browser_internal.mdx +++ b/api_docs/kbn_core_security_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-internal title: "@kbn/core-security-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-internal plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-internal'] --- import kbnCoreSecurityBrowserInternalObj from './kbn_core_security_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_mocks.mdx b/api_docs/kbn_core_security_browser_mocks.mdx index 5f00ef37d81f8..94cf22a9d552d 100644 --- a/api_docs/kbn_core_security_browser_mocks.mdx +++ b/api_docs/kbn_core_security_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-mocks title: "@kbn/core-security-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-mocks plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-mocks'] --- import kbnCoreSecurityBrowserMocksObj from './kbn_core_security_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_security_common.mdx b/api_docs/kbn_core_security_common.mdx index d1b26ebeff3ba..57ac41274be53 100644 --- a/api_docs/kbn_core_security_common.mdx +++ b/api_docs/kbn_core_security_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-common title: "@kbn/core-security-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-common'] --- import kbnCoreSecurityCommonObj from './kbn_core_security_common.devdocs.json'; diff --git a/api_docs/kbn_core_security_server.mdx b/api_docs/kbn_core_security_server.mdx index d5c40ec06a341..18325bf1651ac 100644 --- a/api_docs/kbn_core_security_server.mdx +++ b/api_docs/kbn_core_security_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server title: "@kbn/core-security-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server'] --- import kbnCoreSecurityServerObj from './kbn_core_security_server.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_internal.mdx b/api_docs/kbn_core_security_server_internal.mdx index dbfd838f4512f..87bb44d41d03c 100644 --- a/api_docs/kbn_core_security_server_internal.mdx +++ b/api_docs/kbn_core_security_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-internal title: "@kbn/core-security-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-internal plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-internal'] --- import kbnCoreSecurityServerInternalObj from './kbn_core_security_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_mocks.mdx b/api_docs/kbn_core_security_server_mocks.mdx index 03b8942888c82..b2ddb893b89a6 100644 --- a/api_docs/kbn_core_security_server_mocks.mdx +++ b/api_docs/kbn_core_security_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-mocks title: "@kbn/core-security-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-mocks plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-mocks'] --- import kbnCoreSecurityServerMocksObj from './kbn_core_security_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index e159d96b31426..3c839bb8e0902 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: 2024-06-05 +date: 2024-06-06 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 1b03974c74374..15bc5bd8309f4 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: 2024-06-05 +date: 2024-06-06 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 a444f4d6748f0..f4a7643c4acfd 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: 2024-06-05 +date: 2024-06-06 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 480e2cc306b3a..901fe64810128 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: 2024-06-05 +date: 2024-06-06 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 2ae100beb279b..998d17664276f 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: 2024-06-05 +date: 2024-06-06 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 6476db47c8326..2682ca4c5a9c4 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: 2024-06-05 +date: 2024-06-06 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 f1f00a609d99d..ae341e9c3e050 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: 2024-06-05 +date: 2024-06-06 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 1a1d42cdb6966..60aa630e9d912 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: 2024-06-05 +date: 2024-06-06 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_model_versions.mdx b/api_docs/kbn_core_test_helpers_model_versions.mdx index ccfc107f999c5..aafca4a09f770 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-model-versions'] --- import kbnCoreTestHelpersModelVersionsObj from './kbn_core_test_helpers_model_versions.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 e245b0704e48d..dee1fc002cffc 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: 2024-06-05 +date: 2024-06-06 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 9a9af7001cf38..dbebc77fa5fe7 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: 2024-06-05 +date: 2024-06-06 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 c92bcae9a5b5a..dd7c5a5719c84 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: 2024-06-05 +date: 2024-06-06 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_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index f1a96c6840a4c..f130231ef8e10 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: 2024-06-05 +date: 2024-06-06 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 ab53cb4aa0ccf..c4d4694122e2a 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: 2024-06-05 +date: 2024-06-06 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 c76d477815de3..fffdeff228570 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: 2024-06-05 +date: 2024-06-06 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 75bb1d96b969a..65ef01a286ec0 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: 2024-06-05 +date: 2024-06-06 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 b6c34f17740aa..1f28ee212a18e 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: 2024-06-05 +date: 2024-06-06 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 f9e5de0734a2a..e9fccc01ab61d 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: 2024-06-05 +date: 2024-06-06 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 d2bc29dc41c2a..8b20cd8e50aa9 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: 2024-06-05 +date: 2024-06-06 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 ea711b2297d90..a101c255f3244 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: 2024-06-05 +date: 2024-06-06 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 edf596c32409b..47b27c6e58503 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: 2024-06-05 +date: 2024-06-06 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 36a685f5ab0ec..2a0bf0e7794b6 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: 2024-06-05 +date: 2024-06-06 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 6f289ebd0e7ae..529466e00862b 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: 2024-06-05 +date: 2024-06-06 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_profile_browser.mdx b/api_docs/kbn_core_user_profile_browser.mdx index 45bc3cfaefe84..171c7cf1a29ea 100644 --- a/api_docs/kbn_core_user_profile_browser.mdx +++ b/api_docs/kbn_core_user_profile_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser title: "@kbn/core-user-profile-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser'] --- import kbnCoreUserProfileBrowserObj from './kbn_core_user_profile_browser.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_internal.mdx b/api_docs/kbn_core_user_profile_browser_internal.mdx index d82314c4d7d42..450484366f626 100644 --- a/api_docs/kbn_core_user_profile_browser_internal.mdx +++ b/api_docs/kbn_core_user_profile_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-internal title: "@kbn/core-user-profile-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-internal plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-internal'] --- import kbnCoreUserProfileBrowserInternalObj from './kbn_core_user_profile_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_mocks.mdx b/api_docs/kbn_core_user_profile_browser_mocks.mdx index 966e6516441ec..2d2cab336aa7b 100644 --- a/api_docs/kbn_core_user_profile_browser_mocks.mdx +++ b/api_docs/kbn_core_user_profile_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-mocks title: "@kbn/core-user-profile-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-mocks plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-mocks'] --- import kbnCoreUserProfileBrowserMocksObj from './kbn_core_user_profile_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_common.mdx b/api_docs/kbn_core_user_profile_common.mdx index 7ef10f4ec5c15..2989952f0b26c 100644 --- a/api_docs/kbn_core_user_profile_common.mdx +++ b/api_docs/kbn_core_user_profile_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-common title: "@kbn/core-user-profile-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-common'] --- import kbnCoreUserProfileCommonObj from './kbn_core_user_profile_common.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server.mdx b/api_docs/kbn_core_user_profile_server.mdx index 337aa76617432..fa29cb692b158 100644 --- a/api_docs/kbn_core_user_profile_server.mdx +++ b/api_docs/kbn_core_user_profile_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server title: "@kbn/core-user-profile-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server'] --- import kbnCoreUserProfileServerObj from './kbn_core_user_profile_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_internal.mdx b/api_docs/kbn_core_user_profile_server_internal.mdx index 2136bfacd3c97..fb2ec358dc59b 100644 --- a/api_docs/kbn_core_user_profile_server_internal.mdx +++ b/api_docs/kbn_core_user_profile_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-internal title: "@kbn/core-user-profile-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-internal plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-internal'] --- import kbnCoreUserProfileServerInternalObj from './kbn_core_user_profile_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_mocks.mdx b/api_docs/kbn_core_user_profile_server_mocks.mdx index 74ace54ea75d1..4264b73dd9619 100644 --- a/api_docs/kbn_core_user_profile_server_mocks.mdx +++ b/api_docs/kbn_core_user_profile_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-mocks title: "@kbn/core-user-profile-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-mocks plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-mocks'] --- import kbnCoreUserProfileServerMocksObj from './kbn_core_user_profile_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 2697b9a0db2ea..17f3b2818faea 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: 2024-06-05 +date: 2024-06-06 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_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 75f3dfbffdb57..a3b120109e3c7 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: 2024-06-05 +date: 2024-06-06 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 4e69f1c6d4e48..a8f074a147163 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: 2024-06-05 +date: 2024-06-06 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 86ceeafe3c82c..3059edfae6e92 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_icons.mdx b/api_docs/kbn_custom_icons.mdx index 53e240cbf19c4..b55196acb98a7 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-icons'] --- import kbnCustomIconsObj from './kbn_custom_icons.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index 1af921f94178d..815fb6d9d13cf 100644 --- a/api_docs/kbn_custom_integrations.mdx +++ b/api_docs/kbn_custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-integrations title: "@kbn/custom-integrations" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-integrations plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-integrations'] --- import kbnCustomIntegrationsObj from './kbn_custom_integrations.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 173b39a085c9a..bbd309d1c720c 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_forge.mdx b/api_docs/kbn_data_forge.mdx index a88979f63fb75..bc794f0cf19ce 100644 --- a/api_docs/kbn_data_forge.mdx +++ b/api_docs/kbn_data_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-forge title: "@kbn/data-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-forge plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-forge'] --- import kbnDataForgeObj from './kbn_data_forge.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index ea60b222e5486..f85865e50f2c7 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_data_stream_adapter.mdx b/api_docs/kbn_data_stream_adapter.mdx index 300abd336b96e..3819e315a2960 100644 --- a/api_docs/kbn_data_stream_adapter.mdx +++ b/api_docs/kbn_data_stream_adapter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-stream-adapter title: "@kbn/data-stream-adapter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-stream-adapter plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-stream-adapter'] --- import kbnDataStreamAdapterObj from './kbn_data_stream_adapter.devdocs.json'; diff --git a/api_docs/kbn_data_view_utils.mdx b/api_docs/kbn_data_view_utils.mdx index 3e7d3b40377a6..0e42ac9f36ab2 100644 --- a/api_docs/kbn_data_view_utils.mdx +++ b/api_docs/kbn_data_view_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-view-utils title: "@kbn/data-view-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-view-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-view-utils'] --- import kbnDataViewUtilsObj from './kbn_data_view_utils.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 6fe149edabfa1..ce4f2e42843d9 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: 2024-06-05 +date: 2024-06-06 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 54a91cc24402f..095d545eac671 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: 2024-06-05 +date: 2024-06-06 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 7d323693b396c..20920d355c178 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_fleet.mdx b/api_docs/kbn_deeplinks_fleet.mdx index b049d34d83013..76ffebe96c030 100644 --- a/api_docs/kbn_deeplinks_fleet.mdx +++ b/api_docs/kbn_deeplinks_fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-fleet title: "@kbn/deeplinks-fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-fleet plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-fleet'] --- import kbnDeeplinksFleetObj from './kbn_deeplinks_fleet.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index e429cfda37245..6aec967f6af10 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: 2024-06-05 +date: 2024-06-06 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 3b74723f63e0e..16cef106f87b3 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: 2024-06-05 +date: 2024-06-06 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 1e2f3725851d7..366ac8d1b5e9a 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: 2024-06-05 +date: 2024-06-06 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 dfc485abd4be6..89acf665dca51 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_security.mdx b/api_docs/kbn_deeplinks_security.mdx index ac350787ab8e7..df164eee52761 100644 --- a/api_docs/kbn_deeplinks_security.mdx +++ b/api_docs/kbn_deeplinks_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-security title: "@kbn/deeplinks-security" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-security plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-security'] --- import kbnDeeplinksSecurityObj from './kbn_deeplinks_security.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_shared.mdx b/api_docs/kbn_deeplinks_shared.mdx index 5e8e8ae5ad8ea..4bbefb30db1f9 100644 --- a/api_docs/kbn_deeplinks_shared.mdx +++ b/api_docs/kbn_deeplinks_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-shared title: "@kbn/deeplinks-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-shared plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-shared'] --- import kbnDeeplinksSharedObj from './kbn_deeplinks_shared.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index c98676fe8b854..6950d5dd296c6 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: 2024-06-05 +date: 2024-06-06 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 97487c07eb1f3..c64cea23f0a77 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: 2024-06-05 +date: 2024-06-06 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 827209c635284..7ae11628e535e 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: 2024-06-05 +date: 2024-06-06 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 ff44272386184..09a9e230a65d7 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: 2024-06-05 +date: 2024-06-06 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 52d0a96c630ae..be995597425cd 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: 2024-06-05 +date: 2024-06-06 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 ef4ba383cd4cf..0a7ed8faec87a 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: 2024-06-05 +date: 2024-06-06 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 dca12cc50a44d..4737c9a9d1250 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: 2024-06-05 +date: 2024-06-06 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 542ad1d163196..dc72d61fecf8f 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 7104e5f24c812..794af4d7a92cf 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 9f29b4dce871c..590233a86c512 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: 2024-06-05 +date: 2024-06-06 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 e9a1b5771f4b3..8e8ce8925bca9 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: 2024-06-05 +date: 2024-06-06 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 7f1c8a5d17914..170b27d29236b 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: 2024-06-05 +date: 2024-06-06 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 471b4bd02994c..23f286773aa22 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 0ff7c3de0a207..e64b22fbe24d8 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: 2024-06-05 +date: 2024-06-06 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_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index 76fa3dc4999c0..76de8d3d838b8 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-agent-utils'] --- import kbnElasticAgentUtilsObj from './kbn_elastic_agent_utils.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index fa56282c7d4bd..12ede6e557145 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant_common.mdx b/api_docs/kbn_elastic_assistant_common.mdx index 793413695b3e5..2d5aa7b027db2 100644 --- a/api_docs/kbn_elastic_assistant_common.mdx +++ b/api_docs/kbn_elastic_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant-common title: "@kbn/elastic-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_entities_schema.devdocs.json b/api_docs/kbn_entities_schema.devdocs.json index 8c34887cde94e..b021defec9a79 100644 --- a/api_docs/kbn_entities_schema.devdocs.json +++ b/api_docs/kbn_entities_schema.devdocs.json @@ -63,7 +63,7 @@ "section": "def-common.EntityType", "text": "EntityType" }, - "; name: string; managed: boolean; indexPatterns: string[]; timestampField: string; identityFields: ({ field: string; optional: boolean; } | { field: string; optional: boolean; })[]; identityTemplate: string; lookback: { toJSON: () => string; clone(): moment.Duration; humanize(argWithSuffix?: boolean | undefined, argThresholds?: moment.argThresholdOpts | undefined): string; humanize(argThresholds?: moment.argThresholdOpts | undefined): string; abs(): moment.Duration; as(units: moment.unitOfTime.Base): number; get(units: moment.unitOfTime.Base): number; milliseconds(): number; asMilliseconds(): number; seconds(): number; asSeconds(): number; minutes(): number; asMinutes(): number; hours(): number; asHours(): number; days(): number; asDays(): number; weeks(): number; asWeeks(): number; months(): number; asMonths(): number; years(): number; asYears(): number; add(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; subtract(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; locale(): string; locale(locale: moment.LocaleSpecifier): moment.Duration; localeData(): moment.Locale; toISOString(): string; isValid(): boolean; lang(locale: moment.LocaleSpecifier): moment.Moment; lang(): moment.Locale; toIsoString(): string; format: moment.Format; }; description?: string | undefined; filter?: string | undefined; metadata?: ({ source: string; destination?: string | undefined; limit?: number | undefined; } | { source: string; destination: string; limit: number; })[] | undefined; metrics?: { name: string; metrics: ({ name: string; field: string; aggregation: ", + "; name: string; history: { interval: moment.Duration; timestampField: string; lookbackPeriod?: moment.Duration | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }; managed: boolean; indexPatterns: string[]; identityFields: ({ field: string; optional: boolean; } | { field: string; optional: boolean; })[]; displayNameTemplate: string; description?: string | undefined; filter?: string | undefined; metadata?: ({ source: string; destination?: string | undefined; limit?: number | undefined; } | { source: string; destination: string; limit: number; })[] | undefined; metrics?: { name: string; metrics: ({ name: string; field: string; aggregation: ", { "pluginId": "@kbn/entities-schema", "scope": "common", @@ -71,7 +71,7 @@ "section": "def-common.BasicAggregations", "text": "BasicAggregations" }, - "; filter?: string | undefined; } | { name: string; aggregation: \"doc_count\"; filter?: string | undefined; } | { name: string; field: string; percentile: number; aggregation: \"percentile\"; filter?: string | undefined; })[]; equation: string; }[] | undefined; staticFields?: Record | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }" + "; filter?: string | undefined; } | { name: string; aggregation: \"doc_count\"; filter?: string | undefined; } | { name: string; field: string; percentile: number; aggregation: \"percentile\"; filter?: string | undefined; })[]; equation: string; }[] | undefined; staticFields?: Record | undefined; latest?: { settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; } | undefined; }" ], "path": "x-pack/packages/kbn-entities-schema/src/schema/entity_definition.ts", "deprecated": false, @@ -226,7 +226,7 @@ "label": "durationSchema", "description": [], "signature": [ - "Zod.ZodEffects string; clone(): moment.Duration; humanize(argWithSuffix?: boolean | undefined, argThresholds?: moment.argThresholdOpts | undefined): string; humanize(argThresholds?: moment.argThresholdOpts | undefined): string; abs(): moment.Duration; as(units: moment.unitOfTime.Base): number; get(units: moment.unitOfTime.Base): number; milliseconds(): number; asMilliseconds(): number; seconds(): number; asSeconds(): number; minutes(): number; asMinutes(): number; hours(): number; asHours(): number; days(): number; asDays(): number; weeks(): number; asWeeks(): number; months(): number; asMonths(): number; years(): number; asYears(): number; add(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; subtract(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; locale(): string; locale(locale: moment.LocaleSpecifier): moment.Duration; localeData(): moment.Locale; toISOString(): string; isValid(): boolean; lang(locale: moment.LocaleSpecifier): moment.Moment; lang(): moment.Locale; toIsoString(): string; format: moment.Format; }, string>" + "Zod.ZodEffects" ], "path": "x-pack/packages/kbn-entities-schema/src/schema/common.ts", "deprecated": false, @@ -249,7 +249,7 @@ "section": "def-common.EntityType", "text": "EntityType" }, - ">; filter: Zod.ZodOptional; indexPatterns: Zod.ZodArray; identityFields: Zod.ZodArray, Zod.ZodEffects]>, \"many\">; identityTemplate: Zod.ZodString; metadata: Zod.ZodOptional; limit: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { source: string; destination?: string | undefined; limit?: number | undefined; }, { source: string; destination?: string | undefined; limit?: number | undefined; }>, Zod.ZodEffects]>, \"many\">>; metrics: Zod.ZodOptional; filter: Zod.ZodOptional; indexPatterns: Zod.ZodArray; identityFields: Zod.ZodArray, Zod.ZodEffects]>, \"many\">; displayNameTemplate: Zod.ZodString; metadata: Zod.ZodOptional; limit: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { source: string; destination?: string | undefined; limit?: number | undefined; }, { source: string; destination?: string | undefined; limit?: number | undefined; }>, Zod.ZodEffects]>, \"many\">>; metrics: Zod.ZodOptional, \"many\">>; staticFields: Zod.ZodOptional>; lookback: Zod.ZodEffects string; clone(): moment.Duration; humanize(argWithSuffix?: boolean | undefined, argThresholds?: moment.argThresholdOpts | undefined): string; humanize(argThresholds?: moment.argThresholdOpts | undefined): string; abs(): moment.Duration; as(units: moment.unitOfTime.Base): number; get(units: moment.unitOfTime.Base): number; milliseconds(): number; asMilliseconds(): number; seconds(): number; asSeconds(): number; minutes(): number; asMinutes(): number; hours(): number; asHours(): number; days(): number; asDays(): number; weeks(): number; asWeeks(): number; months(): number; asMonths(): number; years(): number; asYears(): number; add(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; subtract(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; locale(): string; locale(locale: moment.LocaleSpecifier): moment.Duration; localeData(): moment.Locale; toISOString(): string; isValid(): boolean; lang(locale: moment.LocaleSpecifier): moment.Moment; lang(): moment.Locale; toIsoString(): string; format: moment.Format; }, string>; timestampField: Zod.ZodString; managed: Zod.ZodDefault>; settings: Zod.ZodOptional; syncDelay: Zod.ZodOptional; frequency: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; }, { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { id: string; type: ", + "; filter?: string | undefined; } | { name: string; aggregation: \"doc_count\"; filter?: string | undefined; } | { name: string; field: string; percentile: number; aggregation: \"percentile\"; filter?: string | undefined; })[]; equation: string; }>, \"many\">>; staticFields: Zod.ZodOptional>; managed: Zod.ZodDefault>; history: Zod.ZodObject<{ timestampField: Zod.ZodString; interval: Zod.ZodEffects, moment.Duration, string>; lookbackPeriod: Zod.ZodOptional>; settings: Zod.ZodOptional; syncDelay: Zod.ZodOptional; frequency: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; }, { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { interval: moment.Duration; timestampField: string; lookbackPeriod?: moment.Duration | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }, { interval: string; timestampField: string; lookbackPeriod?: string | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }>; latest: Zod.ZodOptional; syncDelay: Zod.ZodOptional; frequency: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; }, { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }, { settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { id: string; type: ", { "pluginId": "@kbn/entities-schema", "scope": "common", @@ -297,7 +297,7 @@ "section": "def-common.EntityType", "text": "EntityType" }, - "; name: string; managed: boolean; indexPatterns: string[]; timestampField: string; identityFields: ({ field: string; optional: boolean; } | { field: string; optional: boolean; })[]; identityTemplate: string; lookback: { toJSON: () => string; clone(): moment.Duration; humanize(argWithSuffix?: boolean | undefined, argThresholds?: moment.argThresholdOpts | undefined): string; humanize(argThresholds?: moment.argThresholdOpts | undefined): string; abs(): moment.Duration; as(units: moment.unitOfTime.Base): number; get(units: moment.unitOfTime.Base): number; milliseconds(): number; asMilliseconds(): number; seconds(): number; asSeconds(): number; minutes(): number; asMinutes(): number; hours(): number; asHours(): number; days(): number; asDays(): number; weeks(): number; asWeeks(): number; months(): number; asMonths(): number; years(): number; asYears(): number; add(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; subtract(inp?: moment.DurationInputArg1, unit?: moment.unitOfTime.DurationConstructor | undefined): moment.Duration; locale(): string; locale(locale: moment.LocaleSpecifier): moment.Duration; localeData(): moment.Locale; toISOString(): string; isValid(): boolean; lang(locale: moment.LocaleSpecifier): moment.Moment; lang(): moment.Locale; toIsoString(): string; format: moment.Format; }; description?: string | undefined; filter?: string | undefined; metadata?: ({ source: string; destination?: string | undefined; limit?: number | undefined; } | { source: string; destination: string; limit: number; })[] | undefined; metrics?: { name: string; metrics: ({ name: string; field: string; aggregation: ", + "; name: string; history: { interval: moment.Duration; timestampField: string; lookbackPeriod?: moment.Duration | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }; managed: boolean; indexPatterns: string[]; identityFields: ({ field: string; optional: boolean; } | { field: string; optional: boolean; })[]; displayNameTemplate: string; description?: string | undefined; filter?: string | undefined; metadata?: ({ source: string; destination?: string | undefined; limit?: number | undefined; } | { source: string; destination: string; limit: number; })[] | undefined; metrics?: { name: string; metrics: ({ name: string; field: string; aggregation: ", { "pluginId": "@kbn/entities-schema", "scope": "common", @@ -305,7 +305,7 @@ "section": "def-common.BasicAggregations", "text": "BasicAggregations" }, - "; filter?: string | undefined; } | { name: string; aggregation: \"doc_count\"; filter?: string | undefined; } | { name: string; field: string; percentile: number; aggregation: \"percentile\"; filter?: string | undefined; })[]; equation: string; }[] | undefined; staticFields?: Record | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }, { id: string; type: ", + "; filter?: string | undefined; } | { name: string; aggregation: \"doc_count\"; filter?: string | undefined; } | { name: string; field: string; percentile: number; aggregation: \"percentile\"; filter?: string | undefined; })[]; equation: string; }[] | undefined; staticFields?: Record | undefined; latest?: { settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; } | undefined; }, { id: string; type: ", { "pluginId": "@kbn/entities-schema", "scope": "common", @@ -313,7 +313,7 @@ "section": "def-common.EntityType", "text": "EntityType" }, - "; name: string; indexPatterns: string[]; timestampField: string; identityFields: (string | { field: string; optional: boolean; })[]; identityTemplate: string; lookback: string; description?: string | undefined; filter?: string | undefined; metadata?: (string | { source: string; destination?: string | undefined; limit?: number | undefined; })[] | undefined; metrics?: { name: string; metrics: ({ name: string; field: string; aggregation: ", + "; name: string; history: { interval: string; timestampField: string; lookbackPeriod?: string | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }; indexPatterns: string[]; identityFields: (string | { field: string; optional: boolean; })[]; displayNameTemplate: string; description?: string | undefined; filter?: string | undefined; metadata?: (string | { source: string; destination?: string | undefined; limit?: number | undefined; })[] | undefined; metrics?: { name: string; metrics: ({ name: string; field: string; aggregation: ", { "pluginId": "@kbn/entities-schema", "scope": "common", @@ -321,7 +321,7 @@ "section": "def-common.BasicAggregations", "text": "BasicAggregations" }, - "; filter?: string | undefined; } | { name: string; aggregation: \"doc_count\"; filter?: string | undefined; } | { name: string; field: string; percentile: number; aggregation: \"percentile\"; filter?: string | undefined; })[]; equation: string; }[] | undefined; staticFields?: Record | undefined; managed?: boolean | undefined; settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; }>" + "; filter?: string | undefined; } | { name: string; aggregation: \"doc_count\"; filter?: string | undefined; } | { name: string; field: string; percentile: number; aggregation: \"percentile\"; filter?: string | undefined; })[]; equation: string; }[] | undefined; staticFields?: Record | undefined; managed?: boolean | undefined; latest?: { settings?: { syncField?: string | undefined; syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; } | undefined; }>" ], "path": "x-pack/packages/kbn-entities-schema/src/schema/entity_definition.ts", "deprecated": false, @@ -330,13 +330,28 @@ }, { "parentPluginId": "@kbn/entities-schema", - "id": "def-common.entitySchema", + "id": "def-common.entityHistorySchema", "type": "Object", "tags": [], - "label": "entitySchema", + "label": "entityHistorySchema", "description": [], "signature": [ - "Zod.ZodIntersection; identityFields: Zod.ZodArray; metric: Zod.ZodRecord; spaceId: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; spaceId: string; indexPatterns: string[]; metric: Record; identityFields: string[]; }, { id: string; spaceId: string; indexPatterns: string[]; metric: Record; identityFields: string[]; }>; }, \"strip\", Zod.ZodTypeAny, { entity: { id: string; spaceId: string; indexPatterns: string[]; metric: Record; identityFields: string[]; }; }, { entity: { id: string; spaceId: string; indexPatterns: string[]; metric: Record; identityFields: string[]; }; }>, Zod.ZodRecord>>" + "Zod.ZodIntersection; displayName: Zod.ZodString; spaceId: Zod.ZodString; metrics: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }, { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }>; \"@timestamp\": Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { \"@timestamp\": string; entity: { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }; }, { \"@timestamp\": string; entity: { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }; }>, Zod.ZodRecord>>" + ], + "path": "x-pack/packages/kbn-entities-schema/src/schema/entity.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/entities-schema", + "id": "def-common.entitySummarySchema", + "type": "Object", + "tags": [], + "label": "entitySummarySchema", + "description": [], + "signature": [ + "Zod.ZodIntersection; displayName: Zod.ZodString; spaceId: Zod.ZodString; metrics: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }, { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }>; lastSeenTimestamp: Zod.ZodString; firstSeenTimestamp: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { entity: { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }; lastSeenTimestamp: string; firstSeenTimestamp: string; }, { entity: { id: string; spaceId: string; metrics: Record; displayName: string; identityFields: string[]; }; lastSeenTimestamp: string; firstSeenTimestamp: string; }>, Zod.ZodRecord>>" ], "path": "x-pack/packages/kbn-entities-schema/src/schema/entity.ts", "deprecated": false, diff --git a/api_docs/kbn_entities_schema.mdx b/api_docs/kbn_entities_schema.mdx index 59901650a5878..2be750b43856e 100644 --- a/api_docs/kbn_entities_schema.mdx +++ b/api_docs/kbn_entities_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-entities-schema title: "@kbn/entities-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/entities-schema plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/entities-schema'] --- import kbnEntitiesSchemaObj from './kbn_entities_schema.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 19 | 0 | 19 | 0 | +| 20 | 0 | 20 | 0 | ## Common diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index bb433a7bc37b9..67ac80fb34ad1 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: 2024-06-05 +date: 2024-06-06 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 908f873291e79..8c3e21ee0e584 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: 2024-06-05 +date: 2024-06-06 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 5331d3263d2ca..48e5a3e4595d9 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: 2024-06-05 +date: 2024-06-06 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 a2e06984276b5..016e9d5f32f6c 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.devdocs.json b/api_docs/kbn_es_types.devdocs.json index 1caa6b1fda21f..09998ea2bf973 100644 --- a/api_docs/kbn_es_types.devdocs.json +++ b/api_docs/kbn_es_types.devdocs.json @@ -125,10 +125,10 @@ }, { "parentPluginId": "@kbn/es-types", - "id": "def-common.ESQLSearchReponse", + "id": "def-common.ESQLSearchResponse", "type": "Interface", "tags": [], - "label": "ESQLSearchReponse", + "label": "ESQLSearchResponse", "description": [], "path": "packages/kbn-es-types/src/search.ts", "deprecated": false, @@ -136,7 +136,7 @@ "children": [ { "parentPluginId": "@kbn/es-types", - "id": "def-common.ESQLSearchReponse.columns", + "id": "def-common.ESQLSearchResponse.columns", "type": "Array", "tags": [], "label": "columns", @@ -157,7 +157,7 @@ }, { "parentPluginId": "@kbn/es-types", - "id": "def-common.ESQLSearchReponse.all_columns", + "id": "def-common.ESQLSearchResponse.all_columns", "type": "Array", "tags": [], "label": "all_columns", @@ -178,7 +178,7 @@ }, { "parentPluginId": "@kbn/es-types", - "id": "def-common.ESQLSearchReponse.values", + "id": "def-common.ESQLSearchResponse.values", "type": "Array", "tags": [], "label": "values", diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 5b2281df541fe..2a6a44bfb42af 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: 2024-06-05 +date: 2024-06-06 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 f6298db9fe502..620e7e7172cf6 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_esql_ast.mdx b/api_docs/kbn_esql_ast.mdx index 091df034e0671..7861436737a69 100644 --- a/api_docs/kbn_esql_ast.mdx +++ b/api_docs/kbn_esql_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-ast title: "@kbn/esql-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-ast plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-ast'] --- import kbnEsqlAstObj from './kbn_esql_ast.devdocs.json'; diff --git a/api_docs/kbn_esql_utils.devdocs.json b/api_docs/kbn_esql_utils.devdocs.json index 9619ecf037296..ea0d6d6a8f6db 100644 --- a/api_docs/kbn_esql_utils.devdocs.json +++ b/api_docs/kbn_esql_utils.devdocs.json @@ -599,8 +599,8 @@ "pluginId": "@kbn/es-types", "scope": "common", "docId": "kibKbnEsTypesPluginApi", - "section": "def-common.ESQLSearchReponse", - "text": "ESQLSearchReponse" + "section": "def-common.ESQLSearchResponse", + "text": "ESQLSearchResponse" }, "; params: ", { diff --git a/api_docs/kbn_esql_utils.mdx b/api_docs/kbn_esql_utils.mdx index d86d7368656c2..a42b5fc12763a 100644 --- a/api_docs/kbn_esql_utils.mdx +++ b/api_docs/kbn_esql_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-utils title: "@kbn/esql-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_esql_validation_autocomplete.mdx b/api_docs/kbn_esql_validation_autocomplete.mdx index 7f16649c60e95..d441755a4f5aa 100644 --- a/api_docs/kbn_esql_validation_autocomplete.mdx +++ b/api_docs/kbn_esql_validation_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-validation-autocomplete title: "@kbn/esql-validation-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-validation-autocomplete plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-validation-autocomplete'] --- import kbnEsqlValidationAutocompleteObj from './kbn_esql_validation_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index d31fa1761b33a..3a5414e7bb7cd 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index 737e7be8bacb5..9a8ee90e9dbb5 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 1ddc5334f12db..b72f246865334 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: 2024-06-05 +date: 2024-06-06 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 2bee7450a19aa..4fc8ca88e523b 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 2fa70663accb4..481e252119175 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 56156e751deb2..9a5294e0ae564 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: 2024-06-05 +date: 2024-06-06 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_formatters.mdx b/api_docs/kbn_formatters.mdx index c3870e4a2f269..00ce8c0a26e34 100644 --- a/api_docs/kbn_formatters.mdx +++ b/api_docs/kbn_formatters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-formatters title: "@kbn/formatters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/formatters plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/formatters'] --- import kbnFormattersObj from './kbn_formatters.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 6d4e353d7ca17..7e2ebf6f66cc6 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: 2024-06-05 +date: 2024-06-06 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_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index 317e7f4ca94cb..ad45d713382cf 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 7f61054764b82..825c817d3ff19 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: 2024-06-05 +date: 2024-06-06 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 7250a05ad36e4..2234488f9130b 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: 2024-06-05 +date: 2024-06-06 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 83d556e764f57..6e217bd9a3a75 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_grouping.mdx b/api_docs/kbn_grouping.mdx index 7b02b984ce7bb..5bc41f33b9696 100644 --- a/api_docs/kbn_grouping.mdx +++ b/api_docs/kbn_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grouping title: "@kbn/grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grouping plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grouping'] --- import kbnGroupingObj from './kbn_grouping.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 7a4ab6376669f..20e31413166a3 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: 2024-06-05 +date: 2024-06-06 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 05a5c4d730541..95c8ee7d0ff69 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: 2024-06-05 +date: 2024-06-06 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 714f3d23f90f6..9806fc9d53d71 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: 2024-06-05 +date: 2024-06-06 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 3c860342b21be..7990b9dd93490 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: 2024-06-05 +date: 2024-06-06 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 eb0b9e3d9bb95..7683d54967a24 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: 2024-06-05 +date: 2024-06-06 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 df3a9908ca90e..a3a884da6175e 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: 2024-06-05 +date: 2024-06-06 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 cade74c3c2c95..6fdcc827304de 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: 2024-06-05 +date: 2024-06-06 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 d582dcfda04d6..4505e348a8359 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: 2024-06-05 +date: 2024-06-06 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 dc1262938e1fd..d3886d4088931 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_index_management.mdx b/api_docs/kbn_index_management.mdx index dc9598fef8099..f41501dc5a272 100644 --- a/api_docs/kbn_index_management.mdx +++ b/api_docs/kbn_index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-index-management title: "@kbn/index-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/index-management plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-management'] --- import kbnIndexManagementObj from './kbn_index_management.devdocs.json'; diff --git a/api_docs/kbn_inference_integration_flyout.mdx b/api_docs/kbn_inference_integration_flyout.mdx index e3a2ac1185731..b603c76dc4778 100644 --- a/api_docs/kbn_inference_integration_flyout.mdx +++ b/api_docs/kbn_inference_integration_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-inference_integration_flyout title: "@kbn/inference_integration_flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/inference_integration_flyout plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/inference_integration_flyout'] --- import kbnInferenceIntegrationFlyoutObj from './kbn_inference_integration_flyout.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 495e5f4eceb33..8481053e60c6c 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: 2024-06-05 +date: 2024-06-06 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 f6766401f9a45..80e6b8777fb8c 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.devdocs.json b/api_docs/kbn_io_ts_utils.devdocs.json index a175ad37ceda5..62c84e6da030d 100644 --- a/api_docs/kbn_io_ts_utils.devdocs.json +++ b/api_docs/kbn_io_ts_utils.devdocs.json @@ -942,6 +942,22 @@ } ], "objects": [ + { + "parentPluginId": "@kbn/io-ts-utils", + "id": "def-common.arrayToStringRt", + "type": "Object", + "tags": [], + "label": "arrayToStringRt", + "description": [], + "signature": [ + "Type", + "" + ], + "path": "packages/kbn-io-ts-utils/src/array_to_string_rt/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/io-ts-utils", "id": "def-common.DateFromStringOrNumber", diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 826a2e015d92c..31b7793c8bfe1 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 59 | 0 | 59 | 4 | +| 60 | 0 | 60 | 4 | ## Common diff --git a/api_docs/kbn_ipynb.mdx b/api_docs/kbn_ipynb.mdx index 340b97cb50f35..d54d4eaf8c788 100644 --- a/api_docs/kbn_ipynb.mdx +++ b/api_docs/kbn_ipynb.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ipynb title: "@kbn/ipynb" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ipynb plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ipynb'] --- import kbnIpynbObj from './kbn_ipynb.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 6b9d491326ec2..f0820e7db9f22 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: 2024-06-05 +date: 2024-06-06 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 012183e69c95f..47b6bbf013f98 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: 2024-06-05 +date: 2024-06-06 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 373423e47847f..21e5d7ad62bdd 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: 2024-06-05 +date: 2024-06-06 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 dabceb1ea1608..03eadb6054f51 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: 2024-06-05 +date: 2024-06-06 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 0f87ef6a9369b..77e8d495c4318 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index 9f651485f2b0b..e2d1a7abfd3d8 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_lens_formula_docs.mdx b/api_docs/kbn_lens_formula_docs.mdx index 7acc56e64569f..e33ed9495722c 100644 --- a/api_docs/kbn_lens_formula_docs.mdx +++ b/api_docs/kbn_lens_formula_docs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-formula-docs title: "@kbn/lens-formula-docs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-formula-docs plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-formula-docs'] --- import kbnLensFormulaDocsObj from './kbn_lens_formula_docs.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index b4d82c56b8901..464b66fea3882 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: 2024-06-05 +date: 2024-06-06 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 876167ef55c62..6439e9fe9242d 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_content_badge.mdx b/api_docs/kbn_managed_content_badge.mdx index d0ca0747d828f..34f338575dc3c 100644 --- a/api_docs/kbn_managed_content_badge.mdx +++ b/api_docs/kbn_managed_content_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-content-badge title: "@kbn/managed-content-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-content-badge plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-content-badge'] --- import kbnManagedContentBadgeObj from './kbn_managed_content_badge.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index f043a347ad6e1..821c75a6a01e1 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: 2024-06-05 +date: 2024-06-06 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 054e8409da644..e96bfc000c752 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: 2024-06-05 +date: 2024-06-06 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_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index b3193118a2ad3..02e2741887fc6 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index 6d09e5b646000..fa6a998d20dac 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index 25462b5124f72..64af43b129ed5 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-input'] --- import kbnManagementSettingsComponentsFieldInputObj from './kbn_management_settings_components_field_input.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_row.mdx b/api_docs/kbn_management_settings_components_field_row.mdx index 0ad429d7a47c4..3b623ec76df3c 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index eb9f638859990..dbc02d3412473 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index e794f3034430b..8e2f613f72e22 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-field-definition'] --- import kbnManagementSettingsFieldDefinitionObj from './kbn_management_settings_field_definition.devdocs.json'; diff --git a/api_docs/kbn_management_settings_ids.mdx b/api_docs/kbn_management_settings_ids.mdx index d61d058956929..c78540b4ab5b6 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index f44ea4a9921d8..13fb7ebbd709f 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-section-registry'] --- import kbnManagementSettingsSectionRegistryObj from './kbn_management_settings_section_registry.devdocs.json'; diff --git a/api_docs/kbn_management_settings_types.mdx b/api_docs/kbn_management_settings_types.mdx index 344fe3a340396..92491b21b93d5 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-types'] --- import kbnManagementSettingsTypesObj from './kbn_management_settings_types.devdocs.json'; diff --git a/api_docs/kbn_management_settings_utilities.mdx b/api_docs/kbn_management_settings_utilities.mdx index c2eea4430459a..70b43cc9f063d 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-utilities'] --- import kbnManagementSettingsUtilitiesObj from './kbn_management_settings_utilities.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index f1aad633aaf19..d25a5e79337f3 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: 2024-06-05 +date: 2024-06-06 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 d504314d55d07..7dc7ca53553fe 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: 2024-06-05 +date: 2024-06-06 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 15d76b62ed581..9add5bd501270 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: 2024-06-05 +date: 2024-06-06 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 3554304c217d9..0a91925f96637 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: 2024-06-05 +date: 2024-06-06 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 5865cb24bf3b0..a251ff4d1abf7 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: 2024-06-05 +date: 2024-06-06 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_cancellable_search.mdx b/api_docs/kbn_ml_cancellable_search.mdx index d673303b475f1..b5cc32726971f 100644 --- a/api_docs/kbn_ml_cancellable_search.mdx +++ b/api_docs/kbn_ml_cancellable_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-cancellable-search title: "@kbn/ml-cancellable-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-cancellable-search plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-cancellable-search'] --- import kbnMlCancellableSearchObj from './kbn_ml_cancellable_search.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index b6203d8e0f155..e1dca2bbd818f 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index a6e57e27df44e..c226a71f670e7 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.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 c0a8a560dc152..fcbf2c1e3e853 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: 2024-06-05 +date: 2024-06-06 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 efa311c6e9b00..0d8245c86450f 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: 2024-06-05 +date: 2024-06-06 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 40a88f0dd0d36..7d6ec8a79a78d 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: 2024-06-05 +date: 2024-06-06 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 4c799a558a7e8..920d1ef9de54e 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: 2024-06-05 +date: 2024-06-06 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 f16123340b054..fc4ef21de2b06 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: 2024-06-05 +date: 2024-06-06 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_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index d8a77b898ba13..745361f6b250f 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index f1a36981b2202..12066116ccb89 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: 2024-06-05 +date: 2024-06-06 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 7715a0687b19a..5a276a443e8f5 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: 2024-06-05 +date: 2024-06-06 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 4a3e9a2105b75..a3040a6f5dd68 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: 2024-06-05 +date: 2024-06-06 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 6e0ad19a7906e..90d519aed8550 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: 2024-06-05 +date: 2024-06-06 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 27245cd57556e..6ec3763865604 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: 2024-06-05 +date: 2024-06-06 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 14a809867bea5..208967c0e3dbb 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: 2024-06-05 +date: 2024-06-06 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 b20e6fda44fcb..949d725718b18 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: 2024-06-05 +date: 2024-06-06 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 c0c83f836050d..29acb9c13249f 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: 2024-06-05 +date: 2024-06-06 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 dffa3a3fa4c02..5a3c739b74767 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: 2024-06-05 +date: 2024-06-06 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 09fe9abea9422..e6b08aa4f47a4 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: 2024-06-05 +date: 2024-06-06 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 ca597a6a268ce..70c63a5c6ce04 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: 2024-06-05 +date: 2024-06-06 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_time_buckets.mdx b/api_docs/kbn_ml_time_buckets.mdx index 353abe9a68981..8582ab57e387b 100644 --- a/api_docs/kbn_ml_time_buckets.mdx +++ b/api_docs/kbn_ml_time_buckets.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-time-buckets title: "@kbn/ml-time-buckets" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-time-buckets plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-time-buckets'] --- import kbnMlTimeBucketsObj from './kbn_ml_time_buckets.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 8828855ac2d51..7bdefa1e1c3c4 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: 2024-06-05 +date: 2024-06-06 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_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index 1e2375b0370d1..71ded5d676ba7 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index b27fa8f78b94b..f4341114e0b10 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index c07f760c66350..95c1c0abf1a8e 100644 --- a/api_docs/kbn_mock_idp_utils.mdx +++ b/api_docs/kbn_mock_idp_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mock-idp-utils title: "@kbn/mock-idp-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mock-idp-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mock-idp-utils'] --- import kbnMockIdpUtilsObj from './kbn_mock_idp_utils.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 8c24449f2deb5..7c206bb2623e5 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: 2024-06-05 +date: 2024-06-06 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 c7ecfeb10d49b..8854f3c112282 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: 2024-06-05 +date: 2024-06-06 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 a78aad408ddfa..0cfb4790f2727 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index c373a90b0895e..b560823bb00b5 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index ee106ede7c1e5..52146763f43b4 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 442ca3c5e69d0..a214f84263bda 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index 307018c9ce66f..8c05dabd7aeb1 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index a4c78d1bc7f87..b267b100ef71c 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: 2024-06-05 +date: 2024-06-06 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 52a2889f36936..677e39f6b4bc4 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: 2024-06-05 +date: 2024-06-06 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 7bc7a428cbf8a..713d5d444ce71 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: 2024-06-05 +date: 2024-06-06 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_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index e40d5be6ab9b6..c5d41b114aa22 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index ee381d12a13a5..a9f9c4d06c5dd 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: 2024-06-05 +date: 2024-06-06 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_check.mdx b/api_docs/kbn_plugin_check.mdx index 69086d9bfc213..b657207cea809 100644 --- a/api_docs/kbn_plugin_check.mdx +++ b/api_docs/kbn_plugin_check.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-check title: "@kbn/plugin-check" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-check plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-check'] --- import kbnPluginCheckObj from './kbn_plugin_check.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 26e31258fdd0b..4247bf0a9158b 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: 2024-06-05 +date: 2024-06-06 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 d4a18d5bec71a..77ca04087f5a6 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_presentation_containers.devdocs.json b/api_docs/kbn_presentation_containers.devdocs.json index 1568d0f556103..716fbb0bf73cd 100644 --- a/api_docs/kbn_presentation_containers.devdocs.json +++ b/api_docs/kbn_presentation_containers.devdocs.json @@ -384,6 +384,101 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/presentation-containers", + "id": "def-common.combineCompatibleChildrenApis", + "type": "Function", + "tags": [], + "label": "combineCompatibleChildrenApis", + "description": [], + "signature": [ + "(api: unknown, observableKey: keyof ApiType, isCompatible: (api: unknown) => api is ApiType, emptyState: PublishingSubjectType, flattenMethod?: ((array: PublishingSubjectType[]) => PublishingSubjectType) | undefined) => ", + "Observable", + "" + ], + "path": "packages/presentation/presentation_containers/interfaces/presentation_container.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/presentation-containers", + "id": "def-common.combineCompatibleChildrenApis.$1", + "type": "Unknown", + "tags": [], + "label": "api", + "description": [], + "signature": [ + "unknown" + ], + "path": "packages/presentation/presentation_containers/interfaces/presentation_container.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/presentation-containers", + "id": "def-common.combineCompatibleChildrenApis.$2", + "type": "Uncategorized", + "tags": [], + "label": "observableKey", + "description": [], + "signature": [ + "keyof ApiType" + ], + "path": "packages/presentation/presentation_containers/interfaces/presentation_container.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/presentation-containers", + "id": "def-common.combineCompatibleChildrenApis.$3", + "type": "Function", + "tags": [], + "label": "isCompatible", + "description": [], + "signature": [ + "(api: unknown) => api is ApiType" + ], + "path": "packages/presentation/presentation_containers/interfaces/presentation_container.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/presentation-containers", + "id": "def-common.combineCompatibleChildrenApis.$4", + "type": "Uncategorized", + "tags": [], + "label": "emptyState", + "description": [], + "signature": [ + "PublishingSubjectType" + ], + "path": "packages/presentation/presentation_containers/interfaces/presentation_container.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/presentation-containers", + "id": "def-common.combineCompatibleChildrenApis.$5", + "type": "Function", + "tags": [], + "label": "flattenMethod", + "description": [], + "signature": [ + "((array: PublishingSubjectType[]) => PublishingSubjectType) | undefined" + ], + "path": "packages/presentation/presentation_containers/interfaces/presentation_container.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/presentation-containers", "id": "def-common.getContainerParentFromAPI", @@ -1177,17 +1272,7 @@ "section": "def-common.PresentationContainer", "text": "PresentationContainer" }, - " extends Partial<", - { - "pluginId": "@kbn/presentation-publishing", - "scope": "common", - "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishesViewMode", - "text": "PublishesViewMode" - }, - " & ", - "PublishesSettings", - ">,", + " extends ", { "pluginId": "@kbn/presentation-containers", "scope": "common", diff --git a/api_docs/kbn_presentation_containers.mdx b/api_docs/kbn_presentation_containers.mdx index 66e71b3bff34c..3e4b21def6cba 100644 --- a/api_docs/kbn_presentation_containers.mdx +++ b/api_docs/kbn_presentation_containers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-containers title: "@kbn/presentation-containers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-containers plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 76 | 0 | 65 | 1 | +| 82 | 0 | 71 | 0 | ## Common diff --git a/api_docs/kbn_presentation_publishing.devdocs.json b/api_docs/kbn_presentation_publishing.devdocs.json index 7852cd38d7ad4..a91b622e34450 100644 --- a/api_docs/kbn_presentation_publishing.devdocs.json +++ b/api_docs/kbn_presentation_publishing.devdocs.json @@ -704,6 +704,46 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/presentation-publishing", + "id": "def-common.apiPublishesFilters", + "type": "Function", + "tags": [], + "label": "apiPublishesFilters", + "description": [], + "signature": [ + "(unknownApi: unknown) => unknownApi is ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "common", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" + } + ], + "path": "packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/presentation-publishing", + "id": "def-common.apiPublishesFilters.$1", + "type": "Unknown", + "tags": [], + "label": "unknownApi", + "description": [], + "signature": [ + "unknown" + ], + "path": "packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/presentation-publishing", "id": "def-common.apiPublishesPanelDescription", @@ -4275,6 +4315,384 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/presentation-publishing", + "id": "def-common.PublishesFilters", + "type": "Interface", + "tags": [], + "label": "PublishesFilters", + "description": [], + "path": "packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/presentation-publishing", + "id": "def-common.PublishesFilters.filters$", + "type": "Object", + "tags": [], + "label": "filters$", + "description": [], + "signature": [ + "{ source: ", + "Observable", + " | undefined; readonly value: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined; error: (err: any) => void; forEach: { (next: (value: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined) => void): Promise; (next: (value: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined) => void, promiseCtor: PromiseConstructorLike): Promise; }; complete: () => void; getValue: () => ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined; pipe: { (): ", + "Observable", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined>;
(op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + ", op4: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + ", op4: ", + "OperatorFunction", + ", op5: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + ", op4: ", + "OperatorFunction", + ", op5: ", + "OperatorFunction", + ", op6: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + ", op4: ", + "OperatorFunction", + ", op5: ", + "OperatorFunction", + ", op6: ", + "OperatorFunction", + ", op7: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + ", op4: ", + "OperatorFunction", + ", op5: ", + "OperatorFunction", + ", op6: ", + "OperatorFunction", + ", op7: ", + "OperatorFunction", + ", op8: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + ", op4: ", + "OperatorFunction", + ", op5: ", + "OperatorFunction", + ", op6: ", + "OperatorFunction", + ", op7: ", + "OperatorFunction", + ", op8: ", + "OperatorFunction", + ", op9: ", + "OperatorFunction", + "): ", + "Observable", + "; (op1: ", + "OperatorFunction", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, A>, op2: ", + "OperatorFunction", + ", op3: ", + "OperatorFunction", + ", op4: ", + "OperatorFunction", + ", op5: ", + "OperatorFunction", + ", op6: ", + "OperatorFunction", + ", op7: ", + "OperatorFunction", + ", op8: ", + "OperatorFunction", + ", op9: ", + "OperatorFunction", + ", ...operations: ", + "OperatorFunction", + "[]): ", + "Observable", + "; }; closed: boolean; observers: ", + "Observer", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined>[]; isStopped: boolean; hasError: boolean; thrownError: any; lift: (operator: ", + "Operator", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined, R>) => ", + "Observable", + "; unsubscribe: () => void; readonly observed: boolean; asObservable: () => ", + "Observable", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined>; operator: ", + "Operator", + " | undefined; subscribe: { (observerOrNext?: Partial<", + "Observer", + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined>> | ((value: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined) => void) | undefined): ", + "Subscription", + "; (next?: ((value: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined) => void) | null | undefined, error?: ((error: any) => void) | null | undefined, complete?: (() => void) | null | undefined): ", + "Subscription", + "; }; toPromise: { (): Promise<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined>; (PromiseCtor: PromiseConstructor): Promise<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined>; (PromiseCtor: PromiseConstructorLike): Promise<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined>; }; }" + ], + "path": "packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/presentation-publishing", "id": "def-common.PublishesPanelDescription", @@ -5402,6 +5820,23 @@ "tags": [], "label": "PublishesTimeRange", "description": [], + "signature": [ + { + "pluginId": "@kbn/presentation-publishing", + "scope": "common", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-common.PublishesTimeRange", + "text": "PublishesTimeRange" + }, + " extends ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "common", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-common.PublishesTimeslice", + "text": "PublishesTimeslice" + } + ], "path": "packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts", "deprecated": false, "trackAdoption": false, @@ -5790,10 +6225,24 @@ "path": "packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts", "deprecated": false, "trackAdoption": false - }, + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/presentation-publishing", + "id": "def-common.PublishesTimeslice", + "type": "Interface", + "tags": [], + "label": "PublishesTimeslice", + "description": [], + "path": "packages/presentation/presentation_publishing/interfaces/fetch/publishes_unified_search.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "@kbn/presentation-publishing", - "id": "def-common.PublishesTimeRange.timeslice$", + "id": "def-common.PublishesTimeslice.timeslice$", "type": "Object", "tags": [], "label": "timeslice$", @@ -6712,23 +7161,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", @@ -6818,23 +7259,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", @@ -7119,7 +7552,7 @@ "label": "ViewMode", "description": [], "signature": [ - "\"edit\" | \"view\" | \"print\" | \"preview\"" + "\"edit\" | \"view\" | \"preview\" | \"print\"" ], "path": "packages/presentation/presentation_publishing/interfaces/publishes_view_mode.ts", "deprecated": false, diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index 103701c42a297..b45ce4abea611 100644 --- a/api_docs/kbn_presentation_publishing.mdx +++ b/api_docs/kbn_presentation_publishing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-publishing title: "@kbn/presentation-publishing" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-publishing plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 204 | 0 | 169 | 5 | +| 209 | 0 | 174 | 5 | ## Common diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index f4a95cc47e2cb..d67ed422e181c 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 6e148fe04ec5e..9fbde7e1ce37a 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: 2024-06-05 +date: 2024-06-06 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 6c14bdb52f93d..bedb6e8102b19 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_hooks.mdx b/api_docs/kbn_react_hooks.mdx index ae03c6634ae73..fd8de6c291fd9 100644 --- a/api_docs/kbn_react_hooks.mdx +++ b/api_docs/kbn_react_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-hooks title: "@kbn/react-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-hooks plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-hooks'] --- import kbnReactHooksObj from './kbn_react_hooks.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 6555bc962eacd..8283419df32e3 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index f5cd026d1ccf6..fab057a8bd5b8 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index eca3a14649ae0..e2b7293d7ccd6 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index e887d3700a0a1..5cc97bb13ae71 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index 1f6aa871def9e..d6432a839da39 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index 517bac5214506..f9ade2fbd3caa 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 1f6ff143dda3c..6865e689fa9f8 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: 2024-06-05 +date: 2024-06-06 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 75518319fda31..cdc2da85f6b61 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: 2024-06-05 +date: 2024-06-06 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 dbfe238ebea39..29e64b17c6c78 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: 2024-06-05 +date: 2024-06-06 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 cc51cfca0b103..a07a3b72baab1 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: 2024-06-05 +date: 2024-06-06 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 3f522dea4337b..68e79c1085608 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_csv_share_panel.mdx b/api_docs/kbn_reporting_csv_share_panel.mdx index 67e877a936706..53411116aa19c 100644 --- a/api_docs/kbn_reporting_csv_share_panel.mdx +++ b/api_docs/kbn_reporting_csv_share_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-csv-share-panel title: "@kbn/reporting-csv-share-panel" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-csv-share-panel plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-csv-share-panel'] --- import kbnReportingCsvSharePanelObj from './kbn_reporting_csv_share_panel.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 2dae98875726c..99514a50057a2 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index 63c433c3afc7b..f20e7d94cfb31 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index 31cf1a9407b61..7a9debe751eca 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index 80da7f8bb2e85..cbb3da2ea6858 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index 4ef75c51e8c88..8127661ff8263 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index 010968f87653d..adcd5fe4b476a 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index 2ae2cb325add6..9ab030fcc36c5 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index b833e963ca6a5..c416e7d7b46bf 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index 6e587f33910af..3fc0ceba6c245 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index 6fa13a08cdb41..36eb6e26eabd0 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index c4837bf0ac084..4219aac9a0a22 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_to_openapispec.mdx b/api_docs/kbn_router_to_openapispec.mdx index 5350f7213d7d5..c8b565819609f 100644 --- a/api_docs/kbn_router_to_openapispec.mdx +++ b/api_docs/kbn_router_to_openapispec.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-to-openapispec title: "@kbn/router-to-openapispec" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-to-openapispec plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-to-openapispec'] --- import kbnRouterToOpenapispecObj from './kbn_router_to_openapispec.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index ab34dc5ce6af5..0bb7c449fae02 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 1f90b2a663d26..13e27bea70d93 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: 2024-06-05 +date: 2024-06-06 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 f6cf002bf43fa..22cf7855949bc 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: 2024-06-05 +date: 2024-06-06 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 955be246d9bbd..557c59a894bcf 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 7b1f8c78f5a3f..dc3172f92c51a 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 895ac71e0cf77..2582599b32fc1 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index b2bd33803034c..4d8412b32ad75 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index 3e18a26df04a9..306b32146ebaa 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index d70a659e73784..4a01674c86fe1 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_search_types.mdx b/api_docs/kbn_search_types.mdx index 59d4b3fdead40..5e0479a5de430 100644 --- a/api_docs/kbn_search_types.mdx +++ b/api_docs/kbn_search_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-types title: "@kbn/search-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-types plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-types'] --- import kbnSearchTypesObj from './kbn_search_types.devdocs.json'; diff --git a/api_docs/kbn_security_hardening.mdx b/api_docs/kbn_security_hardening.mdx index c15d54f4973cf..0fd698f9f83bd 100644 --- a/api_docs/kbn_security_hardening.mdx +++ b/api_docs/kbn_security_hardening.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-hardening title: "@kbn/security-hardening" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-hardening plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-hardening'] --- import kbnSecurityHardeningObj from './kbn_security_hardening.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 097964a3d6192..1e7ed4ab97197 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.devdocs.json b/api_docs/kbn_security_plugin_types_public.devdocs.json index b09fb5fe59ed4..7f87070f3ade3 100644 --- a/api_docs/kbn_security_plugin_types_public.devdocs.json +++ b/api_docs/kbn_security_plugin_types_public.devdocs.json @@ -90,6 +90,28 @@ "trackAdoption": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.AuthorizationServiceSetup.roles", + "type": "Object", + "tags": [], + "label": "roles", + "description": [ + "\nA set of methods to work with Kibana user roles." + ], + "signature": [ + { + "pluginId": "@kbn/security-plugin-types-public", + "scope": "public", + "docId": "kibKbnSecurityPluginTypesPublicPluginApi", + "section": "def-public.RolesAPIClient", + "text": "RolesAPIClient" + } + ], + "path": "x-pack/packages/security/plugin_types_public/src/authorization/authorization_service.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -165,6 +187,210 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolePutPayload", + "type": "Interface", + "tags": [], + "label": "RolePutPayload", + "description": [], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolePutPayload.role", + "type": "Object", + "tags": [], + "label": "role", + "description": [], + "signature": [ + { + "pluginId": "@kbn/security-plugin-types-common", + "scope": "common", + "docId": "kibKbnSecurityPluginTypesCommonPluginApi", + "section": "def-common.Role", + "text": "Role" + } + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolePutPayload.createOnly", + "type": "CompoundType", + "tags": [], + "label": "createOnly", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient", + "type": "Interface", + "tags": [], + "label": "RolesAPIClient", + "description": [], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient.getRoles", + "type": "Function", + "tags": [], + "label": "getRoles", + "description": [], + "signature": [ + "() => Promise<", + { + "pluginId": "@kbn/security-plugin-types-common", + "scope": "common", + "docId": "kibKbnSecurityPluginTypesCommonPluginApi", + "section": "def-common.Role", + "text": "Role" + }, + "[]>" + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient.getRole", + "type": "Function", + "tags": [], + "label": "getRole", + "description": [], + "signature": [ + "(roleName: string) => Promise<", + { + "pluginId": "@kbn/security-plugin-types-common", + "scope": "common", + "docId": "kibKbnSecurityPluginTypesCommonPluginApi", + "section": "def-common.Role", + "text": "Role" + }, + ">" + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient.getRole.$1", + "type": "string", + "tags": [], + "label": "roleName", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient.deleteRole", + "type": "Function", + "tags": [], + "label": "deleteRole", + "description": [], + "signature": [ + "(roleName: string) => Promise" + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient.deleteRole.$1", + "type": "string", + "tags": [], + "label": "roleName", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient.saveRole", + "type": "Function", + "tags": [], + "label": "saveRole", + "description": [], + "signature": [ + "(payload: ", + { + "pluginId": "@kbn/security-plugin-types-public", + "scope": "public", + "docId": "kibKbnSecurityPluginTypesPublicPluginApi", + "section": "def-public.RolePutPayload", + "text": "RolePutPayload" + }, + ") => Promise" + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/security-plugin-types-public", + "id": "def-public.RolesAPIClient.saveRole.$1", + "type": "Object", + "tags": [], + "label": "payload", + "description": [], + "signature": [ + { + "pluginId": "@kbn/security-plugin-types-public", + "scope": "public", + "docId": "kibKbnSecurityPluginTypesPublicPluginApi", + "section": "def-public.RolePutPayload", + "text": "RolePutPayload" + } + ], + "path": "x-pack/packages/security/plugin_types_public/src/roles/roles_api_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/security-plugin-types-public", "id": "def-public.SecurityNavControlServiceStart", diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index 76bfaf45d129c..35642e22e727d 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 39 | 0 | 14 | 0 | +| 51 | 0 | 25 | 0 | ## Client diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index 9137974b89ddb..35cdc321d4dbd 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index afae0e1eda8c2..9b974e6cfbc7e 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-features'] --- import kbnSecuritySolutionFeaturesObj from './kbn_security_solution_features.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index b5fb278a0bf9f..83f2ca2124e77 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index db32a3f767b39..2d7b13a243859 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: 2024-06-05 +date: 2024-06-06 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 885c1be6a569c..021b65a8e408c 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: 2024-06-05 +date: 2024-06-06 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 93a8035154584..f0cc2e44363d6 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: 2024-06-05 +date: 2024-06-06 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 108912e6e961a..bea87f3ff838b 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: 2024-06-05 +date: 2024-06-06 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 fc3005bbbcbf7..fe7b74dcdb4b6 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: 2024-06-05 +date: 2024-06-06 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 0ec2575ddd3e6..497f29b3856c9 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.devdocs.json b/api_docs/kbn_securitysolution_exception_list_components.devdocs.json index 5382edc3d95e3..40dc8909e03ed 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.devdocs.json +++ b/api_docs/kbn_securitysolution_exception_list_components.devdocs.json @@ -851,7 +851,7 @@ "label": "formattedDateComponent", "description": [], "signature": [ - "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"view\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\"" + "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\" | \"view\"" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx", "deprecated": false, @@ -865,7 +865,7 @@ "label": "securityLinkAnchorComponent", "description": [], "signature": [ - "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"view\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\"" + "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\" | \"view\"" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx", "deprecated": false, @@ -1004,7 +1004,7 @@ "label": "securityLinkAnchorComponent", "description": [], "signature": [ - "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"view\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\"" + "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\" | \"view\"" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, @@ -1018,7 +1018,7 @@ "label": "formattedDateComponent", "description": [], "signature": [ - "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"view\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\"" + "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\" | \"view\"" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, @@ -1144,7 +1144,7 @@ "label": "showValueListModal", "description": [], "signature": [ - "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"view\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\"" + "\"symbol\" | \"object\" | \"source\" | \"meta\" | \"desc\" | \"filter\" | \"big\" | \"link\" | \"small\" | \"sub\" | \"sup\" | \"text\" | \"map\" | \"head\" | \"slot\" | \"style\" | \"title\" | \"data\" | \"pattern\" | \"summary\" | \"template\" | \"span\" | \"main\" | \"path\" | \"form\" | \"body\" | \"q\" | \"label\" | \"progress\" | \"article\" | \"image\" | \"menu\" | \"stop\" | \"base\" | React.ComponentType | \"s\" | \"legend\" | \"canvas\" | \"svg\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"select\" | \"output\" | \"script\" | \"time\" | \"mask\" | \"input\" | \"table\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"bdi\" | \"bdo\" | \"blockquote\" | \"br\" | \"button\" | \"caption\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset\" | \"figcaption\" | \"figure\" | \"footer\" | \"header\" | \"hgroup\" | \"hr\" | \"html\" | \"i\" | \"iframe\" | \"img\" | \"ins\" | \"kbd\" | \"keygen\" | \"li\" | \"mark\" | \"menuitem\" | \"meter\" | \"nav\" | \"noindex\" | \"noscript\" | \"ol\" | \"optgroup\" | \"option\" | \"param\" | \"picture\" | \"pre\" | \"rp\" | \"rt\" | \"ruby\" | \"samp\" | \"section\" | \"strong\" | \"tbody\" | \"td\" | \"textarea\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"track\" | \"u\" | \"ul\" | \"var\" | \"video\" | \"wbr\" | \"webview\" | \"animate\" | \"animateMotion\" | \"animateTransform\" | \"circle\" | \"clipPath\" | \"defs\" | \"ellipse\" | \"feBlend\" | \"feColorMatrix\" | \"feComponentTransfer\" | \"feComposite\" | \"feConvolveMatrix\" | \"feDiffuseLighting\" | \"feDisplacementMap\" | \"feDistantLight\" | \"feDropShadow\" | \"feFlood\" | \"feFuncA\" | \"feFuncB\" | \"feFuncG\" | \"feFuncR\" | \"feGaussianBlur\" | \"feImage\" | \"feMerge\" | \"feMergeNode\" | \"feMorphology\" | \"feOffset\" | \"fePointLight\" | \"feSpecularLighting\" | \"feSpotLight\" | \"feTile\" | \"feTurbulence\" | \"foreignObject\" | \"g\" | \"line\" | \"linearGradient\" | \"marker\" | \"metadata\" | \"mpath\" | \"polygon\" | \"polyline\" | \"radialGradient\" | \"rect\" | \"switch\" | \"textPath\" | \"tspan\" | \"use\" | \"view\"" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 90d1d58eec352..438c1ab42e167 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 9c9be7a01c75a..2bdd9e238697e 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: 2024-06-05 +date: 2024-06-06 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 06066689352d2..eadb0a4b6999f 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: 2024-06-05 +date: 2024-06-06 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 d9f5af2b265f4..9cacf4e44a94b 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: 2024-06-05 +date: 2024-06-06 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 54fb8ee085ccb..c01e4e3ed761a 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: 2024-06-05 +date: 2024-06-06 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 87e873eb9fb30..7fbee25df54b7 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: 2024-06-05 +date: 2024-06-06 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 f515c2f59d23f..f314edce6f547 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: 2024-06-05 +date: 2024-06-06 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 616b7ecc1a89e..484a8dfb271b0 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: 2024-06-05 +date: 2024-06-06 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 b3123547a5c67..bc72b4cb8ae56 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: 2024-06-05 +date: 2024-06-06 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 fc176e18e47fc..01a1d3ea34c7e 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: 2024-06-05 +date: 2024-06-06 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 caf6cc20bf20e..df6fb7f3b1388 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: 2024-06-05 +date: 2024-06-06 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 ec0c337f02828..49197c1256919 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: 2024-06-05 +date: 2024-06-06 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 f3ef3c91cb14b..6b144a6cc7537 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: 2024-06-05 +date: 2024-06-06 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 255b14e6a37ad..88f92b22d7f04 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: 2024-06-05 +date: 2024-06-06 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 7774cfbe1dfc4..69cceeb6fefc3 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: 2024-06-05 +date: 2024-06-06 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_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index cf5ebbec33250..d791360f0340a 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-common-settings'] --- import kbnServerlessCommonSettingsObj from './kbn_serverless_common_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_observability_settings.mdx b/api_docs/kbn_serverless_observability_settings.mdx index 25b3c44d1f964..a6f197fbd55bc 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-observability-settings'] --- import kbnServerlessObservabilitySettingsObj from './kbn_serverless_observability_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 1fc20de3227a6..cf912fb5c32a6 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: 2024-06-05 +date: 2024-06-06 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_search_settings.mdx b/api_docs/kbn_serverless_search_settings.mdx index 4077f22bb4f75..7ee6959d8caff 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-search-settings'] --- import kbnServerlessSearchSettingsObj from './kbn_serverless_search_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_security_settings.mdx b/api_docs/kbn_serverless_security_settings.mdx index 11a1bb7f34cc8..59e2be159758b 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-security-settings'] --- import kbnServerlessSecuritySettingsObj from './kbn_serverless_security_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 9cc22fe4b6830..7e662eba21e81 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: 2024-06-05 +date: 2024-06-06 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 bdcf770f40f55..1c0680d137e7c 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: 2024-06-05 +date: 2024-06-06 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 f733a79703eb7..cea4803901527 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: 2024-06-05 +date: 2024-06-06 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_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 69d197a0ed1bb..b3898d0a68e4a 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: 2024-06-05 +date: 2024-06-06 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_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 87a18a0190921..337568b6900fd 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: 2024-06-05 +date: 2024-06-06 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 df32d8386246e..1fddb4fe12a63 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: 2024-06-05 +date: 2024-06-06 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 7185b09f85b41..165c9775917fa 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: 2024-06-05 +date: 2024-06-06 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 6354f6d5c5f91..8ad79a93bfba6 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: 2024-06-05 +date: 2024-06-06 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_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index d52daa3c8ef49..9473c5eabd903 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index e8eb77be1bb74..e8daeb78308e8 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: 2024-06-05 +date: 2024-06-06 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 846862d1d8812..b33ed2a7a431c 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: 2024-06-05 +date: 2024-06-06 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 aa1cd2df917bb..3f8769f4e1809 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: 2024-06-05 +date: 2024-06-06 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 5d4eb4fae5157..aa12f94a83c34 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: 2024-06-05 +date: 2024-06-06 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 f8e8c1dfb6c38..b098e754cd50b 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: 2024-06-05 +date: 2024-06-06 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 57b5c53721a1c..0718f5c0daaa4 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: 2024-06-05 +date: 2024-06-06 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 10db7013af9b0..1cca08c3209f2 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: 2024-06-05 +date: 2024-06-06 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 a3896a6fa6a2f..d70a7750b212f 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: 2024-06-05 +date: 2024-06-06 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 69fab0852d591..36446e12db4b0 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: 2024-06-05 +date: 2024-06-06 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 f9bcda515c979..d0f279a5ab2c5 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: 2024-06-05 +date: 2024-06-06 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 d66947a0b9714..3de3519a64523 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: 2024-06-05 +date: 2024-06-06 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 caa80e083bb77..1e4662977bb89 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: 2024-06-05 +date: 2024-06-06 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 034d01ebca23c..73f07b4c0fda5 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: 2024-06-05 +date: 2024-06-06 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 3d5d599ee6ced..49b774fc68d88 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: 2024-06-05 +date: 2024-06-06 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 b6f9058f3b778..31abe36d41dd7 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: 2024-06-05 +date: 2024-06-06 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 ed2c97e8da4f9..e6bad30c78ef2 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: 2024-06-05 +date: 2024-06-06 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 58f8c54f328ba..b603563f67656 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: 2024-06-05 +date: 2024-06-06 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 2caab7a2a12d0..cd39e31111d4e 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: 2024-06-05 +date: 2024-06-06 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 c6d49e80e5461..e2aaf03b06464 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: 2024-06-05 +date: 2024-06-06 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 823944a57275b..2c971c4d4a9d6 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: 2024-06-05 +date: 2024-06-06 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 4f506ab58e258..f7a8b4af72bd3 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: 2024-06-05 +date: 2024-06-06 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 7d982fbf2bb8d..098ae86079d62 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: 2024-06-05 +date: 2024-06-06 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 104580929b8f7..664fb28e9653d 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: 2024-06-05 +date: 2024-06-06 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 383cc11bbd81d..b913313f1c415 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: 2024-06-05 +date: 2024-06-06 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 debc17d38d10d..9d9f227a724e7 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: 2024-06-05 +date: 2024-06-06 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 ee9ed111e3c57..6cbab09679e87 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: 2024-06-05 +date: 2024-06-06 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 469d9ff815d8d..540dd5b046040 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: 2024-06-05 +date: 2024-06-06 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 8e290a90cf07a..48bb6cee15eac 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: 2024-06-05 +date: 2024-06-06 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 1143741ced19b..26ff3abc42739 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: 2024-06-05 +date: 2024-06-06 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 4155596c2b2a3..9d9f9dbb65e82 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: 2024-06-05 +date: 2024-06-06 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_tabbed_modal.mdx b/api_docs/kbn_shared_ux_tabbed_modal.mdx index 776ac92a9b8ff..33e5d8f308a09 100644 --- a/api_docs/kbn_shared_ux_tabbed_modal.mdx +++ b/api_docs/kbn_shared_ux_tabbed_modal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-tabbed-modal title: "@kbn/shared-ux-tabbed-modal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-tabbed-modal plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-tabbed-modal'] --- import kbnSharedUxTabbedModalObj from './kbn_shared_ux_tabbed_modal.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index a414385d506b6..d237d95986b7d 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: 2024-06-05 +date: 2024-06-06 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 d57c34be2a147..e30a50ef8ff3f 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: 2024-06-05 +date: 2024-06-06 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 ad2322745e9c8..38f88f777ddeb 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_predicates.mdx b/api_docs/kbn_sort_predicates.mdx index 0f38e027bb897..223a14c3c57fc 100644 --- a/api_docs/kbn_sort_predicates.mdx +++ b/api_docs/kbn_sort_predicates.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-predicates title: "@kbn/sort-predicates" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-predicates plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 16d19e57dbb1a..5a6b2d62ec9fb 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: 2024-06-05 +date: 2024-06-06 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 3569af80b4b14..d4713a81c8f3e 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: 2024-06-05 +date: 2024-06-06 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 7bbb7daa277a0..81e260e524986 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: 2024-06-05 +date: 2024-06-06 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 dc3a9759b2e01..9a035566e85ef 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: 2024-06-05 +date: 2024-06-06 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 b3f503c6c36c8..6dc418ddd22dd 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_eui_helpers.mdx b/api_docs/kbn_test_eui_helpers.mdx index ce64181201138..a4e26e3403fe1 100644 --- a/api_docs/kbn_test_eui_helpers.mdx +++ b/api_docs/kbn_test_eui_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-eui-helpers title: "@kbn/test-eui-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-eui-helpers plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-eui-helpers'] --- import kbnTestEuiHelpersObj from './kbn_test_eui_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 6294212c6d421..56a953dee0195 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: 2024-06-05 +date: 2024-06-06 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 6ee33bab28064..45d9039876b66 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: 2024-06-05 +date: 2024-06-06 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 f70e18da66fca..c9223159101d5 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_timerange.mdx b/api_docs/kbn_timerange.mdx index c2c7c55244ff6..1eb1b7ed8bf32 100644 --- a/api_docs/kbn_timerange.mdx +++ b/api_docs/kbn_timerange.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-timerange title: "@kbn/timerange" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/timerange plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/timerange'] --- import kbnTimerangeObj from './kbn_timerange.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 7d4530dac42ae..4605f179941df 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index f526e33aa9316..a988274710ce7 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_try_in_console.mdx b/api_docs/kbn_try_in_console.mdx index db0387fdcd34b..1d22531325f6b 100644 --- a/api_docs/kbn_try_in_console.mdx +++ b/api_docs/kbn_try_in_console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-try-in-console title: "@kbn/try-in-console" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/try-in-console plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/try-in-console'] --- import kbnTryInConsoleObj from './kbn_try_in_console.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 47a903b0ef8bd..064d5ef942ab1 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: 2024-06-05 +date: 2024-06-06 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 3b19c857dfbd7..ed6bbc7782218 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: 2024-06-05 +date: 2024-06-06 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 d33c0f4be566d..2bbd9dfd047c8 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: 2024-06-05 +date: 2024-06-06 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 e68c484514205..ebf8c157c6747 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: 2024-06-05 +date: 2024-06-06 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 d3f9f5c958c3c..68a37421a1deb 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.devdocs.json b/api_docs/kbn_unified_data_table.devdocs.json index 951029c44915f..56275124e99d8 100644 --- a/api_docs/kbn_unified_data_table.devdocs.json +++ b/api_docs/kbn_unified_data_table.devdocs.json @@ -1453,7 +1453,13 @@ "\nCurrent sort setting" ], "signature": [ - "SortOrder", + { + "pluginId": "@kbn/unified-data-table", + "scope": "common", + "docId": "kibKbnUnifiedDataTablePluginApi", + "section": "def-common.SortOrder", + "text": "SortOrder" + }, "[]" ], "path": "packages/kbn-unified-data-table/src/components/data_table.tsx", @@ -1768,7 +1774,7 @@ "section": "def-common.IUiSettingsClient", "text": "IUiSettingsClient" }, - "; dataViewFieldEditor: ", + "; dataViewFieldEditor?: ", { "pluginId": "dataViewFieldEditor", "scope": "public", @@ -1776,7 +1782,7 @@ "section": "def-public.PluginStart", "text": "PluginStart" }, - "; toastNotifications: ", + " | undefined; toastNotifications: ", { "pluginId": "@kbn/core-notifications-browser", "scope": "common", @@ -2707,6 +2713,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-common.SortOrder", + "type": "Type", + "tags": [], + "label": "SortOrder", + "description": [], + "signature": [ + "[string, string]" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/unified-data-table", "id": "def-common.UnifiedDataTableRenderCustomToolbar", diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index 02def6fdbb576..693a9f4f79409 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.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 | |-------------------|-----------|------------------------|-----------------| -| 152 | 0 | 80 | 2 | +| 153 | 0 | 81 | 1 | ## Common diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 6262ca7f66f89..d29e1814be9b2 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 649b219f409a7..c1df059bc930e 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index 75d27212791d8..9abd22c489603 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index bfcb80d09fb71..13a839a283902 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index be9fc53c1affe..8897c95a656c0 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: 2024-06-05 +date: 2024-06-06 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 7cf4a636e2c78..86045edf15fb8 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: 2024-06-05 +date: 2024-06-06 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 3511c9091e8e6..009129821d28d 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: 2024-06-05 +date: 2024-06-06 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 7e61b2f257d6b..53d474b0c710f 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index dcd6b37837f12..7c09a3ddb7981 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index 3ee7b96ae9940..47263f57d6df6 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 49e7b8a7b2c00..cd8d4c10bec0f 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index c0ea25baf65c0..80dc603c0b1b1 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index 8c320f8c20ca8..e5e548d33795d 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index e293e63a6c3b6..c7f3c9e8dfd4d 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: 2024-06-05 +date: 2024-06-06 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 4991fdc62d5e9..61475a2115986 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: 2024-06-05 +date: 2024-06-06 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 492e6198051e6..b02aabeeb41ae 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: 2024-06-05 +date: 2024-06-06 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 7bee2d2cc03a8..044b18ddface8 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index be40ea5d7e2e7..2e502ecd39bad 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -11058,23 +11058,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index fea55f92c382a..0a0012271aa51 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: 2024-06-05 +date: 2024-06-06 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 f32cdd93d56f6..be0d88c87ca71 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: 2024-06-05 +date: 2024-06-06 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 4bfd5d971c5c9..00fabca4e4953 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: 2024-06-05 +date: 2024-06-06 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 22355597f3209..427cf57221434 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 00b908faf787c..98c4bf0b63540 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 7dc292a3ceec0..0857a1e3c0dcd 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_data_access.mdx b/api_docs/logs_data_access.mdx index 1949457c88114..93b1b05f17ca9 100644 --- a/api_docs/logs_data_access.mdx +++ b/api_docs/logs_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsDataAccess title: "logsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the logsDataAccess plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsDataAccess'] --- import logsDataAccessObj from './logs_data_access.devdocs.json'; diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index e9116222e2aa3..b4813aba4c435 100644 --- a/api_docs/logs_explorer.mdx +++ b/api_docs/logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsExplorer title: "logsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logsExplorer plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsExplorer'] --- import logsExplorerObj from './logs_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 3d1aed2478b5f..7e2dc9ca04cf1 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index b6810c1d8f168..13296a74dd9b9 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.devdocs.json b/api_docs/maps.devdocs.json index 5dea201e25961..7fa01d6407bf2 100644 --- a/api_docs/maps.devdocs.json +++ b/api_docs/maps.devdocs.json @@ -4366,23 +4366,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 53fdb915b53d6..4c791d464e912 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: 2024-06-05 +date: 2024-06-06 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 b2fcdc5f14cf7..05542e5dbdbf5 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index 3131d2446e044..7eb00acb9d3d1 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.devdocs.json b/api_docs/ml.devdocs.json index 1d2c5b4093da3..7bb947c63a348 100644 --- a/api_docs/ml.devdocs.json +++ b/api_docs/ml.devdocs.json @@ -1007,23 +1007,15 @@ "section": "def-common.PublishesTimeRange", "text": "PublishesTimeRange" }, - " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; filters$: ", + " & ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", "docId": "kibKbnPresentationPublishingPluginApi", - "section": "def-common.PublishingSubject", - "text": "PublishingSubject" - }, - "<", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.Filter", - "text": "Filter" + "section": "def-common.PublishesFilters", + "text": "PublishesFilters" }, - "[] | undefined>; query$: ", + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "common", diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 50c831ae03816..9c8f548f24c29 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index 3e96e8cfd14cd..bec9280bff73c 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 0472b0d4965fb..355f4ee51351f 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: 2024-06-05 +date: 2024-06-06 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 681a181a440b0..a710de9c852b9 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: 2024-06-05 +date: 2024-06-06 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 1dff1f3b065bf..e0512f0e731f7 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: 2024-06-05 +date: 2024-06-06 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 93f3061807fe7..924dc6bae7160 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index c7c7bfd43ddad..437cc2c455c36 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 662ed6fc18339..d15d55c62b5c0 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: 2024-06-05 +date: 2024-06-06 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 dc6778b98dc74..10055f2373a28 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index a43fe3ac9a1c7..f4afcf8be4f4b 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant_app.mdx b/api_docs/observability_a_i_assistant_app.mdx index 7ef35ead46e3e..cf608471c50ee 100644 --- a/api_docs/observability_a_i_assistant_app.mdx +++ b/api_docs/observability_a_i_assistant_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistantApp title: "observabilityAIAssistantApp" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistantApp plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistantApp'] --- import observabilityAIAssistantAppObj from './observability_a_i_assistant_app.devdocs.json'; diff --git a/api_docs/observability_ai_assistant_management.mdx b/api_docs/observability_ai_assistant_management.mdx index c88b6dab9b019..a8f39350c6025 100644 --- a/api_docs/observability_ai_assistant_management.mdx +++ b/api_docs/observability_ai_assistant_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAiAssistantManagement title: "observabilityAiAssistantManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAiAssistantManagement plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAiAssistantManagement'] --- import observabilityAiAssistantManagementObj from './observability_ai_assistant_management.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index 629f46660d6cb..5e540ea2d2830 100644 --- a/api_docs/observability_logs_explorer.mdx +++ b/api_docs/observability_logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogsExplorer title: "observabilityLogsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogsExplorer plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogsExplorer'] --- import observabilityLogsExplorerObj from './observability_logs_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 330f07cd79ae7..db1a0a2e36cf1 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: 2024-06-05 +date: 2024-06-06 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 0474530148e91..d01ce86c1eae4 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: 2024-06-05 +date: 2024-06-06 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 32142fa41bcdd..21f037b1cf508 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/painless_lab.mdx b/api_docs/painless_lab.mdx index eadc32d1e24ef..b9f13f481253d 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'painlessLab'] --- import painlessLabObj from './painless_lab.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 6063c56fb8a41..56091945c3ad1 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 799 | 685 | 42 | +| 801 | 687 | 42 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 48698 | 239 | 37188 | 1871 | +| 48784 | 239 | 37272 | 1877 | ## Plugin Directory @@ -51,7 +51,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | The cloud security posture plugin | 14 | 0 | 2 | 2 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 38 | 0 | 30 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Content management app | 149 | 0 | 125 | 6 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 340 | 0 | 332 | 20 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 351 | 0 | 343 | 18 | | crossClusterReplication | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 0 | 0 | 0 | 0 | | customBranding | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Enables customization of Kibana | 0 | 0 | 0 | 0 | | | [@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 | @@ -71,11 +71,12 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | A stateful layer to register shared features and provide an access point to discover without a direct dependency | 16 | 0 | 15 | 2 | | | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | Server APIs for the Elastic AI Assistant | 46 | 0 | 32 | 0 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 556 | 1 | 446 | 8 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 557 | 1 | 447 | 9 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Extends embeddable plugin with more functionality | 19 | 0 | 19 | 2 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 53 | 0 | 46 | 1 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | Adds dashboards for discovering and managing Enterprise Search products. | 5 | 0 | 5 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 99 | 3 | 97 | 3 | +| | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 2 | 0 | 2 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 201 | 0 | 201 | 6 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The listing page for event annotations. | 15 | 0 | 15 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 112 | 0 | 112 | 11 | @@ -96,10 +97,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Adds expression runtime to Kibana | 2233 | 17 | 1763 | 6 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 235 | 0 | 99 | 2 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Index pattern fields and ambiguous values formatters | 292 | 5 | 253 | 3 | +| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | Exposes services for async usage and search of fields metadata. | 39 | 0 | 39 | 7 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 84 | 0 | 84 | 8 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 240 | 0 | 24 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Simple UI for managing files in Kibana | 2 | 0 | 2 | 0 | -| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1329 | 5 | 1208 | 69 | +| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1335 | 5 | 1214 | 71 | | ftrApis | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 72 | 0 | 14 | 5 | | globalSearchBar | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 0 | 0 | 0 | 0 | @@ -173,7 +175,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | Plugin to provide access to and rendering of python notebooks for use in the persistent developer console. | 6 | 0 | 6 | 0 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 18 | 0 | 10 | 1 | | searchprofiler | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 0 | 0 | 0 | 0 | -| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 413 | 0 | 205 | 3 | +| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 414 | 0 | 205 | 3 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 191 | 0 | 121 | 37 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Serverless customizations for security. | 7 | 0 | 7 | 0 | @@ -486,7 +488,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 35 | 0 | 34 | 0 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | - | 165 | 0 | 138 | 9 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | - | 295 | 0 | 276 | 0 | -| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 19 | 0 | 19 | 0 | +| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 20 | 0 | 20 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 52 | 0 | 37 | 7 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 32 | 0 | 19 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 7 | 0 | 3 | 0 | @@ -522,7 +524,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 7 | 1 | 7 | 1 | | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 9 | 0 | 9 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 52 | 12 | 43 | 0 | -| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 59 | 0 | 59 | 4 | +| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 60 | 0 | 60 | 4 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 44 | 0 | 44 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 13 | 0 | 13 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 86 | 0 | 78 | 6 | @@ -591,8 +593,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 1 | 0 | 0 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 1 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 1 | 0 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 76 | 0 | 65 | 1 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 204 | 0 | 169 | 5 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 82 | 0 | 71 | 0 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 209 | 0 | 174 | 5 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 168 | 0 | 55 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 13 | 0 | 7 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 22 | 0 | 9 | 0 | @@ -633,7 +635,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 50 | 0 | 25 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 7 | 0 | 7 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 88 | 0 | 40 | 0 | -| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 39 | 0 | 14 | 0 | +| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 51 | 0 | 25 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 207 | 0 | 114 | 0 | | | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | - | 14 | 0 | 14 | 6 | | | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | - | 54 | 0 | 49 | 0 | @@ -725,7 +727,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 42 | 0 | 28 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 56 | 0 | 47 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 9 | 0 | 8 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the unified data table which can be integrated into apps | 152 | 0 | 80 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the unified data table which can be integrated into apps | 153 | 0 | 81 | 1 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 18 | 0 | 17 | 5 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list and field stats which can be integrated into apps | 313 | 0 | 284 | 8 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 13 | 0 | 9 | 0 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index e99b5a6cf8533..db707a4ec3471 100644 --- a/api_docs/presentation_panel.mdx +++ b/api_docs/presentation_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationPanel title: "presentationPanel" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationPanel plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationPanel'] --- import presentationPanelObj from './presentation_panel.devdocs.json'; diff --git a/api_docs/presentation_util.devdocs.json b/api_docs/presentation_util.devdocs.json index 2d91a73058e8a..dce3971f03c21 100644 --- a/api_docs/presentation_util.devdocs.json +++ b/api_docs/presentation_util.devdocs.json @@ -666,7 +666,7 @@ "label": "FloatingActions", "description": [], "signature": [ - "({ children, viewMode, isEnabled, embeddable, className, disabledActions, }: React.PropsWithChildren<", + "({ children, viewMode, isEnabled, api, className, disabledActions, }: React.PropsWithChildren<", "FloatingActionsProps", ">) => JSX.Element" ], @@ -679,7 +679,7 @@ "id": "def-public.FloatingActions.$1", "type": "CompoundType", "tags": [], - "label": "{\n children,\n viewMode,\n isEnabled,\n embeddable,\n className = '',\n disabledActions,\n}", + "label": "{\n children,\n viewMode,\n isEnabled,\n api,\n className = '',\n disabledActions,\n}", "description": [], "signature": [ "React.PropsWithChildren<", diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index c590b2e2a1a8f..d013bb58ab26e 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: 2024-06-05 +date: 2024-06-06 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 91e23a57ca5d5..826f6e45a1d74 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/profiling_data_access.mdx b/api_docs/profiling_data_access.mdx index 421289b4436be..204b381b1383b 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profilingDataAccess'] --- import profilingDataAccessObj from './profiling_data_access.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 2caf7df103dd1..1ee800df85f26 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: 2024-06-05 +date: 2024-06-06 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 a021a59609769..c38f92541b09a 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 4991ece3f6140..0569c2c01e3e2 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: 2024-06-05 +date: 2024-06-06 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 1b17933d6d349..f969ce1574c60 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: 2024-06-05 +date: 2024-06-06 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 61f6a51553861..74a8d8a7a1ba8 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: 2024-06-05 +date: 2024-06-06 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 098577b3aea4c..1791c0beae57b 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: 2024-06-05 +date: 2024-06-06 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 814fa0fe40572..076ff3f35e2dc 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: 2024-06-05 +date: 2024-06-06 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 ed76398f81e51..e8a1026f13f94 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: 2024-06-05 +date: 2024-06-06 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 c867b80c5ee03..ccbce95fbc9d4 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: 2024-06-05 +date: 2024-06-06 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 1741a9c76ef81..84188cc926cad 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: 2024-06-05 +date: 2024-06-06 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 3c34d8b864a77..0e257da552da6 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: 2024-06-05 +date: 2024-06-06 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 6b8ed2f1ed387..26eed5b8b3fcd 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: 2024-06-05 +date: 2024-06-06 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 f8eeb86b80c7e..cc151e111de88 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/search_connectors.mdx b/api_docs/search_connectors.mdx index bb28a8a9deb1f..2a986d7a569ac 100644 --- a/api_docs/search_connectors.mdx +++ b/api_docs/search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchConnectors title: "searchConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the searchConnectors plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchConnectors'] --- import searchConnectorsObj from './search_connectors.devdocs.json'; diff --git a/api_docs/search_notebooks.mdx b/api_docs/search_notebooks.mdx index c6faebf09cb5c..df57e01953c6d 100644 --- a/api_docs/search_notebooks.mdx +++ b/api_docs/search_notebooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchNotebooks title: "searchNotebooks" image: https://source.unsplash.com/400x175/?github description: API docs for the searchNotebooks plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchNotebooks'] --- import searchNotebooksObj from './search_notebooks.devdocs.json'; diff --git a/api_docs/search_playground.mdx b/api_docs/search_playground.mdx index c115a95736e13..7193bb57cce73 100644 --- a/api_docs/search_playground.mdx +++ b/api_docs/search_playground.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchPlayground title: "searchPlayground" image: https://source.unsplash.com/400x175/?github description: API docs for the searchPlayground plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchPlayground'] --- import searchPlaygroundObj from './search_playground.devdocs.json'; diff --git a/api_docs/security.devdocs.json b/api_docs/security.devdocs.json index 86960e5d096f8..de0e3c09debb7 100644 --- a/api_docs/security.devdocs.json +++ b/api_docs/security.devdocs.json @@ -231,6 +231,28 @@ "trackAdoption": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "security", + "id": "def-public.AuthorizationServiceSetup.roles", + "type": "Object", + "tags": [], + "label": "roles", + "description": [ + "\nA set of methods to work with Kibana user roles." + ], + "signature": [ + { + "pluginId": "@kbn/security-plugin-types-public", + "scope": "public", + "docId": "kibKbnSecurityPluginTypesPublicPluginApi", + "section": "def-public.RolesAPIClient", + "text": "RolesAPIClient" + } + ], + "path": "x-pack/packages/security/plugin_types_public/src/authorization/authorization_service.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 9ddb43e306d93..2911962fdc47d 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 413 | 0 | 205 | 3 | +| 414 | 0 | 205 | 3 | ## Client diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 97639944c4515..fab3dc4fe730f 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 259354a48343b..a38a8cdc20c2f 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index 470ba9d520dc8..23cf506af5a54 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 9493f6ff6eab2..e7efab4689612 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: 2024-06-05 +date: 2024-06-06 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 580aaf78fdfbd..923ac382e645a 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: 2024-06-05 +date: 2024-06-06 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 6f7d93d0a85cf..e68810fcd7113 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 32d004842f302..2516bf08dc03e 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: 2024-06-05 +date: 2024-06-06 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 9ef7b2b5f2be2..b9095535c3df7 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/slo.mdx b/api_docs/slo.mdx index fa326f9e3fe77..ca6a87beb8b74 100644 --- a/api_docs/slo.mdx +++ b/api_docs/slo.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/slo title: "slo" image: https://source.unsplash.com/400x175/?github description: API docs for the slo plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'slo'] --- import sloObj from './slo.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index f0b8f83b4e5fd..66b3b093277c2 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: 2024-06-05 +date: 2024-06-06 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 8692e1a2ce5c1..1f2a374948e46 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: 2024-06-05 +date: 2024-06-06 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 4d001f66c67e0..5d00650229d2e 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: 2024-06-05 +date: 2024-06-06 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 6afe061d59814..75871df63616f 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: 2024-06-05 +date: 2024-06-06 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 6f81c55078132..b71c872b63228 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: 2024-06-05 +date: 2024-06-06 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 3e52100abf669..22a07f83ae2b9 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: 2024-06-05 +date: 2024-06-06 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 32a736453b595..b80602206f17b 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: 2024-06-05 +date: 2024-06-06 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 6dd304982263f..04a7eb993f57a 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: 2024-06-05 +date: 2024-06-06 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 29501507ccf1e..eb553c6cb8473 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: 2024-06-05 +date: 2024-06-06 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 f4a5c553f1d96..9cc1ef21f829b 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: 2024-06-05 +date: 2024-06-06 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 a9a1d696e7db6..a7faf873a2626 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: 2024-06-05 +date: 2024-06-06 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 fadd402e39b22..facd2c78b184a 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: 2024-06-05 +date: 2024-06-06 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 c2d4e0630be28..47df9fe1655e1 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: 2024-06-05 +date: 2024-06-06 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 63fd71211ef36..4992388476b3a 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: 2024-06-05 +date: 2024-06-06 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 d7f47a4c5f758..cbe4bd15cc1ad 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: 2024-06-05 +date: 2024-06-06 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 85b26a0d12782..1c47d7d114bd9 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_doc_viewer.mdx b/api_docs/unified_doc_viewer.mdx index 1bac1f4aa3d0e..bdfcc152f2d0a 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 9cfa9da3d0b96..b4e7b989c91f4 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: 2024-06-05 +date: 2024-06-06 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 9d91eb5d792b7..5fddd517e309f 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: 2024-06-05 +date: 2024-06-06 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 7a5fef5e9cda4..d5ead98c51877 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index bbca679582ce2..c76eef63d9490 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 7b550c54a118c..4b30bd73f2032 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: 2024-06-05 +date: 2024-06-06 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 d1dff752504b5..4ec70c04ca0a6 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: 2024-06-05 +date: 2024-06-06 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 b665527257e47..411a483ea78d9 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: 2024-06-05 +date: 2024-06-06 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 b96cc6f0908d4..1f525a5f6e9ab 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: 2024-06-05 +date: 2024-06-06 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 3bb1016e612fe..cfb9a3a94056f 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: 2024-06-05 +date: 2024-06-06 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 6ccb0cf1166df..ada490d897b58 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: 2024-06-05 +date: 2024-06-06 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 0038c2988eee9..4233b06e61626 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: 2024-06-05 +date: 2024-06-06 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 8ba2473615f86..91402ff70afad 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: 2024-06-05 +date: 2024-06-06 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 deae079852c3b..9aa66ffcc42ab 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: 2024-06-05 +date: 2024-06-06 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 fc9be06a2d820..9951a7a6d1aa9 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: 2024-06-05 +date: 2024-06-06 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 6905810c1c5d0..f06c4a914da4c 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: 2024-06-05 +date: 2024-06-06 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 1a2d9a75c4cdf..47b5154e27935 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: 2024-06-05 +date: 2024-06-06 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 7a21b41f684fa..e12e613c44b4f 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index d72780746a17b..d8ed2b189500f 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: 2024-06-05 +date: 2024-06-06 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 51eb7944a6e34034dcba82f5b4a35388e36634bc Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Thu, 6 Jun 2024 08:08:24 +0200 Subject: [PATCH 026/122] [Data grid] Allow consumer to set initial columns (#184880) Allow the consumer of `ESQLDataGrid` to set the initial columns to be displayed. --- src/plugins/esql_datagrid/public/create_datagrid.tsx | 1 + src/plugins/esql_datagrid/public/data_grid.tsx | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/esql_datagrid/public/create_datagrid.tsx b/src/plugins/esql_datagrid/public/create_datagrid.tsx index 04e5693c96c38..6e218fac2bde4 100644 --- a/src/plugins/esql_datagrid/public/create_datagrid.tsx +++ b/src/plugins/esql_datagrid/public/create_datagrid.tsx @@ -24,6 +24,7 @@ interface ESQLDataGridProps { query: AggregateQuery; flyoutType?: 'overlay' | 'push'; isTableView?: boolean; + initialColumns?: DatatableColumn[]; } const DataGridLazy = withSuspense(lazy(() => import('./data_grid'))); diff --git a/src/plugins/esql_datagrid/public/data_grid.tsx b/src/plugins/esql_datagrid/public/data_grid.tsx index 00d1ef2f541b6..c9e507295b9f3 100644 --- a/src/plugins/esql_datagrid/public/data_grid.tsx +++ b/src/plugins/esql_datagrid/public/data_grid.tsx @@ -30,6 +30,7 @@ interface ESQLDataGridProps { query: AggregateQuery; flyoutType?: 'overlay' | 'push'; isTableView?: boolean; + initialColumns?: DatatableColumn[]; } type DataTableColumnsMeta = Record< string, @@ -44,7 +45,7 @@ const sortOrder: SortOrder[] = []; const DataGrid: React.FC = (props) => { const [expandedDoc, setExpandedDoc] = useState(undefined); const [activeColumns, setActiveColumns] = useState( - props.isTableView ? props.columns.map((c) => c.name) : [] + (props.initialColumns || (props.isTableView ? props.columns : [])).map((c) => c.name) ); const [rowHeight, setRowHeight] = useState(5); From 072b29d3de3b6f1cb5ebc8172163879c8bc22996 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Thu, 6 Jun 2024 09:34:36 +0200 Subject: [PATCH 027/122] [Alert details page][Custom threshold] Add warning threshold info (#184571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #183628 ## Summary This PR adds warning threshold to the Threshold component in the alert details page. It also fixes the issue with range threshold. |Warning info|Storybook| |---|---| |![image](https://github.com/elastic/kibana/assets/12370520/c48a6fa8-4df6-4f1e-bf7b-9f9d0b2b85be)|![image](https://github.com/elastic/kibana/assets/12370520/8084e27e-424a-48db-9eef-256190c96b89)| ### 🧪 How to test - Enable `xpack.observability.unsafe.alertDetails.metrics.enabled: true` feature flag. - Generate data with the following command ``` node x-pack/scripts/data_forge.js \ --events-per-cycle 7 \ --lookback now-20m \ --install-kibana-assets \ --dataset fake_hosts ``` - Adjust the Inventory setting and add `kbn-data-forge*` to the Metric indices - Create a metric threshold rule with both alert and warning thresholds set - Go to the alert details page and verify the warning info as stated above #### Storybook You can also check the [Threshold component storybook](https://ci-artifacts.kibana.dev/storybooks/pr-184571/787578147f949823baa7bc3b421be5ba0f948088/infra/index.html?path=/story/infra-alerting-threshold--default). --- .../common/components/threshold.stories.tsx | 6 ++- .../common/components/threshold.test.tsx | 44 +++++++++++++++++-- .../alerting/common/components/threshold.tsx | 30 ++++++++++--- .../alert_details_app_section/index.tsx | 4 +- .../components/alert_details_app_section.tsx | 12 ++++- 5 files changed, 82 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.stories.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.stories.tsx index 0b253a981b122..195a868ff0af2 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.stories.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.stories.tsx @@ -32,10 +32,14 @@ const defaultProps: Props = { chartProps: { baseTheme: LIGHT_THEME }, comparator: COMPARATORS.GREATER_THAN, id: 'componentId', - threshold: 90, + thresholds: [90], title: 'Threshold breached', value: 93, valueFormatter: (d) => `${d}%`, + warning: { + thresholds: [75], + comparator: COMPARATORS.GREATER_THAN, + }, }; export const Default = { diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.test.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.test.tsx index 3decd9cfdd9c0..32d70920c5a73 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.test.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.test.tsx @@ -5,11 +5,19 @@ * 2.0. */ -import { LIGHT_THEME } from '@elastic/charts'; import { COMPARATORS } from '@kbn/alerting-comparators'; +import { Metric, LIGHT_THEME } from '@elastic/charts'; import { render } from '@testing-library/react'; -import { Props, Threshold } from './threshold'; import React from 'react'; +import { Props, Threshold } from './threshold'; + +jest.mock('@elastic/charts', () => { + const actual = jest.requireActual('@elastic/charts'); + return { + ...actual, + Metric: jest.fn(() => 'mocked Metric'), + }; +}); describe('Threshold', () => { const renderComponent = (props: Partial = {}) => { @@ -17,7 +25,7 @@ describe('Threshold', () => { chartProps: { baseTheme: LIGHT_THEME }, comparator: COMPARATORS.GREATER_THAN, id: 'componentId', - threshold: 90, + thresholds: [90], title: 'Threshold breached', value: 93, valueFormatter: (d) => `${d}%`, @@ -35,8 +43,38 @@ describe('Threshold', () => { ); }; + beforeEach(() => { + jest.clearAllMocks(); + }); + it('shows component', () => { const component = renderComponent(); expect(component.queryByTestId('threshold-90-93')).toBeTruthy(); }); + + it('shows warning message', () => { + renderComponent({ + thresholds: [7], + comparator: COMPARATORS.GREATER_THAN_OR_EQUALS, + warning: { + thresholds: [3, 7], + comparator: COMPARATORS.BETWEEN, + }, + }); + + expect((Metric as jest.Mock).mock.calls[0][0].data[0][0]).toMatchInlineSnapshot(` + Object { + "color": "#f8e9e9", + "extra": + Alert when >= 7% +
+ Warn when between 3% - 7% +
, + "icon": [Function], + "title": "Threshold breached", + "value": 93, + "valueFormatter": [Function], + } + `); + }); }); diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.tsx index bb710a165733b..0b587bf067f47 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/common/components/threshold.tsx @@ -11,6 +11,7 @@ import { EuiIcon, EuiPanel, useEuiBackgroundColor } from '@elastic/eui'; import type { PartialTheme, Theme } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; import { COMPARATORS } from '@kbn/alerting-comparators'; + export interface ChartProps { theme?: PartialTheme; baseTheme: Theme; @@ -20,20 +21,25 @@ export interface Props { chartProps: ChartProps; comparator: COMPARATORS | string; id: string; - threshold: number; + thresholds: number[]; title: string; value: number; valueFormatter: (d: number) => string; + warning?: { + thresholds: number[]; + comparator: COMPARATORS; + }; } export const Threshold = ({ chartProps: { theme, baseTheme }, comparator, id, - threshold, + thresholds, title, value, valueFormatter, + warning, }: Props) => { const color = useEuiBackgroundColor('danger'); @@ -47,7 +53,7 @@ export const Threshold = ({ minWidth: '100%', }} hasShadow={false} - data-test-subj={`threshold-${threshold}-${value}`} + data-test-subj={`threshold-${thresholds.join('-')}-${value}`} > @@ -58,12 +64,24 @@ export const Threshold = ({ { title, extra: ( - + <> {i18n.translate('xpack.infra.alerting.thresholdExtraTitle', { - values: { comparator, threshold: valueFormatter(threshold) }, + values: { + comparator, + threshold: thresholds.map((t) => valueFormatter(t)).join(' - '), + }, defaultMessage: `Alert when {comparator} {threshold}`, })} - +
+ {warning && + i18n.translate('xpack.infra.alerting.warningExtraTitle', { + values: { + comparator: warning.comparator, + threshold: warning.thresholds.map((t) => valueFormatter(t)).join(' - '), + }, + defaultMessage: `Warn when {comparator} {threshold}`, + })} + ), color, value, diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx index a3a4895d4e9a3..ae0021adb2e01 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx @@ -128,7 +128,7 @@ const AlertDetailsAppSection = ({ chartProps={{ theme, baseTheme: LEGACY_LIGHT_THEME }} comparator={ComparatorToi18nSymbolsMap[rule.params.count.comparator]} id={'threshold-ratio-chart'} - threshold={rule.params.count.value} + thresholds={[rule.params.count.value]} value={Number(alert.fields[ALERT_EVALUATION_VALUE]?.toFixed(2))} valueFormatter={formatThreshold} /> @@ -195,7 +195,7 @@ const AlertDetailsAppSection = ({ chartProps={{ theme, baseTheme: LEGACY_LIGHT_THEME }} comparator={ComparatorToi18nSymbolsMap[rule.params.count.comparator]} id="logCountThreshold" - threshold={rule.params.count.value} + thresholds={[rule.params.count.value]} value={Number(alert.fields[ALERT_EVALUATION_VALUE])} valueFormatter={formatThreshold} /> diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/alert_details_app_section.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/alert_details_app_section.tsx index e0607341aa150..6a9e4999714bc 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/alert_details_app_section.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/metric_threshold/components/alert_details_app_section.tsx @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { convertToBuiltInComparators } from '@kbn/observability-plugin/common'; import React, { useEffect } from 'react'; import moment from 'moment'; import { @@ -160,7 +161,7 @@ export function AlertDetailsAppSection({ metricValueFormatter(d, 'metric' in criterion ? criterion.metric : undefined) @@ -171,7 +172,14 @@ export function AlertDetailsAppSection({ defaultMessage: 'Threshold breached', } )} - comparator={criterion.comparator} + comparator={convertToBuiltInComparators(criterion.comparator)} + warning={ + criterion.warningThreshold && + criterion.warningComparator && { + thresholds: criterion.warningThreshold, + comparator: convertToBuiltInComparators(criterion.warningComparator), + } + } /> From 584362ed32d7ba1377405c2078b8a7dd7d3a0453 Mon Sep 17 00:00:00 2001 From: Cristina Amico Date: Thu, 6 Jun 2024 09:44:04 +0200 Subject: [PATCH 028/122] [Fleet] Remove beta badges from proxies sections and add warning (#184811) Closes https://github.com/elastic/ingest-dev/issues/3232 ## Summary - Remove beta badges from settings proxies sections - Add a callout message in all previous sections to warn user about proxies usage - Add link to [docs](https://www.elastic.co/guide/en/fleet/master/fleet-agent-proxy-support.html) in proxies table
Screenshots ### Proxies table ![Screenshot 2024-06-05 at 14 30 50](https://github.com/elastic/kibana/assets/16084106/2f85974a-626d-4dbb-9757-e40555f9dd71) ### Add proxy flyout ![Screenshot 2024-06-05 at 12 32 35](https://github.com/elastic/kibana/assets/16084106/54d085e5-a761-4171-be8a-a8a763f1a02a) ### Edit fleet server flyout ![Screenshot 2024-06-05 at 12 28 01](https://github.com/elastic/kibana/assets/16084106/e9dc075f-4fba-4f2e-b0cb-1576560967a7) ### Add agent binary source flyout ![Screenshot 2024-06-05 at 12 26 30](https://github.com/elastic/kibana/assets/16084106/a452a7a7-c154-4d88-9215-56a1b4950d63) ### Add new output flyout ![Screenshot 2024-06-05 at 12 24 23](https://github.com/elastic/kibana/assets/16084106/6f083394-d0a5-447c-ac1a-b26ac57a9075)
### Checklist - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-doc-links/src/get_doc_links.ts | 1 + packages/kbn-doc-links/src/types.ts | 1 + .../download_source_flyout/index.tsx | 20 ++---- .../edit_fleet_proxy_flyout/index.tsx | 7 +- .../components/edit_output_flyout/index.tsx | 65 +++++++++---------- .../fleet_proxies_table/proxy_warning.tsx | 24 +++++++ .../fleet_server_hosts_flyout/index.tsx | 62 ++++++++---------- .../settings_page/fleet_proxies_section.tsx | 20 ++++-- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 11 files changed, 104 insertions(+), 99 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_proxies_table/proxy_warning.tsx diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index a599f9a2bf0b6..34895385bef9b 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -859,6 +859,7 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D performancePresets: `${FLEET_DOCS}es-output-settings.html#es-output-settings-performance-tuning-settings`, scalingKubernetesResourcesAndLimits: `${FLEET_DOCS}scaling-on-kubernetes.html#_specifying_resources_and_limits_in_agent_manifests`, roleAndPrivileges: `${FLEET_DOCS}fleet-roles-and-privileges.html`, + proxiesSettings: `${FLEET_DOCS}fleet-agent-proxy-support.html`, }, ecs: { guide: `${ELASTIC_WEBSITE_URL}guide/en/ecs/${ECS_VERSION}/index.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index 567652df3123c..554e26ccd7685 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -552,6 +552,7 @@ export interface DocLinks { performancePresets: string; scalingKubernetesResourcesAndLimits: string; roleAndPrivileges: string; + proxiesSettings: string; }>; readonly ecs: { readonly guide: string; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx index 292bb63e3c54c..b6c2ef272d813 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx @@ -24,13 +24,13 @@ import { EuiLink, EuiSwitch, EuiSpacer, - EuiBetaBadge, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { DownloadSource, FleetProxy } from '../../../../types'; import { FLYOUT_MAX_WIDTH } from '../../constants'; import { useBreadcrumbs, useStartServices } from '../../../../hooks'; +import { ProxyWarning } from '../fleet_proxies_table/proxy_warning'; import { useDowloadSourceFlyoutForm } from './use_download_source_flyout_form'; @@ -142,21 +142,7 @@ export const EditDownloadSourceFlyout: React.FunctionComponent - ), - }} + defaultMessage="Proxy" /> } helpText={ @@ -188,6 +174,8 @@ export const EditDownloadSourceFlyout: React.FunctionComponent + + = onClose, fleetProxy, }) => { - // const { docLinks } = useStartServices(); - const form = useFleetProxyForm(fleetProxy, onClose); const { inputs } = form; @@ -61,6 +62,8 @@ export const FleetProxyFlyout: React.FunctionComponent = + + = label={ - ), - }} + defaultMessage="Proxy" /> } > - inputs.proxyIdInput.setValue(options?.[0]?.value ?? '')} - selectedOptions={ - inputs.proxyIdInput.value !== '' - ? proxiesOptions.filter((option) => option.value === inputs.proxyIdInput.value) - : [] - } - options={proxiesOptions} - singleSelection={{ asPlainText: true }} - isDisabled={inputs.proxyIdInput.props.disabled} - isClearable={true} - placeholder={i18n.translate( - 'xpack.fleet.settings.editOutputFlyout.proxyIdPlaceholder', - { - defaultMessage: 'Select proxy', + <> + inputs.proxyIdInput.setValue(options?.[0]?.value ?? '')} + selectedOptions={ + inputs.proxyIdInput.value !== '' + ? proxiesOptions.filter( + (option) => option.value === inputs.proxyIdInput.value + ) + : [] } - )} - /> + options={proxiesOptions} + singleSelection={{ asPlainText: true }} + isDisabled={inputs.proxyIdInput.props.disabled} + isClearable={true} + placeholder={i18n.translate( + 'xpack.fleet.settings.editOutputFlyout.proxyIdPlaceholder', + { + defaultMessage: 'Select proxy', + } + )} + /> + + + )} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_proxies_table/proxy_warning.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_proxies_table/proxy_warning.tsx new file mode 100644 index 0000000000000..7fdf1ab325728 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_proxies_table/proxy_warning.tsx @@ -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 React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiCallOut } from '@elastic/eui'; + +export const ProxyWarning: React.FunctionComponent<{}> = () => ( + + } + /> +); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/index.tsx index 0dcf808fbb4d7..bb018b9366483 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/index.tsx @@ -26,7 +26,6 @@ import { EuiSwitch, EuiComboBox, EuiCallOut, - EuiBetaBadge, } from '@elastic/eui'; import { MultiRowInput } from '../multi_row_input'; @@ -34,6 +33,7 @@ import { useStartServices } from '../../../../hooks'; import { FLYOUT_MAX_WIDTH } from '../../constants'; import type { FleetServerHost, FleetProxy } from '../../../../types'; import { TextInput } from '../form'; +import { ProxyWarning } from '../fleet_proxies_table/proxy_warning'; import { useFleetServerHostsForm } from './use_fleet_server_host_form'; @@ -188,45 +188,35 @@ export const FleetServerHostsFlyout: React.FunctionComponent - ), - }} + defaultMessage="Proxy" /> } > - inputs.proxyIdInput.setValue(options?.[0]?.value ?? '')} - selectedOptions={ - inputs.proxyIdInput.value !== '' - ? proxiesOptions.filter((option) => option.value === inputs.proxyIdInput.value) - : [] - } - options={proxiesOptions} - singleSelection={{ asPlainText: true }} - isDisabled={inputs.proxyIdInput.props.disabled} - isClearable={true} - placeholder={i18n.translate( - 'xpack.fleet.settings.fleetServerHostsFlyout.proxyIdPlaceholder', - { - defaultMessage: 'Select proxy', + <> + inputs.proxyIdInput.setValue(options?.[0]?.value ?? '')} + selectedOptions={ + inputs.proxyIdInput.value !== '' + ? proxiesOptions.filter((option) => option.value === inputs.proxyIdInput.value) + : [] } - )} - /> + options={proxiesOptions} + singleSelection={{ asPlainText: true }} + isDisabled={inputs.proxyIdInput.props.disabled} + isClearable={true} + placeholder={i18n.translate( + 'xpack.fleet.settings.fleetServerHostsFlyout.proxyIdPlaceholder', + { + defaultMessage: 'Select proxy', + } + )} + /> + + + { const authz = useAuthz(); const { getHref } = useLink(); + const { docLinks } = useStartServices(); return ( <> @@ -46,14 +47,21 @@ export const FleetProxiesSection: React.FunctionComponent
- - - + + + ), + }} /> diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 17442f5c3ab82..71c86aac906ce 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -18696,7 +18696,6 @@ "xpack.fleet.settings.editDownloadSourcesFlyout.hostsInputPlaceholder": "Indiquer l’hôte", "xpack.fleet.settings.editDownloadSourcesFlyout.nameInputLabel": "Nom", "xpack.fleet.settings.editDownloadSourcesFlyout.nameInputPlaceholder": "Indiquer le nom", - "xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdBetaBadge": "Bêta", "xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdPlaceholder": "Sélectionner un proxy", "xpack.fleet.settings.editDownloadSourcesFlyout.proxyInputDescription": "Proxy utilisé pour accéder à la source de téléchargement. Actuellement, seule l’URL du proxy est utilisée, les en-têtes et les certificats ne sont pas compatibles.", "xpack.fleet.settings.editDownloadSourcesFlyout.saveButton": "Enregistrer et appliquer les paramètres", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 0223842043653..75a83002c3a40 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -18675,7 +18675,6 @@ "xpack.fleet.settings.editDownloadSourcesFlyout.hostsInputPlaceholder": "ホストを指定", "xpack.fleet.settings.editDownloadSourcesFlyout.nameInputLabel": "名前", "xpack.fleet.settings.editDownloadSourcesFlyout.nameInputPlaceholder": "名前を指定", - "xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdBetaBadge": "ベータ", "xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdPlaceholder": "プロキシを選択", "xpack.fleet.settings.editDownloadSourcesFlyout.proxyInputDescription": "ダウンロードソースへのアクセスに使用されるプロキシ。現在はプロキシURLのみが使用され、ヘッダーや証明書はサポートされていません。", "xpack.fleet.settings.editDownloadSourcesFlyout.saveButton": "設定を保存して適用", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index a448ac3bf66e7..56d67e46ade68 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -18704,7 +18704,6 @@ "xpack.fleet.settings.editDownloadSourcesFlyout.hostsInputPlaceholder": "指定主机", "xpack.fleet.settings.editDownloadSourcesFlyout.nameInputLabel": "名称", "xpack.fleet.settings.editDownloadSourcesFlyout.nameInputPlaceholder": "指定名称", - "xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdBetaBadge": "公测版", "xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdPlaceholder": "选择代理", "xpack.fleet.settings.editDownloadSourcesFlyout.proxyInputDescription": "用于访问下载源的代理。当前仅使用代理 URL,不支持标题和证书。", "xpack.fleet.settings.editDownloadSourcesFlyout.saveButton": "保存并应用设置", From 678ffa0bfe50419720075e45ce315eea3da33d2a Mon Sep 17 00:00:00 2001 From: Jedr Blaszyk Date: Thu, 6 Jun 2024 10:43:37 +0200 Subject: [PATCH 029/122] [Connectors] Use Connector API to create a connector (#183398) ## Summary Use [Connector API endpoint](https://www.elastic.co/guide/en/elasticsearch/reference/master/create-connector-api.html) in the create connectors action. Note: https://github.com/elastic/elasticsearch/pull/109248 was merged into ES very recently, you might need to pull latest ES image to get this working. Note: some crawler features also utilise connector index, since it was agreed not to support those features in the Connector API I'm leaving crawler related logic unchanged ### Validation - Add unit tests - Test locally with stack - Test locally with serverless --- .../lib/create_connector.test.ts | 198 ++++++++++++++++++ .../lib/create_connector.ts | 51 +++-- .../utils/connector_status_helpers.ts | 14 +- .../server/routes/connectors_routes.ts | 1 - 4 files changed, 245 insertions(+), 19 deletions(-) create mode 100644 packages/kbn-search-connectors/lib/create_connector.test.ts diff --git a/packages/kbn-search-connectors/lib/create_connector.test.ts b/packages/kbn-search-connectors/lib/create_connector.test.ts new file mode 100644 index 0000000000000..66d8ce226c1a8 --- /dev/null +++ b/packages/kbn-search-connectors/lib/create_connector.test.ts @@ -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 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 { errors } from '@elastic/elasticsearch'; + +import { ElasticsearchClient } from '@kbn/core/server'; +import { FeatureName } from '../types'; + +import { createConnector } from './create_connector'; + +const notFoundError = new errors.ResponseError({ + statusCode: 404, + body: { + error: { + type: `document_missing_exception`, + }, + }, +} as any); + +describe('createConnector lib', () => { + const mockClient = { + transport: { + request: jest.fn(), + }, + }; + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should create connector with _connector API endpoint', async () => { + const connectorId = 'connectorId'; + const mockConnector = { + id: connectorId, + index_name: 'indexName', + language: 'en', + is_native: true, + }; + mockClient.transport.request + .mockResolvedValueOnce({ id: connectorId }) + .mockResolvedValueOnce(mockConnector); + + await expect( + createConnector(mockClient as unknown as ElasticsearchClient, { + isNative: true, + indexName: mockConnector.index_name, + language: mockConnector.language, + }) + ).resolves.toEqual(mockConnector); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'POST', + path: `/_connector`, + body: { + index_name: 'indexName', + language: 'en', + is_native: true, + name: '', + }, + }); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'GET', + path: `/_connector/${connectorId}`, + }); + }); + + it('should update pipeline params if provided', async () => { + const connectorId = 'connectorId'; + const mockConnector = { + id: connectorId, + index_name: 'indexName', + language: 'en', + is_native: true, + }; + + const mockPipeline = { + extract_binary_content: true, + name: 'test', + reduce_whitespace: true, + run_ml_inference: true, + }; + + mockClient.transport.request + .mockResolvedValueOnce({ id: connectorId }) + .mockResolvedValueOnce({ result: 'updated' }) + .mockResolvedValueOnce(mockConnector); + + await expect( + createConnector(mockClient as unknown as ElasticsearchClient, { + isNative: true, + indexName: 'indexName', + language: 'en', + pipeline: mockPipeline, + }) + ).resolves.toEqual(mockConnector); + + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'POST', + path: `/_connector`, + body: { + index_name: 'indexName', + language: 'en', + is_native: true, + name: '', + }, + }); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'PUT', + path: `/_connector/${connectorId}/_pipeline`, + body: { pipeline: mockPipeline }, + }); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'GET', + path: `/_connector/${connectorId}`, + }); + }); + + it('should update connector features if provided', async () => { + const connectorId = 'connectorId'; + const mockConnector = { + id: connectorId, + index_name: 'indexName', + language: 'en', + is_native: true, + }; + + const mockFeatures = { + [FeatureName.FILTERING_ADVANCED_CONFIG]: true, + [FeatureName.FILTERING_RULES]: true, + [FeatureName.SYNC_RULES]: { + advanced: { enabled: true }, + basic: { enabled: true }, + }, + }; + + mockClient.transport.request + .mockResolvedValueOnce({ id: connectorId }) + .mockResolvedValueOnce({ result: 'updated' }) + .mockResolvedValueOnce(mockConnector); + + await expect( + createConnector(mockClient as unknown as ElasticsearchClient, { + isNative: true, + indexName: 'indexName', + language: 'en', + features: mockFeatures, + }) + ).resolves.toEqual(mockConnector); + + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'POST', + path: `/_connector`, + body: { + index_name: 'indexName', + language: 'en', + is_native: true, + name: '', + }, + }); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'PUT', + path: `/_connector/${connectorId}/_features`, + body: { features: mockFeatures }, + }); + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'GET', + path: `/_connector/${connectorId}`, + }); + }); + + it('should throw an error if connector doc is not found', async () => { + mockClient.transport.request + .mockResolvedValueOnce({ id: 'connectorId' }) + .mockRejectedValueOnce(notFoundError); + + await expect( + createConnector(mockClient as unknown as ElasticsearchClient, { + isNative: true, + indexName: 'some-index', + language: 'somelang', + }) + ).rejects.toEqual(new Error('Could not retrieve the created connector')); + + expect(mockClient.transport.request).toHaveBeenCalledWith({ + method: 'POST', + path: `/_connector`, + body: { + index_name: 'some-index', + is_native: true, + language: 'somelang', + name: '', + }, + }); + }); +}); diff --git a/packages/kbn-search-connectors/lib/create_connector.ts b/packages/kbn-search-connectors/lib/create_connector.ts index 524fc3c195eac..666011e50f341 100644 --- a/packages/kbn-search-connectors/lib/create_connector.ts +++ b/packages/kbn-search-connectors/lib/create_connector.ts @@ -7,10 +7,10 @@ */ import { ElasticsearchClient } from '@kbn/core/server'; -import { CURRENT_CONNECTORS_INDEX } from '..'; +import { i18n } from '@kbn/i18n'; +import { fetchConnectorById } from '..'; import { Connector, ConnectorConfiguration, IngestPipelineParams } from '../types/connectors'; -import { createConnectorDocument } from './create_connector_document'; export const createConnector = async ( client: ElasticsearchClient, @@ -23,19 +23,46 @@ export const createConnector = async ( name?: string; pipeline?: IngestPipelineParams; serviceType?: string | null; - instant_response?: boolean; } ): Promise => { - const document = createConnectorDocument({ - ...input, - serviceType: input.serviceType || null, + const { id: connectorId } = await client.transport.request<{ id: string }>({ + method: 'POST', + path: `/_connector`, + body: { + ...(input.indexName && { index_name: input.indexName }), + is_native: input.isNative, + ...(input.language && { language: input.language }), + name: input.name || '', + ...(input.serviceType && { service_type: input.serviceType }), + }, }); - const result = await client.index({ - document, - index: CURRENT_CONNECTORS_INDEX, - refresh: input.instant_response ? false : 'wait_for', - }); + if (input.pipeline) { + await client.transport.request({ + method: 'PUT', + path: `/_connector/${connectorId}/_pipeline`, + body: { pipeline: input.pipeline }, + }); + } + + if (input.features) { + await client.transport.request({ + method: 'PUT', + path: `/_connector/${connectorId}/_features`, + body: { features: input.features }, + }); + } + + // createConnector function expects to return a Connector doc, so we fetch it from the index + const connector = await fetchConnectorById(client, connectorId); + + if (!connector) { + throw new Error( + i18n.translate('searchConnectors.server.connectors.not_found_error', { + defaultMessage: 'Could not retrieve the created connector', + }) + ); + } - return { ...document, id: result._id }; + return connector; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts index 52d59ae81ccef..c9e2bb0dd2b45 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts @@ -44,9 +44,10 @@ export function connectorStatusToText(connector: Connector): string { ); } if ( - connector.error === SyncStatus.ERROR || - connector.last_sync_error !== null || - connector.last_access_control_sync_error !== null + connector.last_sync_status === SyncStatus.ERROR || + connector.last_access_control_sync_status === SyncStatus.ERROR || + connector.last_sync_error != null || + connector.last_access_control_sync_error != null ) { return i18n.translate( 'xpack.enterpriseSearch.content.searchIndices.connectorStatus.syncFailure.label', @@ -87,9 +88,10 @@ export function connectorStatusToColor(connector: Connector): 'warning' | 'dange if ( isLastSeenOld(connector) || connectorStatus === ConnectorStatus.ERROR || - connector.error === SyncStatus.ERROR || - connector.last_sync_error !== null || - connector.last_access_control_sync_error !== null + connector.last_sync_status === SyncStatus.ERROR || + connector.last_access_control_sync_status === SyncStatus.ERROR || + connector.last_sync_error != null || + connector.last_access_control_sync_error != null ) { return 'danger'; } diff --git a/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts b/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts index af54d4ccb6d56..36d9a48bedffb 100644 --- a/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts +++ b/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts @@ -73,7 +73,6 @@ export const registerConnectorsRoutes = ({ http, router }: RouteDependencies) => const { client } = (await context.core).elasticsearch; const connector = await createConnector(client.asCurrentUser, { indexName: null, - instant_response: true, isNative: false, language: null, }); From 2a56861b49814c0a9c02163a83dd588d7cb9d973 Mon Sep 17 00:00:00 2001 From: elena-shostak <165678770+elena-shostak@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:41:32 +0200 Subject: [PATCH 030/122] [Roles] ComboBox overflow fix (#184722) ## Summary Fixed `ComboBox` overflow with large chips. Applies to the following fields: - Indices. - Remote indices. - Remote clusters. Screenshot 2024-06-04 at 11 43 39 https://github.com/elastic/kibana/assets/165678770/f6bbc325-a957-4c3e-bc88-721b77dc8ff0 Options considered: 1. **Flex with specific grow attribute set**. This will not stop the `ComboBox` from growing after it reaches 50% point of available space. ``` ... ... ``` 2. **Grid with columns.** ``` ... ... ``` CSS is the following. ``` grid-template-columns: repeat(2, 1fr); ``` The problem is that `1fr` is about the distribution of available space, as soon as content of `ComboBox` becomes bigger it breaks. 3. **Combobox props.** We have `fullWidth` attribute set that we need for stretching to available column space, so the content doesn't wrap unless there is the `maxWidth` set for column. Alternative is to remove `fullWidth` which wraps chips correctly, but then doesn't satisfy the design. 4. **`maxWidth` for `EuiFlexItem`.** ``` ... ... ``` That option works, but since we have the same form for index privileges and remote index privileges, we would need to justify it for 2 columns (maxWidth: '50%' ), 3 columns (maxWidth: '33%' ) and mobile accordingly (maxWidth: '100%' ). Can be less scalable. 4. Leverage grid `minmax`. ``` grid-template-columns: repeat(N, minmax(0, 1fr)); ``` It allows to create columns as large as `1fr` and not exceed it, so `ComboBox` will nicely fit. ### 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 - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) __Fixes: https://github.com/elastic/kibana/issues/183311__ ### Release note Fixed `ComboBox` overflow with large chips. --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../index_privilege_form.test.tsx.snap | 22 +++++++++++++++++-- ...mote_cluster_privileges_form.test.tsx.snap | 19 ++++++++++++++-- .../privileges/es/index_privilege_form.tsx | 17 ++++++++++++-- .../es/remote_cluster_privileges_form.tsx | 14 ++++++++++-- 4 files changed, 64 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap index 7080b6a70be9b..5107e8abf2e0b 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/index_privilege_form.test.tsx.snap @@ -14,7 +14,25 @@ exports[`it renders without crashing 1`] = ` - + - + - + - + { private getPrivilegeForm = () => { return ( <> - + {this.props.indexType === 'remote_indices' ? ( { /> - + {this.getFieldLevelControls()} {this.getGrantedDocumentsControl()} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/remote_cluster_privileges_form.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/remote_cluster_privileges_form.tsx index 5e55ebaf1d281..7f406df106f72 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/remote_cluster_privileges_form.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/remote_cluster_privileges_form.tsx @@ -9,17 +9,20 @@ import type { EuiComboBoxOptionOption } from '@elastic/eui'; import { EuiButtonIcon, EuiComboBox, + EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiPanel, EuiSpacer, } from '@elastic/eui'; +import { css } from '@emotion/react'; import React, { Fragment, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import type { Cluster } from '@kbn/remote-clusters-plugin/public'; +import { euiThemeVars } from '@kbn/ui-theme'; import { RemoteClusterComboBox } from './remote_clusters_combo_box'; import type { RoleRemoteClusterPrivilege } from '../../../../../../common'; @@ -92,7 +95,14 @@ export const RemoteClusterPrivilegesForm: React.FunctionComponent = ({ > - + = ({ /> - + {!isRoleReadOnly && ( From dd999bbd29fbc3d1d7bef7fc70c3e9246780dba6 Mon Sep 17 00:00:00 2001 From: Luke G <11671118+lgestc@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:55:11 +0200 Subject: [PATCH 031/122] [Security Solution] Toggle new sourcerer implementation with local storage switch (#184822) ## Summary Add `localStorage` based mechanism to toggle between the future experiemental sourcerer implementation and the stable one in **runtime**. Also moved the hook for pulling in the data from the sourcerer to appropriately named file. --- .../public/sourcerer/containers/index.tsx | 9 ++++++- .../sourcerer/experimental/is_enabled.ts | 16 +++++++++++++ .../public/sourcerer/experimental/readme.md | 18 ++++++++++++++ ...se_unstable_security_solution_data_view.ts | 24 +++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/security_solution/public/sourcerer/experimental/is_enabled.ts create mode 100644 x-pack/plugins/security_solution/public/sourcerer/experimental/readme.md create mode 100644 x-pack/plugins/security_solution/public/sourcerer/experimental/use_unstable_security_solution_data_view.ts diff --git a/x-pack/plugins/security_solution/public/sourcerer/containers/index.tsx b/x-pack/plugins/security_solution/public/sourcerer/containers/index.tsx index a9cf833696a57..a8dc888541f33 100644 --- a/x-pack/plugins/security_solution/public/sourcerer/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/sourcerer/containers/index.tsx @@ -15,6 +15,7 @@ import { getDataViewStateFromIndexFields } from '../../common/containers/source/ import { useFetchIndex } from '../../common/containers/source'; import type { State } from '../../common/store/types'; import { sortWithExcludesAtEnd } from '../../../common/utils/sourcerer'; +import { useUnstableSecuritySolutionDataView } from '../experimental/use_unstable_security_solution_data_view'; export const useSourcererDataView = ( scopeId: SourcererScopeName = SourcererScopeName.default @@ -114,7 +115,7 @@ export const useSourcererDataView = ( return dataViewBrowserFields; }, [sourcererDataView.fields, sourcererDataView.patternList]); - return useMemo( + const stableSourcererValues = useMemo( () => ({ browserFields: browserFields(), dataViewId: sourcererDataView.id, @@ -143,4 +144,10 @@ export const useSourcererDataView = ( legacyPatterns.length, ] ); + + return useUnstableSecuritySolutionDataView( + scopeId, + // NOTE: data view derived from current implementation is used as a fallback + stableSourcererValues + ); }; diff --git a/x-pack/plugins/security_solution/public/sourcerer/experimental/is_enabled.ts b/x-pack/plugins/security_solution/public/sourcerer/experimental/is_enabled.ts new file mode 100644 index 0000000000000..efdc2c7468847 --- /dev/null +++ b/x-pack/plugins/security_solution/public/sourcerer/experimental/is_enabled.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/** + * Allows toggling between sourcerer implementations in runtime. Simply set the value in local storage + * to: + * - display the experimental component instead of the stable one + * - use experimental data views hook instead of the stable one + */ +export const IS_EXPERIMENTAL_SOURCERER_ENABLED = !!window.localStorage.getItem( + 'EXPERIMENTAL_SOURCERER_ENABLED' +); diff --git a/x-pack/plugins/security_solution/public/sourcerer/experimental/readme.md b/x-pack/plugins/security_solution/public/sourcerer/experimental/readme.md new file mode 100644 index 0000000000000..077bef147cbed --- /dev/null +++ b/x-pack/plugins/security_solution/public/sourcerer/experimental/readme.md @@ -0,0 +1,18 @@ +# Experimental Sourcerer Replacement + +## Introduction + +This directory is a home for Discovery Components based re-implementation of the Sourcerer. + +Currently, it can be enabled and used only by setting the localStorage value, like this: + +``` +window.localStorage.setItem('EXPERIMENTAL_SOURCERER_ENABLED', true) +``` + +The reason for having this feature toggle like this is we want to be able to inspect both implementations side by side, +using the same Kibana instance deployed locally (for now). + +## Architecture + +TODO diff --git a/x-pack/plugins/security_solution/public/sourcerer/experimental/use_unstable_security_solution_data_view.ts b/x-pack/plugins/security_solution/public/sourcerer/experimental/use_unstable_security_solution_data_view.ts new file mode 100644 index 0000000000000..a841834a8b1fe --- /dev/null +++ b/x-pack/plugins/security_solution/public/sourcerer/experimental/use_unstable_security_solution_data_view.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 SourcererScopeName, type SelectedDataView } from '../store/model'; + +import { IS_EXPERIMENTAL_SOURCERER_ENABLED } from './is_enabled'; + +/** + * FOR INTERNAL USE ONLY + * This hook provides data for experimental Sourcerer replacement in Security Solution. + * Do not use in client code as the API will change frequently. + * It will be extended in the future, covering more and more functionality from the current sourcerer. + */ +export const useUnstableSecuritySolutionDataView = ( + _scopeId: SourcererScopeName, + fallbackDataView: SelectedDataView +): SelectedDataView => { + // TODO: extend the fallback state with values computed using new logic + return IS_EXPERIMENTAL_SOURCERER_ENABLED ? fallbackDataView : fallbackDataView; +}; From 28a01c142404f9524bd8e1676f848bf75af594a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Thu, 6 Jun 2024 11:05:12 +0100 Subject: [PATCH 032/122] [Project sidenav] Refactor NavigationSectionUI component (#184745) --- .../project_navigation_service.test.ts | 28 -- .../project_navigation_service.ts | 78 +-- .../core/chrome/core-chrome-browser/index.ts | 1 + .../chrome/core-chrome-browser/src/index.ts | 1 + .../ui/components/navigation_section_ui.tsx | 473 ++++++------------ .../chrome/navigation/src/ui/constants.ts | 13 + .../chrome/navigation/src/ui/hooks/index.ts | 9 + .../src/ui/hooks/use_accordion_state.ts | 181 +++++++ .../chrome/navigation/src/ui/types.ts | 53 +- .../shared-ux/chrome/navigation/src/utils.ts | 6 + .../test_suites/observability/navigation.ts | 1 - .../test_suites/search/navigation.ts | 1 - 12 files changed, 383 insertions(+), 462 deletions(-) create mode 100644 packages/shared-ux/chrome/navigation/src/ui/constants.ts create mode 100644 packages/shared-ux/chrome/navigation/src/ui/hooks/index.ts create mode 100644 packages/shared-ux/chrome/navigation/src/ui/hooks/use_accordion_state.ts diff --git a/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.test.ts b/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.test.ts index b9cca3027f2fc..e8dd64aab41b0 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.test.ts +++ b/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.test.ts @@ -1002,32 +1002,4 @@ describe('solution navigations', () => { expect(activeSolution).toEqual(solution1); } }); - - it('should change the active solution if no node match the current Location', async () => { - const { projectNavigation, navLinksService, application } = setup({ - locationPathName: '/app/app3', // we are on app3 which only exists in solution3 - navLinkIds: ['app1', 'app2', 'app3'], - }); - - navLinksService.get.mockReturnValue({ url: '/app/app3', href: '/app/app3' } as any); - - const getActiveDefinition = () => - firstValueFrom(projectNavigation.getActiveSolutionNavDefinition$()); - - projectNavigation.updateSolutionNavigations({ solution1, solution2, solution3 }); - - { - const definition = await getActiveDefinition(); - expect(definition).toBe(null); // No active solution id yet - } - - // Change to solution 2, but we are still on '/app/app3' which only exists in solution3 - projectNavigation.changeActiveSolutionNavigation('solution2'); - - { - const definition = await getActiveDefinition(); - expect(definition?.id).toBe('solution3'); // The solution3 was activated as it matches the "/app/app3" location - expect(application.navigateToUrl).toHaveBeenCalled(); // Redirect - } - }); }); diff --git a/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts b/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts index 892ae29ed6862..0a1292be9b3f1 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts +++ b/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts @@ -32,7 +32,6 @@ import { of, type Observable, type Subscription, - take, } from 'rxjs'; import { type Location, createLocation } from 'history'; import deepEqual from 'react-fast-compare'; @@ -224,22 +223,9 @@ export class ProjectNavigationService { this.navigationTree$.next(navigationTree); this.navigationTreeUi$.next(navigationTreeUI); this.projectNavigationNavTreeFlattened = flattenNav(navigationTree); + this.updateActiveProjectNavigationNodes(); - // Verify if the current location is part of the navigation tree of - // the initiated solution. If not, we need to find the correct solution - const activeNodes = this.updateActiveProjectNavigationNodes(); - let willChangeSolution = false; - - if (activeNodes.length === 0) { - const solutionForCurrentLocation = this.findSolutionForCurrentLocation(); - if (solutionForCurrentLocation) { - willChangeSolution = true; - this.goToSolutionHome(solutionForCurrentLocation); - this.changeActiveSolutionNavigation(solutionForCurrentLocation); - } - } - - if (!initialised && !willChangeSolution) { + if (!initialised) { this.activeSolutionNavDefinitionId$.next(id); initialised = true; } @@ -318,48 +304,6 @@ export class ProjectNavigationService { }); } - /** - * When we are in stateful Kibana with multiple solution navigations, it is possible that a user - * lands on a page that does not belong to the current active solution navigation. In this case, - * we need to find the correct solution navigation based on the current location and switch to it. - */ - private findSolutionForCurrentLocation(): string | null { - if (Object.keys(this.solutionNavDefinitions$.getValue()).length === 0) return null; - - let idFound: string | null = null; - - combineLatest([this.solutionNavDefinitions$, this.location$]) - .pipe(take(1)) - .subscribe(([definitions, location]) => { - Object.entries(definitions).forEach(([id, definition]) => { - if (idFound) return; - - combineLatest([definition.navigationTree$, this.deepLinksMap$, this.cloudLinks$]) - .pipe( - take(1), - map(([def, deepLinksMap, cloudLinks]) => - parseNavigationTree(def, { - deepLinks: deepLinksMap, - cloudLinks, - }) - ) - ) - .subscribe(({ navigationTree }) => { - const maybeActiveNodes = this.findActiveNodes({ - location, - flattendTree: flattenNav(navigationTree), - }); - - if (maybeActiveNodes.length > 0) { - idFound = id; - } - }); - }); - }); - - return idFound; - } - private setSideNavComponent(component: SideNavComponent | null) { this.customProjectSideNavComponent$.next({ current: component }); } @@ -400,24 +344,6 @@ export class ProjectNavigationService { this.projectHome$.next(homeHref); } - private goToSolutionHome(id: string) { - const definitions = this.solutionNavDefinitions$.getValue(); - const definition = definitions[id]; - if (!definition) { - throw new Error(`No solution navigation definition found for id ${id}`); - } - - // Navigate to the new home page if it's defined - const link = this.navLinksService?.get(definition.homePage ?? 'undefined'); - if (!link) { - throw new Error(`No home page defined for solution navigation ${definition.id}`); - } - - const location = createLocation(link.url); - this.location$.next(location); - this.application?.navigateToUrl(link.url); - } - private changeActiveSolutionNavigation(id: string | null) { if (this.nextSolutionNavDefinitionId$.getValue() === id) return; this.nextSolutionNavDefinitionId$.next(id); diff --git a/packages/core/chrome/core-chrome-browser/index.ts b/packages/core/chrome/core-chrome-browser/index.ts index 27c20f502bc06..32b889ea7979d 100644 --- a/packages/core/chrome/core-chrome-browser/index.ts +++ b/packages/core/chrome/core-chrome-browser/index.ts @@ -57,4 +57,5 @@ export type { SolutionNavigationDefinition, SolutionNavigationDefinitions, EuiSideNavItemTypeEnhanced, + RenderAs, } from './src'; diff --git a/packages/core/chrome/core-chrome-browser/src/index.ts b/packages/core/chrome/core-chrome-browser/src/index.ts index a287499cd73ff..d3ac70d6520b8 100644 --- a/packages/core/chrome/core-chrome-browser/src/index.ts +++ b/packages/core/chrome/core-chrome-browser/src/index.ts @@ -56,4 +56,5 @@ export type { SolutionNavigationDefinition, SolutionNavigationDefinitions, EuiSideNavItemTypeEnhanced, + RenderAs, } from './project_navigation'; diff --git a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx index 37297e3f25c0e..3d549cf663703 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx +++ b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx @@ -6,14 +6,12 @@ * Side Public License, v 1. */ -import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import classNames from 'classnames'; +import React, { type FC, useMemo, useEffect, useState, useCallback } from 'react'; import { css } from '@emotion/css'; import { EuiTitle, EuiCollapsibleNavItem, EuiSpacer, - type EuiAccordionProps, type EuiCollapsibleNavItemProps, type EuiCollapsibleNavSubItemProps, } from '@elastic/eui'; @@ -22,36 +20,31 @@ import classnames from 'classnames'; import type { EuiThemeSize, RenderAs } from '@kbn/core-chrome-browser/src/project_navigation'; import { useNavigation as useServices } from '../../services'; -import { isAbsoluteLink, isActiveFromUrl } from '../../utils'; +import { isAbsoluteLink, isActiveFromUrl, isAccordionNode } from '../../utils'; import type { NavigateToUrlFn } from '../../types'; import { useNavigation } from '../navigation'; +import { useAccordionState } from '../hooks'; +import { + DEFAULT_IS_COLLAPSIBLE, + DEFAULT_RENDER_AS, + DEFAULT_SPACE_BETWEEN_LEVEL_1_GROUPS, +} from '../constants'; +import type { EuiCollapsibleNavSubItemPropsEnhanced } from '../types'; import { PanelContext, usePanel } from './panel'; import { NavigationItemOpenPanel } from './navigation_item_open_panel'; -type EuiCollapsibleNavSubItemPropsEnhanced = EuiCollapsibleNavSubItemProps & { path?: string }; - -const DEFAULT_SPACE_BETWEEN_LEVEL_1_GROUPS: EuiThemeSize = 'm'; -const DEFAULT_IS_COLLAPSED = true; -const DEFAULT_IS_COLLAPSIBLE = true; -const DEFAULT_RENDER_AS: RenderAs = 'block'; - const nodeHasLink = (navNode: ChromeProjectNavigationNode) => Boolean(navNode.deepLink) || Boolean(navNode.href); const nodeHasChildren = (navNode: ChromeProjectNavigationNode) => Boolean(navNode.children?.length); -/** - * Predicate to determine if a node should be visible in the main side nav. - * If it is not visible it will be filtered out and not rendered. - */ +/** Predicate to determine if a node should be visible in the main side nav.*/ const itemIsVisible = (item: ChromeProjectNavigationNode) => { if (item.sideNavStatus === 'hidden') return false; if (item.renderItem) return true; - if (nodeHasLink(item)) { - return true; - } + if (nodeHasLink(item)) return true; if (nodeHasChildren(item)) { return item.renderAs === 'item' ? true : item.children!.some(itemIsVisible); @@ -75,17 +68,10 @@ const getTestSubj = (navNode: ChromeProjectNavigationNode, isActive = false): st }); }; -const filterChildren = ( - children?: ChromeProjectNavigationNode[] -): ChromeProjectNavigationNode[] | undefined => { - if (!children) return undefined; - return children.filter(itemIsVisible); -}; - const serializeNavNode = (navNode: ChromeProjectNavigationNode) => { const serialized: ChromeProjectNavigationNode = { ...navNode, - children: filterChildren(navNode.children), + children: navNode.children?.filter(itemIsVisible), }; serialized.renderAs = getRenderAs(serialized); @@ -94,7 +80,7 @@ const serializeNavNode = (navNode: ChromeProjectNavigationNode) => { navNode: serialized, hasChildren: nodeHasChildren(serialized), hasLink: nodeHasLink(serialized), - isItem: serialized.renderAs === 'item' || serialized.children === undefined, + isItem: serialized.renderAs === 'item', }; }; @@ -156,58 +142,69 @@ const renderGroup = ( return [itemPrepend, ...groupItems]; }; -const isAccordionNode = ( - node: Pick -) => - node.renderAs === 'accordion' || - ['defaultIsCollapsed', 'isCollapsible'].some((prop) => node.hasOwnProperty(prop)); - -// Generate the EuiCollapsible props for both the root component (EuiCollapsibleNavItem) and its -// "items" props. Both are compatible with the exception of "renderItem" which is only used for -// sub items. -const nodeToEuiCollapsibleNavProps = ( - _navNode: ChromeProjectNavigationNode, +const renderPanelOpener = ( + navGroup: ChromeProjectNavigationNode, { + spaceBefore, navigateToUrl, - openPanel, - closePanel, - isSideNavCollapsed, - treeDepth, - itemsAccordionState, activeNodes, }: { + spaceBefore?: EuiThemeSize | null; + navigateToUrl: NavigateToUrlFn; + activeNodes: ChromeProjectNavigationNode[][]; + } +): Required['items'] => { + const items: EuiCollapsibleNavSubItemPropsEnhanced[] = [ + { + renderItem: () => ( + + ), + }, + ]; + + if (spaceBefore) { + items.unshift({ + renderItem: () => , + }); + } + + return items; +}; + +const getEuiProps = ( + _navNode: ChromeProjectNavigationNode, + deps: { navigateToUrl: NavigateToUrlFn; - openPanel: PanelContext['open']; closePanel: PanelContext['close']; - isSideNavCollapsed: boolean; treeDepth: number; - itemsAccordionState: AccordionItemsState; + getIsCollapsed: (path: string) => boolean; activeNodes: ChromeProjectNavigationNode[][]; } ): { - items: Array; - isVisible: boolean; -} => { + navNode: ChromeProjectNavigationNode; + subItems: EuiCollapsibleNavItemProps['items']; + isSelected: boolean; + isItem: boolean; + dataTestSubj: string; + spaceBefore?: EuiThemeSize | null; +} & Pick => { + const { navigateToUrl, closePanel, treeDepth, getIsCollapsed, activeNodes } = deps; const { navNode, isItem, hasChildren, hasLink } = serializeNavNode(_navNode); - const { - id, - path, - href, - renderAs, - onClick: customOnClick, - isCollapsible = DEFAULT_IS_COLLAPSIBLE, - } = navNode; - const isAccordion = isAccordionNode(navNode); + const { path, href, onClick: customOnClick, isCollapsible = DEFAULT_IS_COLLAPSIBLE } = navNode; + const isAccordion = isAccordionNode(navNode); // If the node is an accordion and it is not collapsible, we only want to mark it as active // if it is the highest match in the URL, not if one of its children is also active. const onlyIfHighestMatch = isAccordion && !isCollapsible; const isActive = isActiveFromUrl(navNode.path, activeNodes, onlyIfHighestMatch); const isExternal = Boolean(href) && !navNode.isElasticInternalLink && isAbsoluteLink(href!); - const isAccordionExpanded = - (itemsAccordionState[path]?.isCollapsed ?? DEFAULT_IS_COLLAPSED) === false; - let isSelected = isActive; + const isAccordionExpanded = !getIsCollapsed(path); + let isSelected = isActive; if (isAccordion && isAccordionExpanded) { // For accordions that are collapsible, we don't want to mark the parent button as selected // when it is expanded. If the accordion is **not** collapsible then we do. @@ -223,56 +220,12 @@ const nodeToEuiCollapsibleNavProps = ( spaceBefore = DEFAULT_SPACE_BETWEEN_LEVEL_1_GROUPS; } - if (renderAs === 'panelOpener') { - const items: EuiCollapsibleNavSubItemPropsEnhanced[] = [ - { - renderItem: () => ( - - ), - }, - ]; - if (spaceBefore) { - items.unshift({ - renderItem: () => , - }); - } - return { items, isVisible: true }; - } - - const onClick = (e: React.MouseEvent) => { - if (customOnClick) { - customOnClick(e); - return; - } - - // Do not navigate if it is a collapsible accordion, link will be used in the breadcrumb - if (isAccordion && isCollapsible) return; - - if (href !== undefined) { - e.preventDefault(); - navigateToUrl(href); - closePanel(); - return; - } - }; - const subItems: EuiCollapsibleNavItemProps['items'] | undefined = isItem ? undefined : navNode.children ?.map((child) => - nodeToEuiCollapsibleNavProps(child, { - navigateToUrl, - openPanel, - closePanel, - isSideNavCollapsed, - treeDepth: treeDepth + 1, - itemsAccordionState, - activeNodes, - }) + // Recursively convert the children to EuiCollapsibleNavSubItemProps + nodeToEuiCollapsibleNavProps(child, { ...deps, treeDepth: treeDepth + 1 }) ) .filter(({ isVisible }) => isVisible) .map((res) => { @@ -299,25 +252,81 @@ const nodeToEuiCollapsibleNavProps = ( } : undefined; - if (renderAs === 'block' && treeDepth > 0 && subItems) { - // Render as a group block (bold title + list of links underneath) + const onClick = (e: React.MouseEvent) => { + if (customOnClick) { + customOnClick(e); + return; + } + + // Do not navigate if it is a collapsible accordion, if there is a "link" defined it + // will be used in the breadcrumb navigation. + if (isAccordion && isCollapsible) return; + + if (href !== undefined) { + e.preventDefault(); + navigateToUrl(href); + closePanel(); + return; + } + }; + + return { + navNode, + subItems, + isSelected, + isItem, + spaceBefore, + dataTestSubj, + linkProps, + onClick, + }; +}; + +// Generate the EuiCollapsible props for the root component (EuiCollapsibleNavItem) and its +// "items" props (recursively). Both are compatible with the exception of `renderItem` which +// can only be used for sub items (not top level). +function nodeToEuiCollapsibleNavProps( + _navNode: ChromeProjectNavigationNode, + deps: { + navigateToUrl: NavigateToUrlFn; + closePanel: PanelContext['close']; + treeDepth: number; + getIsCollapsed: (path: string) => boolean; + activeNodes: ChromeProjectNavigationNode[][]; + } +): { + items: Array; + isVisible: boolean; +} { + const { navNode, subItems, dataTestSubj, isSelected, isItem, spaceBefore, linkProps, onClick } = + getEuiProps(_navNode, deps); + const { id, path, href, renderAs, isCollapsible } = navNode; + + if (navNode.renderItem) { + // Leave the rendering to the consumer return { - items: [...renderGroup(navNode, subItems, { spaceBefore: spaceBefore ?? null })], - isVisible: subItems.length > 0, + items: [{ renderItem: navNode.renderItem }], + isVisible: true, }; } - if (navNode.renderItem) { + if (renderAs === 'panelOpener') { + // Render as a panel opener (button to open a panel as a second navigation) return { - items: [ - { - renderItem: navNode.renderItem, - }, - ], + items: [...renderPanelOpener(navNode, deps)], isVisible: true, }; } + if (renderAs === 'block' && deps.treeDepth > 0 && subItems) { + // Render as a group block (bold title + list of links underneath) + return { + items: [...renderGroup(navNode, subItems, { spaceBefore: spaceBefore ?? null })], + isVisible: subItems.length > 0, + }; + } + + // Render as a link or an accordion const items: Array = [ { id, @@ -327,12 +336,12 @@ const nodeToEuiCollapsibleNavProps = ( icon: navNode.icon, title: navNode.title, ['data-test-subj']: dataTestSubj, - iconProps: { size: treeDepth === 0 ? 'm' : 's' }, + iconProps: { size: deps.treeDepth === 0 ? 'm' : 's' }, // Render as an accordion or a link (handled by EUI) depending if // "items" is undefined or not. If it is undefined --> a link, otherwise an // accordion is rendered. - ...(subItems ? { items: subItems } : { href, linkProps }), + ...(subItems ? { items: subItems, isCollapsible } : { href, linkProps }), }, ]; @@ -346,7 +355,7 @@ const nodeToEuiCollapsibleNavProps = ( } return { items, isVisible }; -}; +} const className = css` .euiAccordion__childWrapper { @@ -354,204 +363,46 @@ const className = css` } `; -interface AccordionItemsState { - [navNodeId: string]: { - isCollapsible: boolean; - isCollapsed: boolean; - // We want to auto expand the group automatically if the node is active (URL match) - // but once the user manually expand a group we don't want to close it afterward automatically. - doCollapseFromActiveState: boolean; - }; -} - interface Props { navNode: ChromeProjectNavigationNode; } export const NavigationSectionUI: FC = React.memo(({ navNode: _navNode }) => { const { activeNodes } = useNavigation(); - const { navigateToUrl, isSideNavCollapsed } = useServices(); + const { navigateToUrl } = useServices(); + const [items, setItems] = useState(); const { navNode } = useMemo( () => serializeNavNode({ - renderAs: 'accordion', // Top level nodes are always rendered as accordion + renderAs: _navNode.children ? 'accordion' : 'item', // Top level nodes are either item or accordion ..._navNode, }), [_navNode] ); - const { open: openPanel, close: closePanel } = usePanel(); + const { close: closePanel } = usePanel(); - const navNodesById = useMemo(() => { - const byId = { - [navNode.path]: navNode, - }; + const { getIsCollapsed, getAccordionProps } = useAccordionState({ navNode }); - const parse = (navNodes?: ChromeProjectNavigationNode[]) => { - if (!navNodes) return; - navNodes.forEach((childNode) => { - byId[childNode.path] = childNode; - parse(childNode.children); - }); - }; - parse(navNode.children); - - return byId; - }, [navNode]); - - const [itemsAccordionState, setItemsAccordionState] = useState(() => { - return Object.entries(navNodesById).reduce((acc, [_id, node]) => { - if (isAccordionNode(node)) { - let isCollapsed = DEFAULT_IS_COLLAPSED; - let doCollapseFromActiveState = true; - - if (node.defaultIsCollapsed !== undefined) { - isCollapsed = node.defaultIsCollapsed; - doCollapseFromActiveState = false; - } - - acc[_id] = { - isCollapsed, - isCollapsible: node.isCollapsible ?? DEFAULT_IS_COLLAPSIBLE, - doCollapseFromActiveState, - }; - } - - return acc; - }, {}); - }); - - const [subItems, setSubItems] = useState(); - - const toggleAccordion = useCallback((id: string) => { - setItemsAccordionState((prev) => { - const prevState = prev[id]; - const prevValue = prevState?.isCollapsed ?? DEFAULT_IS_COLLAPSED; - const { isCollapsible } = prevState; - return { - ...prev, - [id]: { - ...prev[id], - isCollapsed: !prevValue, - doCollapseFromActiveState: isCollapsible - ? // if the accordion is collapsible & the user has interacted with the accordion - // we don't want to auto-close it when URL changes to not interfere with the user's choice - false - : // if the accordion is **not** collapsible we do want to auto-close it when the URL changes - prevState.doCollapseFromActiveState, - }, - }; - }); - }, []); - - const getAccordionProps = useCallback( - ( - id: string, - _accordionProps?: Partial - ): Partial | undefined => { - const isCollapsed = itemsAccordionState[id]?.isCollapsed; - const isCollapsible = itemsAccordionState[id]?.isCollapsible; - - if (isCollapsed === undefined) return _accordionProps; // No state set yet - - let forceState: EuiAccordionProps['forceState'] = isCollapsed ? 'closed' : 'open'; - if (!isCollapsible) forceState = 'open'; // Allways open if the accordion is not collapsible - - const arrowProps: EuiAccordionProps['arrowProps'] = { - css: isCollapsible ? undefined : { display: 'none' }, - 'data-test-subj': classNames(`accordionArrow`, `accordionArrow-${id}`), - }; - - const updated: Partial = { - ..._accordionProps, - arrowProps, - isCollapsible, - forceState, - onToggle: isCollapsible - ? () => { - toggleAccordion(id); - } - : undefined, - }; - - return updated; - }, - [itemsAccordionState, toggleAccordion] - ); - - const { items, isVisible } = useMemo(() => { + const { + items: [props], + isVisible, + } = useMemo(() => { return nodeToEuiCollapsibleNavProps(navNode, { navigateToUrl, - openPanel, closePanel, - isSideNavCollapsed, treeDepth: 0, - itemsAccordionState, + getIsCollapsed, activeNodes, }); - }, [ - navNode, - navigateToUrl, - openPanel, - closePanel, - isSideNavCollapsed, - itemsAccordionState, - activeNodes, - ]); - - const [props] = items; - const { items: accordionItems } = props; - - if (!isEuiCollapsibleNavItemProps(props)) { - throw new Error(`Invalid EuiCollapsibleNavItem props for node ${props.id}`); - } + }, [navNode, navigateToUrl, closePanel, getIsCollapsed, activeNodes]); - /** - * Effect to set the internal state of each of the accordions (isCollapsed) based on the - * "isActive" state of the navNode or if its path matches the URL location - */ - useEffect(() => { - setItemsAccordionState((prev) => { - return Object.entries(navNodesById).reduce( - (acc, [_id, node]) => { - const prevState = prev[_id]; - - if ( - isAccordionNode(node) && - (!prevState || prevState.doCollapseFromActiveState === true) - ) { - let nextIsActive = false; - let doCollapseFromActiveState = true; - - if (!prevState && node.defaultIsCollapsed !== undefined) { - nextIsActive = !node.defaultIsCollapsed; - doCollapseFromActiveState = false; - } else { - if (prevState?.doCollapseFromActiveState !== false) { - nextIsActive = isActiveFromUrl(node.path, activeNodes); - } else if (nextIsActive === undefined) { - nextIsActive = !DEFAULT_IS_COLLAPSED; - } - } - - acc[_id] = { - ...prevState, - isCollapsed: !nextIsActive, - isCollapsible: node.isCollapsible ?? DEFAULT_IS_COLLAPSIBLE, - doCollapseFromActiveState, - }; - } - return acc; - }, - { ...prev } - ); - }); - }, [navNodesById, activeNodes]); + const { items: topLevelItems } = props; - useEffect(() => { - // Serializer to add recursively the accordionProps to each of the items - // that will control its "open"/"closed" state + handler to toggle the state. - const serializeAccordionItems = ( + // Serializer to add recursively the accordionProps to each of the items + // that will control its "open"/"closed" state + handler to toggle the state. + const serializeAccordionItems = useCallback( + ( _items?: EuiCollapsibleNavSubItemPropsEnhanced[] ): EuiCollapsibleNavSubItemProps[] | undefined => { if (!_items) return; @@ -561,12 +412,12 @@ export const NavigationSectionUI: FC = React.memo(({ navNode: _navNode }) return item; } - const itemsSerialized: EuiCollapsibleNavSubItemProps['items'] = serializeAccordionItems( + const subItems: EuiCollapsibleNavSubItemProps['items'] = serializeAccordionItems( item.items ); const accordionProps = - itemsSerialized === undefined + subItems === undefined ? undefined : getAccordionProps(path ?? item.id!, { onClick: item.onClick, @@ -584,10 +435,10 @@ export const NavigationSectionUI: FC = React.memo(({ navNode: _navNode }) ...rest } = item; - const parsed: EuiCollapsibleNavSubItemProps = itemsSerialized + const parsed: EuiCollapsibleNavSubItemProps = subItems ? { ...rest, - items: itemsSerialized, + items: subItems, accordionProps, isCollapsible, } @@ -599,27 +450,35 @@ export const NavigationSectionUI: FC = React.memo(({ navNode: _navNode }) return parsed; }); - }; + }, + [getAccordionProps] + ); - setSubItems(serializeAccordionItems(accordionItems)); - }, [accordionItems, getAccordionProps]); + useEffect(() => { + setItems(serializeAccordionItems(topLevelItems)); + }, [topLevelItems, serializeAccordionItems]); + + if (!isEuiCollapsibleNavItemProps(props)) { + throw new Error(`Invalid EuiCollapsibleNavItem props for node ${props.id}`); + } if (!isVisible) { return null; } - if (!subItems) { + + if (!items) { return ; } + // Item type ExclusiveUnion - accordions should not contain links + const { href, linkProps, ...rest } = props; + return ( ); }); diff --git a/packages/shared-ux/chrome/navigation/src/ui/constants.ts b/packages/shared-ux/chrome/navigation/src/ui/constants.ts new file mode 100644 index 0000000000000..4a6a85bba00ae --- /dev/null +++ b/packages/shared-ux/chrome/navigation/src/ui/constants.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 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 { EuiThemeSize, RenderAs } from '@kbn/core-chrome-browser'; + +export const DEFAULT_SPACE_BETWEEN_LEVEL_1_GROUPS: EuiThemeSize = 'm'; +export const DEFAULT_IS_COLLAPSED = true; +export const DEFAULT_IS_COLLAPSIBLE = true; +export const DEFAULT_RENDER_AS: RenderAs = 'block'; diff --git a/packages/shared-ux/chrome/navigation/src/ui/hooks/index.ts b/packages/shared-ux/chrome/navigation/src/ui/hooks/index.ts new file mode 100644 index 0000000000000..acfda4ab1bd2e --- /dev/null +++ b/packages/shared-ux/chrome/navigation/src/ui/hooks/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 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 { useAccordionState, type AccordionItemsState } from './use_accordion_state'; diff --git a/packages/shared-ux/chrome/navigation/src/ui/hooks/use_accordion_state.ts b/packages/shared-ux/chrome/navigation/src/ui/hooks/use_accordion_state.ts new file mode 100644 index 0000000000000..782d93464df15 --- /dev/null +++ b/packages/shared-ux/chrome/navigation/src/ui/hooks/use_accordion_state.ts @@ -0,0 +1,181 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { useCallback, useMemo, useState, useEffect } from 'react'; +import classNames from 'classnames'; +import { type EuiAccordionProps } from '@elastic/eui'; +import type { ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; + +import { isAccordionNode, isActiveFromUrl } from '../../utils'; +import { DEFAULT_IS_COLLAPSED, DEFAULT_IS_COLLAPSIBLE } from '../constants'; +import { useNavigation } from '../navigation'; + +export interface AccordionItemsState { + [navNodeId: string]: { + isCollapsible: boolean; + isCollapsed: boolean; + // We want to auto expand the group automatically if the node is active (URL match) + // but once the user manually expand a group we don't want to close it afterward automatically. + doCollapseFromActiveState: boolean; + }; +} + +export const useAccordionState = ({ navNode }: { navNode: ChromeProjectNavigationNode }) => { + const { activeNodes } = useNavigation(); + + const navNodesById = useMemo(() => { + const byId = { + [navNode.path]: navNode, + }; + + const parse = (navNodes?: ChromeProjectNavigationNode[]) => { + if (!navNodes) return; + navNodes.forEach((childNode) => { + byId[childNode.path] = childNode; + parse(childNode.children); + }); + }; + parse(navNode.children); + + return byId; + }, [navNode]); + + const [accordionStateById, setAccordionStateById] = useState(() => { + return Object.entries(navNodesById).reduce((acc, [_id, node]) => { + if (isAccordionNode(node)) { + let isCollapsed = DEFAULT_IS_COLLAPSED; + let doCollapseFromActiveState = true; + + if (node.defaultIsCollapsed !== undefined) { + isCollapsed = node.defaultIsCollapsed; + doCollapseFromActiveState = false; + } + + acc[_id] = { + isCollapsed, + isCollapsible: node.isCollapsible ?? DEFAULT_IS_COLLAPSIBLE, + doCollapseFromActiveState, + }; + } + + return acc; + }, {}); + }); + + const toggleAccordion = useCallback((path: string) => { + setAccordionStateById((prev) => { + const prevState = prev[path]; + const prevValue = prevState?.isCollapsed ?? DEFAULT_IS_COLLAPSED; + const { isCollapsible } = prevState; + return { + ...prev, + [path]: { + ...prev[path], + isCollapsed: !prevValue, + doCollapseFromActiveState: isCollapsible + ? // if the accordion is collapsible & the user has interacted with the accordion + // we don't want to auto-close it when URL changes to not interfere with the user's choice + false + : // if the accordion is **not** collapsible we do want to auto-close it when the URL changes + prevState.doCollapseFromActiveState, + }, + }; + }); + }, []); + + const getAccordionProps = useCallback( + ( + path: string, + _accordionProps?: Partial + ): Partial | undefined => { + const isCollapsed = accordionStateById[path]?.isCollapsed; + const isCollapsible = accordionStateById[path]?.isCollapsible; + + if (isCollapsed === undefined) return _accordionProps; // No state set yet + + let forceState: EuiAccordionProps['forceState'] = isCollapsed ? 'closed' : 'open'; + if (!isCollapsible) forceState = 'open'; // Allways open if the accordion is not collapsible + + const arrowProps: EuiAccordionProps['arrowProps'] = { + css: isCollapsible ? undefined : { display: 'none' }, + 'data-test-subj': classNames(`accordionArrow`, `accordionArrow-${path}`), + }; + + const updated: Partial = { + ..._accordionProps, + arrowProps, + isCollapsible, + forceState, + onToggle: isCollapsible + ? () => { + toggleAccordion(path); + } + : undefined, + }; + + return updated; + }, + [accordionStateById, toggleAccordion] + ); + + const getIsCollapsed = useCallback( + (path: string) => { + return accordionStateById[path]?.isCollapsed ?? DEFAULT_IS_COLLAPSED; + }, + [accordionStateById] + ); + + /** + * Effect to set the internal state of each of the accordions (isCollapsed) based on the + * "isActive" state of the navNode or if its path matches the URL location + */ + useEffect(() => { + setAccordionStateById((prev) => { + return Object.entries(navNodesById).reduce( + (acc, [_id, node]) => { + const prevState = prev[_id]; + + if ( + isAccordionNode(node) && + (!prevState || prevState.doCollapseFromActiveState === true) + ) { + let nextIsActive = false; + let doCollapseFromActiveState = true; + + if (!prevState && node.defaultIsCollapsed !== undefined) { + nextIsActive = !node.defaultIsCollapsed; + doCollapseFromActiveState = false; + } else { + if (prevState?.doCollapseFromActiveState !== false) { + nextIsActive = isActiveFromUrl(node.path, activeNodes); + } else if (nextIsActive === undefined) { + nextIsActive = !DEFAULT_IS_COLLAPSED; + } + } + + acc[_id] = { + ...prevState, + isCollapsed: !nextIsActive, + isCollapsible: node.isCollapsible ?? DEFAULT_IS_COLLAPSIBLE, + doCollapseFromActiveState, + }; + } + return acc; + }, + { ...prev } + ); + }); + }, [navNodesById, activeNodes]); + + return { + /** Get the EUI accordion props for the node at a specific path */ + getAccordionProps, + /** Get the isCollapsed state for a node at a specific path */ + getIsCollapsed, + }; +}; diff --git a/packages/shared-ux/chrome/navigation/src/ui/types.ts b/packages/shared-ux/chrome/navigation/src/ui/types.ts index 10b1b7630b20c..ec01773b422db 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/types.ts +++ b/packages/shared-ux/chrome/navigation/src/ui/types.ts @@ -5,53 +5,8 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { ReactNode } from 'react'; +import { type EuiCollapsibleNavSubItemProps } from '@elastic/eui'; -import type { - AppDeepLinkId, - ChromeProjectNavigationNode, - NodeDefinition, -} from '@kbn/core-chrome-browser'; - -/** - * @public - * - * A navigation node definition with its unique id, title, path in the tree and optional deep link. - * Those are the props that can be passed to the Navigation.Group and Navigation.Item components. - */ -export interface NodeProps< - LinkId extends AppDeepLinkId = AppDeepLinkId, - Id extends string = string, - ChildrenId extends string = Id -> extends Omit, 'children'> { - /** - * Children of the node. For Navigation.Item (only) it allows a function to be set. - * This function will receive the ChromeProjectNavigationNode object - */ - children?: ReactNode; - /** @internal - Prop internally controlled, don't use it. */ - parentNodePath?: string; - /** @internal - Prop internally controlled, don't use it. */ - rootIndex?: number; - /** @internal - Prop internally controlled, don't use it. */ - treeDepth?: number; - /** @internal - Prop internally controlled, don't use it. */ - index?: number; -} - -/** - * @internal - * - * Function to unregister a navigation node from its parent. - */ -export type UnRegisterFunction = () => void; - -/** - * @internal - * - * A function to register a navigation node on its parent. - */ -export type RegisterFunction = ( - navNode: ChromeProjectNavigationNode, - order?: number -) => UnRegisterFunction; +export type EuiCollapsibleNavSubItemPropsEnhanced = EuiCollapsibleNavSubItemProps & { + path?: string; +}; diff --git a/packages/shared-ux/chrome/navigation/src/utils.ts b/packages/shared-ux/chrome/navigation/src/utils.ts index 5b070c55176f0..f63ff518a18d4 100644 --- a/packages/shared-ux/chrome/navigation/src/utils.ts +++ b/packages/shared-ux/chrome/navigation/src/utils.ts @@ -39,3 +39,9 @@ export function isActiveFromUrl( : nodesBranch.some((branch) => isSamePath(branch.path, nodePath)); }, false); } + +export const isAccordionNode = ( + node: Pick +) => + node.renderAs === 'accordion' || + ['defaultIsCollapsed', 'isCollapsible'].some((prop) => node.hasOwnProperty(prop)); diff --git a/x-pack/test_serverless/functional/test_suites/observability/navigation.ts b/x-pack/test_serverless/functional/test_suites/observability/navigation.ts index 24287170b83a6..5c9dc65027b6b 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/navigation.ts @@ -33,7 +33,6 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await svlCommonNavigation.breadcrumbs.expectExists(); // check side nav links - await svlCommonNavigation.sidenav.expectSectionOpen('observability_project_nav'); await svlCommonNavigation.breadcrumbs.expectBreadcrumbExists({ deepLinkId: 'observabilityOnboarding', }); diff --git a/x-pack/test_serverless/functional/test_suites/search/navigation.ts b/x-pack/test_serverless/functional/test_suites/search/navigation.ts index 85042af186ebc..554a2e2b63c15 100644 --- a/x-pack/test_serverless/functional/test_suites/search/navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/search/navigation.ts @@ -37,7 +37,6 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { // check side nav links await testSubjects.existOrFail(`svlSearchOverviewPage`); - await svlCommonNavigation.sidenav.expectSectionOpen('search_project_nav'); await svlCommonNavigation.sidenav.expectLinkActive({ deepLinkId: 'serverlessElasticsearch', }); From a03f3bce7dfc3a7daac6367954290890d92ac34d Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Thu, 6 Jun 2024 13:06:39 +0300 Subject: [PATCH 033/122] [Cloud Security] FTRs for Accessing Pages with Custom Roles (#184622) --- ...enerated_csp_requirements_test_coverage.md | 46 +- .../__auto_generated_csp_test_log.json | 671 +++++++++++++++++- .../latest_findings_transform.ts | 4 +- .../latest_vulnerabilities_transforms.ts | 5 +- .../page_objects/benchmark_page.ts | 59 ++ .../page_objects/findings_page.ts | 5 + .../page_objects/index.ts | 4 + .../page_objects/security_common.ts | 128 ++++ .../pages/benchmark.ts | 79 +++ .../pages/compliance_dashboard.ts | 27 +- .../pages/findings.ts | 29 +- .../pages/findings_grouping.ts | 2 + .../pages/index.ts | 12 +- 13 files changed, 1019 insertions(+), 52 deletions(-) create mode 100644 x-pack/test/cloud_security_posture_functional/page_objects/benchmark_page.ts create mode 100644 x-pack/test/cloud_security_posture_functional/page_objects/security_common.ts create mode 100644 x-pack/test/cloud_security_posture_functional/pages/benchmark.ts diff --git a/x-pack/plugins/cloud_security_posture/common/dev_docs/__auto_generated_csp_requirements_test_coverage.md b/x-pack/plugins/cloud_security_posture/common/dev_docs/__auto_generated_csp_requirements_test_coverage.md index 16c826cbc9dd2..a6fdc6aa618ab 100644 --- a/x-pack/plugins/cloud_security_posture/common/dev_docs/__auto_generated_csp_requirements_test_coverage.md +++ b/x-pack/plugins/cloud_security_posture/common/dev_docs/__auto_generated_csp_requirements_test_coverage.md @@ -7,7 +7,7 @@ You can also check out the dedicated app view, which enables easier search and f ## Directory: x-pack/plugins/cloud_security_posture -**Total Tests:** 444 | **Skipped:** 5 (1.13%) | **Todo:** 0 (0.00%) +**Total Tests:** 458 | **Skipped:** 5 (1.09%) | **Todo:** 0 (0.00%) ![](https://img.shields.io/badge/UT-brightgreen) ![](https://img.shields.io/badge/HAS-SKIP-yellow) @@ -69,7 +69,6 @@ You can also check out the dedicated app view, which enables easier search and f | [useNavigateFindings](x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts) | describe | | | | [creates a URL to findings page with correct path, filter and dataViewId](x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts) | it | | | | [creates a URL to findings page with correct path and negated filter](x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts) | it | | | -| [creates a URL to findings resource page with correct path and filter](x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts) | it | | | | [creates a URL to vulnerabilities page with correct path, filter and dataViewId](x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts) | it | | | | [useUrlQuery](x-pack/plugins/cloud_security_posture/public/common/hooks/use_url_query.test.ts) | describe | | | | [uses default query when no query is provided](x-pack/plugins/cloud_security_posture/public/common/hooks/use_url_query.test.ts) | it | | | @@ -266,6 +265,14 @@ You can also check out the dedicated app view, which enables easier search and f | [Should return undefined when datastream is undefined](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/utils.test.ts) | it | | | | [Should return undefined when stream is undefined](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/utils.test.ts) | it | | | | [Should return undefined when stream.var is invalid](x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/utils.test.ts) | it | | | +| [NoFindingsStates](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | describe | | | +| [should show the indexing notification when CSPM is not installed and KSPM is indexing](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | | +| [should show the indexing notification when KSPM is not installed and CSPM is indexing](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | | +| [should show the indexing timout notification when CSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | | +| [should show the indexing timout notification when KSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | | +| [should show the unprivileged notification when CSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | | +| [should show the unprivileged notification when KSPM is status is index-timeout](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | | +| [should show the not-installed notification when CSPM and KSPM status is not-installed](x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx) | it | | | | [](x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx) | describe | | | | [renders cis integration name](x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx) | it | | | | [renders benchmark version](x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx) | it | | | @@ -335,6 +342,13 @@ You can also check out the dedicated app view, which enables easier search and f | [](x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx) | describe | | | | [calls Benchmark API](x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx) | it | | | | [Display success state when result request is resolved](x-pack/plugins/cloud_security_posture/public/pages/rules/rules.test.tsx) | it | | | +| [use_change_csp_rule_state](x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx) | describe | | | +| [should call http.post with the correct parameters](x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx) | it | | | +| [should cancel queries and update query data onMutate](x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx) | it | | | +| [should invalidate queries onSettled](x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx) | it | | | +| [should restore previous query data onError](x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx) | it | | | +| [creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState](x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx) | it | | | +| [creates the new cache with rules in a unmute state](x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx) | it | | | | [](x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx) | describe | | | | [Header Info](x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx) | describe | | | | [displays text details flyout header info](x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx) | it | | | @@ -464,9 +478,9 @@ You can also check out the dedicated app view, which enables easier search and f ## Directory: x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture -**Total Tests:** 37 | **Skipped:** 4 (10.81%) | **Todo:** 0 (0.00%) +**Total Tests:** 37 | **Skipped:** 0 (0.00%) | **Todo:** 0 (0.00%) -![](https://img.shields.io/badge/FTR-blue) ![](https://img.shields.io/badge/SERVERLESS-pink) ![](https://img.shields.io/badge/API-INTEGRATION-purple) ![](https://img.shields.io/badge/HAS-SKIP-yellow) +![](https://img.shields.io/badge/FTR-blue) ![](https://img.shields.io/badge/SERVERLESS-pink) ![](https://img.shields.io/badge/API-INTEGRATION-purple)
Test Details @@ -490,10 +504,10 @@ You can also check out the dedicated app view, which enables easier search and f | [Should return 200 status code and paginate rules with a limit of PerPage](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/find_csp_benchmark_rule.ts) | it | | | | [cloud_security_posture](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/index.ts) | describe | | | | [GET /internal/cloud_security_posture/status](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | describe | | | -| [STATUS = INDEXED TEST](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | describe | ![](https://img.shields.io/badge/skipped-yellow) | | -| [Return kspm status indexed when logs-cloud_security_posture.findings_latest-default contains new kspm documents](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | | -| [Return cspm status indexed when logs-cloud_security_posture.findings_latest-default contains new cspm documents](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | | -| [Return vuln status indexed when logs-cloud_security_posture.vulnerabilities_latest-default contains new documents](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | | +| [STATUS = INDEXED TEST](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | describe | | | +| [Return kspm status indexed when logs-cloud_security_posture.findings_latest-default contains new kspm documents](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | it | | | +| [Return cspm status indexed when logs-cloud_security_posture.findings_latest-default contains new cspm documents](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | it | | | +| [Return vuln status indexed when logs-cloud_security_posture.vulnerabilities_latest-default contains new documents](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexed.ts) | it | | | | [GET /internal/cloud_security_posture/status](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexing.ts) | describe | | | | [STATUS = INDEXING TEST](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexing.ts) | describe | | | | [Return kspm status indexing when logs-cloud_security_posture.findings_latest-default doesn](x-pack/test_serverless/api_integration/test_suites/security/cloud_security_posture/status/status_indexing.ts) | it | | | @@ -654,15 +668,21 @@ You can also check out the dedicated app view, which enables easier search and f ## Directory: x-pack/test/cloud_security_posture_functional -**Total Tests:** 190 | **Skipped:** 37 (19.47%) | **Todo:** 2 (1.05%) +**Total Tests:** 202 | **Skipped:** 41 (20.30%) | **Todo:** 3 (1.49%) -![](https://img.shields.io/badge/FTR-blue) ![](https://img.shields.io/badge/HAS-TODO-green) ![](https://img.shields.io/badge/HAS-SKIP-yellow) +![](https://img.shields.io/badge/FTR-blue) ![](https://img.shields.io/badge/HAS-SKIP-yellow) ![](https://img.shields.io/badge/HAS-TODO-green)
Test Details | Test Label | Type | Skipped | Todo | |------------|------|---------|------| +| [Access with custom roles](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | describe | | | +| [Access with valid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | | +| [Access with invalid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | | +| [Access with custom roles - rule page](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | describe | | | +| [Access with valid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it | | | +| [Access with invalid user role](x-pack/test/cloud_security_posture_functional/pages/benchmark.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | | | [Test adding Cloud Security Posture Integrations CNVM](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | describe | | | | [CNVM AWS](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | describe | | | | [Hyperlink on PostInstallation Modal should have the correct URL](x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts) | it | | | @@ -748,6 +768,9 @@ You can also check out the dedicated app view, which enables easier search and f | [displays accurate summary compliance score](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | it | | | | [TODO - Cloud Dashboard](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | describe | | ![](https://img.shields.io/badge/todo-green) | | [todo - displays accurate summary compliance score](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | it | | ![](https://img.shields.io/badge/todo-green) | +| [Access with custom roles](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | describe | | | +| [Access with valid user role](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | it | | | +| [todo - Access with invalid user role](x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | ![](https://img.shields.io/badge/todo-green) | | [Findings Page - Alerts](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | describe | | | | [Create detection rule](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | describe | ![](https://img.shields.io/badge/skipped-yellow) | | | [Creates a detection rule from the Take Action button and navigates to rule page](x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts) | it | ![](https://img.shields.io/badge/skipped-yellow) | | @@ -796,6 +819,9 @@ You can also check out the dedicated app view, which enables easier search and f | [Reset fields to default](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | | | [Findings Page - support muting rules](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe | | | | [verify only enabled rules appears](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | | +| [Access with custom roles](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | describe | | | +| [Access with valid user role](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | | +| [Access with invalid user role](x-pack/test/cloud_security_posture_functional/pages/findings.ts) | it | | | | [Cloud Security Posture](x-pack/test/cloud_security_posture_functional/pages/index.ts) | describe | | | | [Cloud Posture Rules Page](x-pack/test/cloud_security_posture_functional/pages/rules.ts) | describe | ![](https://img.shields.io/badge/skipped-yellow) | | | [Rules Page - Rules Counters](x-pack/test/cloud_security_posture_functional/pages/rules.ts) | describe | ![](https://img.shields.io/badge/skipped-yellow) | | diff --git a/x-pack/plugins/cloud_security_posture/common/scripts/__auto_generated_csp_test_log.json b/x-pack/plugins/cloud_security_posture/common/scripts/__auto_generated_csp_test_log.json index 98a7c6629ee7e..8c177cd46e713 100644 --- a/x-pack/plugins/cloud_security_posture/common/scripts/__auto_generated_csp_test_log.json +++ b/x-pack/plugins/cloud_security_posture/common/scripts/__auto_generated_csp_test_log.json @@ -1148,7 +1148,6 @@ "describe('useNavigateFindings')", " it('creates a URL to findings page with correct path, filter and dataViewId')", " it('creates a URL to findings page with correct path and negated filter')", - " it('creates a URL to findings resource page with correct path and filter')", " it('creates a URL to vulnerabilities page with correct path, filter and dataViewId')" ], "testSuits": [ @@ -1182,16 +1181,6 @@ "isSkipped": false, "isTodo": false }, - { - "id": "creates-a-url-to-findings-resource-page-with-correct-path-and-filter", - "rawLine": " it('creates a URL to findings resource page with correct path and filter', () => {", - "line": " it('creates a URL to findings resource page with correct path and filter')", - "label": "creates a URL to findings resource page with correct path and filter", - "indent": 2, - "type": "it", - "isSkipped": false, - "isTodo": false - }, { "id": "creates-a-url-to-vulnerabilities-page-with-correct-path,-filter-and-dataviewid", "rawLine": " it('creates a URL to vulnerabilities page with correct path, filter and dataViewId', () => {", @@ -1234,16 +1223,6 @@ "isSkipped": false, "isTodo": false }, - { - "id": "creates-a-url-to-findings-resource-page-with-correct-path-and-filter", - "rawLine": " it('creates a URL to findings resource page with correct path and filter', () => {", - "line": " it('creates a URL to findings resource page with correct path and filter')", - "label": "creates a URL to findings resource page with correct path and filter", - "indent": 2, - "type": "it", - "isSkipped": false, - "isTodo": false - }, { "id": "creates-a-url-to-vulnerabilities-page-with-correct-path,-filter-and-dataviewid", "rawLine": " it('creates a URL to vulnerabilities page with correct path, filter and dataViewId', () => {", @@ -5695,6 +5674,190 @@ } ] }, + { + "filePath": "x-pack/plugins/cloud_security_posture/public/components/no_findings_states.test.tsx", + "fileName": "no_findings_states.test.tsx", + "directory": "x-pack/plugins/cloud_security_posture", + "tags": [ + "UT" + ], + "lines": [ + "describe('NoFindingsStates')", + " it('should show the indexing notification when CSPM is not installed and KSPM is indexing')", + " it('should show the indexing notification when KSPM is not installed and CSPM is indexing')", + " it('should show the indexing timout notification when CSPM is status is index-timeout')", + " it('should show the indexing timout notification when KSPM is status is index-timeout')", + " it('should show the unprivileged notification when CSPM is status is index-timeout')", + " it('should show the unprivileged notification when KSPM is status is index-timeout')", + " it('should show the not-installed notification when CSPM and KSPM status is not-installed')" + ], + "testSuits": [ + { + "id": "nofindingsstates", + "rawLine": "describe('NoFindingsStates', () => {", + "line": "describe('NoFindingsStates')", + "label": "NoFindingsStates", + "indent": 0, + "type": "describe", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-indexing-notification-when-cspm-is-not-installed-and-kspm-is-indexing", + "rawLine": " it('should show the indexing notification when CSPM is not installed and KSPM is indexing', async () => {", + "line": " it('should show the indexing notification when CSPM is not installed and KSPM is indexing')", + "label": "should show the indexing notification when CSPM is not installed and KSPM is indexing", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-indexing-notification-when-kspm-is-not-installed-and-cspm-is-indexing", + "rawLine": " it('should show the indexing notification when KSPM is not installed and CSPM is indexing', async () => {", + "line": " it('should show the indexing notification when KSPM is not installed and CSPM is indexing')", + "label": "should show the indexing notification when KSPM is not installed and CSPM is indexing", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-indexing-timout-notification-when-cspm-is-status-is-index-timeout", + "rawLine": " it('should show the indexing timout notification when CSPM is status is index-timeout', async () => {", + "line": " it('should show the indexing timout notification when CSPM is status is index-timeout')", + "label": "should show the indexing timout notification when CSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-indexing-timout-notification-when-kspm-is-status-is-index-timeout", + "rawLine": " it('should show the indexing timout notification when KSPM is status is index-timeout', async () => {", + "line": " it('should show the indexing timout notification when KSPM is status is index-timeout')", + "label": "should show the indexing timout notification when KSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-unprivileged-notification-when-cspm-is-status-is-index-timeout", + "rawLine": " it('should show the unprivileged notification when CSPM is status is index-timeout', async () => {", + "line": " it('should show the unprivileged notification when CSPM is status is index-timeout')", + "label": "should show the unprivileged notification when CSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-unprivileged-notification-when-kspm-is-status-is-index-timeout", + "rawLine": " it('should show the unprivileged notification when KSPM is status is index-timeout', async () => {", + "line": " it('should show the unprivileged notification when KSPM is status is index-timeout')", + "label": "should show the unprivileged notification when KSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-not-installed-notification-when-cspm-and-kspm-status-is-not-installed", + "rawLine": " it('should show the not-installed notification when CSPM and KSPM status is not-installed', async () => {", + "line": " it('should show the not-installed notification when CSPM and KSPM status is not-installed')", + "label": "should show the not-installed notification when CSPM and KSPM status is not-installed", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + } + ], + "tree": [ + { + "id": "nofindingsstates", + "rawLine": "describe('NoFindingsStates', () => {", + "line": "describe('NoFindingsStates')", + "label": "NoFindingsStates", + "indent": 0, + "type": "describe", + "isSkipped": false, + "isTodo": false, + "children": [ + { + "id": "should-show-the-indexing-notification-when-cspm-is-not-installed-and-kspm-is-indexing", + "rawLine": " it('should show the indexing notification when CSPM is not installed and KSPM is indexing', async () => {", + "line": " it('should show the indexing notification when CSPM is not installed and KSPM is indexing')", + "label": "should show the indexing notification when CSPM is not installed and KSPM is indexing", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-indexing-notification-when-kspm-is-not-installed-and-cspm-is-indexing", + "rawLine": " it('should show the indexing notification when KSPM is not installed and CSPM is indexing', async () => {", + "line": " it('should show the indexing notification when KSPM is not installed and CSPM is indexing')", + "label": "should show the indexing notification when KSPM is not installed and CSPM is indexing", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-indexing-timout-notification-when-cspm-is-status-is-index-timeout", + "rawLine": " it('should show the indexing timout notification when CSPM is status is index-timeout', async () => {", + "line": " it('should show the indexing timout notification when CSPM is status is index-timeout')", + "label": "should show the indexing timout notification when CSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-indexing-timout-notification-when-kspm-is-status-is-index-timeout", + "rawLine": " it('should show the indexing timout notification when KSPM is status is index-timeout', async () => {", + "line": " it('should show the indexing timout notification when KSPM is status is index-timeout')", + "label": "should show the indexing timout notification when KSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-unprivileged-notification-when-cspm-is-status-is-index-timeout", + "rawLine": " it('should show the unprivileged notification when CSPM is status is index-timeout', async () => {", + "line": " it('should show the unprivileged notification when CSPM is status is index-timeout')", + "label": "should show the unprivileged notification when CSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-unprivileged-notification-when-kspm-is-status-is-index-timeout", + "rawLine": " it('should show the unprivileged notification when KSPM is status is index-timeout', async () => {", + "line": " it('should show the unprivileged notification when KSPM is status is index-timeout')", + "label": "should show the unprivileged notification when KSPM is status is index-timeout", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-show-the-not-installed-notification-when-cspm-and-kspm-status-is-not-installed", + "rawLine": " it('should show the not-installed notification when CSPM and KSPM status is not-installed', async () => {", + "line": " it('should show the not-installed notification when CSPM and KSPM status is not-installed')", + "label": "should show the not-installed notification when CSPM and KSPM status is not-installed", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + } + ] + } + ] + }, { "filePath": "x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx", "fileName": "benchmarks_table.test.tsx", @@ -7330,6 +7493,169 @@ } ] }, + { + "filePath": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_change_csp_rule_state.test.tsx", + "fileName": "use_change_csp_rule_state.test.tsx", + "directory": "x-pack/plugins/cloud_security_posture", + "tags": [ + "UT" + ], + "lines": [ + "describe('use_change_csp_rule_state')", + " it('should call http.post with the correct parameters')", + " it('should cancel queries and update query data onMutate')", + " it('should invalidate queries onSettled')", + " it('should restore previous query data onError')", + " it('creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState')", + " it('creates the new cache with rules in a unmute state')" + ], + "testSuits": [ + { + "id": "use_change_csp_rule_state", + "rawLine": "describe('use_change_csp_rule_state', () => {", + "line": "describe('use_change_csp_rule_state')", + "label": "use_change_csp_rule_state", + "indent": 0, + "type": "describe", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-call-http.post-with-the-correct-parameters", + "rawLine": " it('should call http.post with the correct parameters', async () => {", + "line": " it('should call http.post with the correct parameters')", + "label": "should call http.post with the correct parameters", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-cancel-queries-and-update-query-data-onmutate", + "rawLine": " it('should cancel queries and update query data onMutate', async () => {", + "line": " it('should cancel queries and update query data onMutate')", + "label": "should cancel queries and update query data onMutate", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-invalidate-queries-onsettled", + "rawLine": " it('should invalidate queries onSettled', async () => {", + "line": " it('should invalidate queries onSettled')", + "label": "should invalidate queries onSettled", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-restore-previous-query-data-onerror", + "rawLine": " it('should restore previous query data onError', async () => {", + "line": " it('should restore previous query data onError')", + "label": "should restore previous query data onError", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "creates-the-new-set-of-cache-rules-in-a-muted-state-when-calling-createruleswithupdatedstate", + "rawLine": " it('creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState', async () => {", + "line": " it('creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState')", + "label": "creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "creates-the-new-cache-with-rules-in-a-unmute-state", + "rawLine": " it('creates the new cache with rules in a unmute state', async () => {", + "line": " it('creates the new cache with rules in a unmute state')", + "label": "creates the new cache with rules in a unmute state", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + } + ], + "tree": [ + { + "id": "use_change_csp_rule_state", + "rawLine": "describe('use_change_csp_rule_state', () => {", + "line": "describe('use_change_csp_rule_state')", + "label": "use_change_csp_rule_state", + "indent": 0, + "type": "describe", + "isSkipped": false, + "isTodo": false, + "children": [ + { + "id": "should-call-http.post-with-the-correct-parameters", + "rawLine": " it('should call http.post with the correct parameters', async () => {", + "line": " it('should call http.post with the correct parameters')", + "label": "should call http.post with the correct parameters", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-cancel-queries-and-update-query-data-onmutate", + "rawLine": " it('should cancel queries and update query data onMutate', async () => {", + "line": " it('should cancel queries and update query data onMutate')", + "label": "should cancel queries and update query data onMutate", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-invalidate-queries-onsettled", + "rawLine": " it('should invalidate queries onSettled', async () => {", + "line": " it('should invalidate queries onSettled')", + "label": "should invalidate queries onSettled", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "should-restore-previous-query-data-onerror", + "rawLine": " it('should restore previous query data onError', async () => {", + "line": " it('should restore previous query data onError')", + "label": "should restore previous query data onError", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "creates-the-new-set-of-cache-rules-in-a-muted-state-when-calling-createruleswithupdatedstate", + "rawLine": " it('creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState', async () => {", + "line": " it('creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState')", + "label": "creates the new set of cache rules in a muted state when calling createRulesWithUpdatedState", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "creates-the-new-cache-with-rules-in-a-unmute-state", + "rawLine": " it('creates the new cache with rules in a unmute state', async () => {", + "line": " it('creates the new cache with rules in a unmute state')", + "label": "creates the new cache with rules in a unmute state", + "indent": 2, + "type": "it", + "isSkipped": false, + "isTodo": false + } + ] + } + ] + }, { "filePath": "x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx", "fileName": "vulnerability_finding_flyout.test.tsx", @@ -10683,12 +11009,11 @@ "tags": [ "FTR", "SERVERLESS", - "API INTEGRATION", - "HAS SKIP" + "API INTEGRATION" ], "lines": [ " describe('GET /internal/cloud_security_posture/status')", - " describe.skip('STATUS = INDEXED TEST')", + " describe('STATUS = INDEXED TEST')", " it(`Return kspm status indexed when logs-cloud_security_posture.findings_latest-default contains new kspm documents`)", " it(`Return cspm status indexed when logs-cloud_security_posture.findings_latest-default contains new cspm documents`)", " it(`Return vuln status indexed when logs-cloud_security_posture.vulnerabilities_latest-default contains new documents`)" @@ -10706,12 +11031,12 @@ }, { "id": "status-=-indexed-test", - "rawLine": " describe.skip('STATUS = INDEXED TEST', () => {", - "line": " describe.skip('STATUS = INDEXED TEST')", + "rawLine": " describe('STATUS = INDEXED TEST', () => {", + "line": " describe('STATUS = INDEXED TEST')", "label": "STATUS = INDEXED TEST", "indent": 4, "type": "describe", - "isSkipped": true, + "isSkipped": false, "isTodo": false }, { @@ -10758,12 +11083,12 @@ "children": [ { "id": "status-=-indexed-test", - "rawLine": " describe.skip('STATUS = INDEXED TEST', () => {", - "line": " describe.skip('STATUS = INDEXED TEST')", + "rawLine": " describe('STATUS = INDEXED TEST', () => {", + "line": " describe('STATUS = INDEXED TEST')", "label": "STATUS = INDEXED TEST", "indent": 4, "type": "describe", - "isSkipped": true, + "isSkipped": false, "isTodo": false, "children": [ { @@ -10773,7 +11098,7 @@ "label": "Return kspm status indexed when logs-cloud_security_posture.findings_latest-default contains new kspm documents", "indent": 6, "type": "it", - "isSkipped": true, + "isSkipped": false, "isTodo": false }, { @@ -10783,7 +11108,7 @@ "label": "Return cspm status indexed when logs-cloud_security_posture.findings_latest-default contains new cspm documents", "indent": 6, "type": "it", - "isSkipped": true, + "isSkipped": false, "isTodo": false }, { @@ -10793,7 +11118,7 @@ "label": "Return vuln status indexed when logs-cloud_security_posture.vulnerabilities_latest-default contains new documents", "indent": 6, "type": "it", - "isSkipped": true, + "isSkipped": false, "isTodo": false } ] @@ -13678,6 +14003,151 @@ } ] }, + { + "filePath": "x-pack/test/cloud_security_posture_functional/pages/benchmark.ts", + "fileName": "benchmark.ts", + "directory": "x-pack/test/cloud_security_posture_functional", + "tags": [ + "FTR", + "HAS SKIP" + ], + "lines": [ + " describe('Access with custom roles')", + " it.skip('Access with valid user role')", + " it.skip('Access with invalid user role')", + " describe('Access with custom roles - rule page')", + " it('Access with valid user role')", + " it.skip('Access with invalid user role')" + ], + "testSuits": [ + { + "id": "access-with-custom-roles", + "rawLine": " describe('Access with custom roles', async () => {", + "line": " describe('Access with custom roles')", + "label": "Access with custom roles", + "indent": 2, + "type": "describe", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-valid-user-role", + "rawLine": " it.skip('Access with valid user role', async () => {", + "line": " it.skip('Access with valid user role')", + "label": "Access with valid user role", + "indent": 4, + "type": "it", + "isSkipped": true, + "isTodo": false + }, + { + "id": "access-with-invalid-user-role", + "rawLine": " it.skip('Access with invalid user role', async () => {});", + "line": " it.skip('Access with invalid user role')", + "label": "Access with invalid user role", + "indent": 4, + "type": "it", + "isSkipped": true, + "isTodo": false + }, + { + "id": "access-with-custom-roles---rule-page", + "rawLine": " describe('Access with custom roles - rule page', async () => {", + "line": " describe('Access with custom roles - rule page')", + "label": "Access with custom roles - rule page", + "indent": 4, + "type": "describe", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-valid-user-role", + "rawLine": " it('Access with valid user role', async () => {", + "line": " it('Access with valid user role')", + "label": "Access with valid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-invalid-user-role", + "rawLine": " it.skip('Access with invalid user role', async () => {});", + "line": " it.skip('Access with invalid user role')", + "label": "Access with invalid user role", + "indent": 6, + "type": "it", + "isSkipped": true, + "isTodo": false + } + ], + "tree": [ + { + "id": "access-with-custom-roles", + "rawLine": " describe('Access with custom roles', async () => {", + "line": " describe('Access with custom roles')", + "label": "Access with custom roles", + "indent": 2, + "type": "describe", + "isSkipped": false, + "isTodo": false, + "children": [ + { + "id": "access-with-valid-user-role", + "rawLine": " it.skip('Access with valid user role', async () => {", + "line": " it.skip('Access with valid user role')", + "label": "Access with valid user role", + "indent": 4, + "type": "it", + "isSkipped": true, + "isTodo": false + }, + { + "id": "access-with-invalid-user-role", + "rawLine": " it.skip('Access with invalid user role', async () => {});", + "line": " it.skip('Access with invalid user role')", + "label": "Access with invalid user role", + "indent": 4, + "type": "it", + "isSkipped": true, + "isTodo": false + }, + { + "id": "access-with-custom-roles---rule-page", + "rawLine": " describe('Access with custom roles - rule page', async () => {", + "line": " describe('Access with custom roles - rule page')", + "label": "Access with custom roles - rule page", + "indent": 4, + "type": "describe", + "isSkipped": false, + "isTodo": false, + "children": [ + { + "id": "access-with-valid-user-role", + "rawLine": " it('Access with valid user role', async () => {", + "line": " it('Access with valid user role')", + "label": "Access with valid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-invalid-user-role", + "rawLine": " it.skip('Access with invalid user role', async () => {});", + "line": " it.skip('Access with invalid user role')", + "label": "Access with invalid user role", + "indent": 6, + "type": "it", + "isSkipped": true, + "isTodo": false + } + ] + } + ] + } + ] + }, { "filePath": "x-pack/test/cloud_security_posture_functional/pages/cis_integrations/cnvm/cis_integration_cnvm.ts", "fileName": "cis_integration_cnvm.ts", @@ -15516,6 +15986,7 @@ "directory": "x-pack/test/cloud_security_posture_functional", "tags": [ "FTR", + "HAS SKIP", "HAS TODO" ], "lines": [ @@ -15523,7 +15994,10 @@ " describe('Kubernetes Dashboard')", " it('displays accurate summary compliance score')", " describe('TODO - Cloud Dashboard', () => {", - " it('todo - displays accurate summary compliance score', async () => {});" + " it('todo - displays accurate summary compliance score', async () => {});", + " describe('Access with custom roles')", + " it('Access with valid user role')", + " it.skip('todo - Access with invalid user role')" ], "testSuits": [ { @@ -15575,6 +16049,36 @@ "type": "it", "isSkipped": false, "isTodo": true + }, + { + "id": "access-with-custom-roles", + "rawLine": " describe('Access with custom roles', async () => {", + "line": " describe('Access with custom roles')", + "label": "Access with custom roles", + "indent": 4, + "type": "describe", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-valid-user-role", + "rawLine": " it('Access with valid user role', async () => {", + "line": " it('Access with valid user role')", + "label": "Access with valid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "todo---access-with-invalid-user-role", + "rawLine": " it.skip('todo - Access with invalid user role', async () => {});", + "line": " it.skip('todo - Access with invalid user role')", + "label": "todo - Access with invalid user role", + "indent": 6, + "type": "it", + "isSkipped": true, + "isTodo": true } ], "tree": [ @@ -15631,6 +16135,38 @@ "isTodo": true } ] + }, + { + "id": "access-with-custom-roles", + "rawLine": " describe('Access with custom roles', async () => {", + "line": " describe('Access with custom roles')", + "label": "Access with custom roles", + "indent": 4, + "type": "describe", + "isSkipped": false, + "isTodo": false, + "children": [ + { + "id": "access-with-valid-user-role", + "rawLine": " it('Access with valid user role', async () => {", + "line": " it('Access with valid user role')", + "label": "Access with valid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "todo---access-with-invalid-user-role", + "rawLine": " it.skip('todo - Access with invalid user role', async () => {});", + "line": " it.skip('todo - Access with invalid user role')", + "label": "todo - Access with invalid user role", + "indent": 6, + "type": "it", + "isSkipped": true, + "isTodo": true + } + ] } ] } @@ -16393,7 +16929,10 @@ " it('Remove fields from the Findings DataTable')", " it('Reset fields to default')", " describe('Findings Page - support muting rules')", - " it(`verify only enabled rules appears`)" + " it(`verify only enabled rules appears`)", + " describe('Access with custom roles')", + " it('Access with valid user role')", + " it('Access with invalid user role')" ], "testSuits": [ { @@ -16565,6 +17104,36 @@ "type": "it", "isSkipped": false, "isTodo": false + }, + { + "id": "access-with-custom-roles", + "rawLine": " describe('Access with custom roles', async () => {", + "line": " describe('Access with custom roles')", + "label": "Access with custom roles", + "indent": 4, + "type": "describe", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-valid-user-role", + "rawLine": " it('Access with valid user role', async () => {", + "line": " it('Access with valid user role')", + "label": "Access with valid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-invalid-user-role", + "rawLine": " it('Access with invalid user role', async () => {", + "line": " it('Access with invalid user role')", + "label": "Access with invalid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false } ], "tree": [ @@ -16751,6 +17320,38 @@ "isTodo": false } ] + }, + { + "id": "access-with-custom-roles", + "rawLine": " describe('Access with custom roles', async () => {", + "line": " describe('Access with custom roles')", + "label": "Access with custom roles", + "indent": 4, + "type": "describe", + "isSkipped": false, + "isTodo": false, + "children": [ + { + "id": "access-with-valid-user-role", + "rawLine": " it('Access with valid user role', async () => {", + "line": " it('Access with valid user role')", + "label": "Access with valid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false + }, + { + "id": "access-with-invalid-user-role", + "rawLine": " it('Access with invalid user role', async () => {", + "line": " it('Access with invalid user role')", + "label": "Access with invalid user role", + "indent": 6, + "type": "it", + "isSkipped": false, + "isTodo": false + } + ] } ] }, diff --git a/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts b/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts index 6697dbdbbea56..556ab0c7c830c 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts @@ -16,7 +16,7 @@ const LATEST_FINDINGS_TRANSFORM_V830 = 'cloud_security_posture.findings_latest-d const LATEST_FINDINGS_TRANSFORM_V840 = 'cloud_security_posture.findings_latest-default-8.4.0'; const LATEST_FINDINGS_TRANSFORM_V880 = 'cloud_security_posture.findings_latest-default-8.8.0'; -const CURRENT_FINDINGS_TRANSFORM = 'cloud_security_posture.findings_latest-default-8.15.0'; +const CURRENT_FINDINGS_TRANSFORM_VERSION = 'cloud_security_posture.findings_latest-default-8.15.0'; export const DEPRECATED_FINDINGS_TRANSFORMS_VERSION = [ LATEST_FINDINGS_TRANSFORM_V830, @@ -25,7 +25,7 @@ export const DEPRECATED_FINDINGS_TRANSFORMS_VERSION = [ ]; export const latestFindingsTransform: TransformPutTransformRequest = { - transform_id: CURRENT_FINDINGS_TRANSFORM, + transform_id: CURRENT_FINDINGS_TRANSFORM_VERSION, description: 'Defines findings transformation to view only the latest finding per resource', source: { index: FINDINGS_INDEX_PATTERN, diff --git a/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_vulnerabilities_transforms.ts b/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_vulnerabilities_transforms.ts index 2be5cf6072cf6..c7cd2dd0921f7 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_vulnerabilities_transforms.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_vulnerabilities_transforms.ts @@ -13,14 +13,15 @@ import { VULNERABILITIES_INDEX_PATTERN, } from '../../common/constants'; -const CURRENT_VULN_VERSION = 'cloud_security_posture.vulnerabilities_latest-default-8.15.0'; +const CURRENT_VULN_TRANSFORM_VERSION = + 'cloud_security_posture.vulnerabilities_latest-default-8.15.0'; export const DEPRECATED_VULN_TRANSFORM_VERSIONS = [ 'cloud_security_posture.vulnerabilities_latest-default-8.8.0', ]; export const latestVulnerabilitiesTransform: TransformPutTransformRequest = { - transform_id: CURRENT_VULN_VERSION, + transform_id: CURRENT_VULN_TRANSFORM_VERSION, description: 'Defines vulnerabilities transformation to view only the latest vulnerability per resource', source: { diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/benchmark_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/benchmark_page.ts new file mode 100644 index 0000000000000..39856fa34d3fb --- /dev/null +++ b/x-pack/test/cloud_security_posture_functional/page_objects/benchmark_page.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 expect from '@kbn/expect'; +import { + ELASTIC_HTTP_VERSION_HEADER, + X_ELASTIC_INTERNAL_ORIGIN_REQUEST, +} from '@kbn/core-http-common'; +import type { FtrProviderContext } from '../ftr_provider_context'; + +export const CSP_BECNHMARK_TABLE = 'csp_benchmarks_table'; + +export function BenchmarkPagePageProvider({ getService, getPageObjects }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['common', 'header']); + const retry = getService('retry'); + const supertest = getService('supertest'); + const log = getService('log'); + + /** + * required before indexing findings + */ + const waitForPluginInitialized = (): Promise => + retry.try(async () => { + log.debug('Check CSP plugin is initialized'); + const response = await supertest + .get('/internal/cloud_security_posture/status?check=init') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .expect(200); + expect(response.body).to.eql({ isPluginInitialized: true }); + log.debug('CSP plugin is initialized'); + }); + + const benchmarkPage = { + doesBenchmarkTableExists: async () => { + return await testSubjects.find('csp_benchmarks_table'); + }, + }; + + const navigateToBenchnmarkPage = async () => { + await PageObjects.common.navigateToUrl( + 'securitySolution', // Defined in Security Solution plugin + `cloud_security_posture/benchmarks/`, + { shouldUseHashForSubUrl: false } + ); + await PageObjects.header.waitUntilLoadingHasFinished(); + }; + + return { + waitForPluginInitialized, + navigateToBenchnmarkPage, + benchmarkPage, + }; +} diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts index bc1ae63cea51e..17cd9f581c6be 100644 --- a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts +++ b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts @@ -337,6 +337,10 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider return trueOrFalse; }; + const getUnprivilegedPrompt = async () => { + return await testSubjects.find('status-api-unprivileged'); + }; + return { navigateToLatestFindingsPage, navigateToLatestVulnerabilitiesPage, @@ -356,5 +360,6 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider findingsGrouping, createDataTableObject, isLatestFindingsTableThere, + getUnprivilegedPrompt, }; } diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/index.ts b/x-pack/test/cloud_security_posture_functional/page_objects/index.ts index 020341fdd811b..704f6310cdbb2 100644 --- a/x-pack/test/cloud_security_posture_functional/page_objects/index.ts +++ b/x-pack/test/cloud_security_posture_functional/page_objects/index.ts @@ -10,6 +10,8 @@ import { FindingsPageProvider } from './findings_page'; import { CspDashboardPageProvider } from './csp_dashboard_page'; import { AddCisIntegrationFormPageProvider } from './add_cis_integration_form_page'; import { VulnerabilityDashboardPageProvider } from './vulnerability_dashboard_page_object'; +import { BenchmarkPagePageProvider } from './benchmark_page'; +import { CspSecurityCommonProvider } from './security_common'; import { RulePagePageProvider } from './rule_page'; export const cloudSecurityPosturePageObjects = { @@ -18,6 +20,8 @@ export const cloudSecurityPosturePageObjects = { cisAddIntegration: AddCisIntegrationFormPageProvider, vulnerabilityDashboard: VulnerabilityDashboardPageProvider, rule: RulePagePageProvider, + benchmark: BenchmarkPagePageProvider, + cspSecurity: CspSecurityCommonProvider, }; export const pageObjects = { ...xpackFunctionalPageObjects, diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/security_common.ts b/x-pack/test/cloud_security_posture_functional/page_objects/security_common.ts new file mode 100644 index 0000000000000..4d5baaa6a2ff9 --- /dev/null +++ b/x-pack/test/cloud_security_posture_functional/page_objects/security_common.ts @@ -0,0 +1,128 @@ +/* + * 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 { FtrProviderContext } from '../ftr_provider_context'; + +export function CspSecurityCommonProvider({ getPageObjects, getService }: FtrProviderContext) { + const security = getService('security'); + const pageObjects = getPageObjects(['security']); + + const roles = [ + { + name: 'csp_viewer', + elasticsearch: { + indices: [ + { + names: ['logs-cloud_security_posture.findings-*'], + privileges: ['read'], + }, + { + names: ['logs-cloud_security_posture.findings_latest-*'], + privileges: ['read'], + }, + { + names: ['logs-cloud_security_posture.scores-*'], + privileges: ['read'], + }, + ], + }, + kibana: [ + { + base: ['all'], + spaces: ['*'], + }, + ], + }, + { + name: 'missing_access_findings_latest_role', + elasticsearch: { + indices: [ + { + names: ['logs-cloud_security_posture.findings-*'], + privileges: ['read'], + }, + { + names: ['logs-cloud_security_posture.scores-*'], + privileges: ['read'], + }, + ], + }, + kibana: [ + { + base: ['all'], + spaces: ['*'], + }, + ], + }, + ]; + + const users = [ + { + name: 'csp_read_user', + full_name: 'csp viewer', + password: 'test123', + roles: ['csp_viewer'], + }, + { + name: 'csp_missing_latest_findings_access_user', + full_name: 'missing latest findings index access', + password: 'csp123', + roles: ['missing_access_findings_latest_role'], + }, + ]; + + return { + async createRoles() { + for (const role of roles) { + await security.role.create(role.name, { + elasticsearch: role.elasticsearch, + kibana: role.kibana, + }); + } + }, + + async createUsers() { + for (const user of users) { + await security.user.create(user.name, { + password: user.password, + roles: user.roles, + full_name: user.full_name, + }); + } + }, + + async login(user: string) { + await pageObjects.security.login(user, this.getPasswordForUser(user), { + expectSpaceSelector: false, + }); + }, + + async logout() { + await pageObjects.security.forceLogout(); + }, + + async cleanRoles() { + for (const role of roles) { + await security.role.delete(role.name); + } + }, + + async cleanUsers() { + for (const user of users) { + await security.user.delete(user.name); + } + }, + + getPasswordForUser(user: string): string { + const userConfig = users.find((u) => u.name === user); + if (userConfig === undefined) { + throw new Error(`Can't log in user ${user} - not defined`); + } + return userConfig.password; + }, + }; +} diff --git a/x-pack/test/cloud_security_posture_functional/pages/benchmark.ts b/x-pack/test/cloud_security_posture_functional/pages/benchmark.ts new file mode 100644 index 0000000000000..7eca494108e87 --- /dev/null +++ b/x-pack/test/cloud_security_posture_functional/pages/benchmark.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { k8sFindingsMock } from '../mocks/latest_findings_mock'; +import type { FtrProviderContext } from '../ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const kibanaServer = getService('kibanaServer'); + const pageObjects = getPageObjects([ + 'common', + 'cspSecurity', + 'cloudPostureDashboard', + 'rule', + 'benchmark', + 'findings', + ]); + + describe('Access with custom roles', async () => { + let cspSecurity = pageObjects.cspSecurity; + let rule: typeof pageObjects.rule; + let benchmark: typeof pageObjects.benchmark; + let findings: typeof pageObjects.findings; + + before(async () => { + benchmark = pageObjects.benchmark; + cspSecurity = pageObjects.cspSecurity; + await benchmark.waitForPluginInitialized(); + await kibanaServer.savedObjects.clean({ + types: ['cloud-security-posture-settings'], + }); + }); + + // Blocked by https://github.com/elastic/kibana/issues/184621 + it.skip('Access with valid user role', async () => { + await cspSecurity.logout(); + await cspSecurity.login('csp_read_user'); + await benchmark.navigateToBenchnmarkPage(); + expect(await benchmark.benchmarkPage.doesBenchmarkTableExists()); + }); + + // Blocked by https://github.com/elastic/kibana/issues/184621 + it.skip('Access with invalid user role', async () => {}); + + // The entire describe block bellow should move to rule.ts byt the page test is blocked by: + // FLAKY: https://github.com/elastic/kibana/issues/178413 + describe('Access with custom roles - rule page', async () => { + before(async () => { + findings = pageObjects.findings; + rule = pageObjects.rule; + await findings.index.add(k8sFindingsMock); + }); + after(async () => { + await findings.index.remove(); + }); + + afterEach(async () => { + // force logout to prevent the next test from failing + await cspSecurity.logout(); + }); + + it('Access with valid user role', async () => { + await cspSecurity.logout(); + await cspSecurity.login('csp_read_user'); + await rule.navigateToRulePage('cis_k8s', '1.0.1'); + + expect(await rule.rulePage.toggleBulkActionButton()); + }); + + // Blocked by https://github.com/elastic/kibana/issues/184621 + it.skip('Access with invalid user role', async () => {}); + }); + }); +} diff --git a/x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts b/x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts index 3faaa849c537c..6d824df8ef4c4 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/compliance_dashboard.ts @@ -12,7 +12,7 @@ import type { FtrProviderContext } from '../ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function ({ getPageObjects, getService }: FtrProviderContext) { const retry = getService('retry'); - const pageObjects = getPageObjects(['common', 'cloudPostureDashboard', 'header']); + const pageObjects = getPageObjects(['common', 'cspSecurity', 'cloudPostureDashboard', 'header']); const chance = new Chance(); const data = [ @@ -36,10 +36,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { this.tags(['cloud_security_posture_compliance_dashboard']); let cspDashboard: typeof pageObjects.cloudPostureDashboard; let dashboard: typeof pageObjects.cloudPostureDashboard.dashboard; + let cspSecurity = pageObjects.cspSecurity; before(async () => { cspDashboard = pageObjects.cloudPostureDashboard; dashboard = pageObjects.cloudPostureDashboard.dashboard; + cspSecurity = pageObjects.cspSecurity; + await cspDashboard.waitForPluginInitialized(); await cspDashboard.index.add(data); @@ -66,5 +69,27 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // describe('TODO - Cloud Dashboard', () => { // it('todo - displays accurate summary compliance score', async () => {}); // }); + + describe('Access with custom roles', async () => { + this.afterEach(async () => { + // force logout to prevent the next test from failing + await cspSecurity.logout(); + }); + it('Access with valid user role', async () => { + await cspSecurity.logout(); + await cspSecurity.login('csp_read_user'); + await cspDashboard.navigateToComplianceDashboardPage(); + await retry.waitFor( + 'Cloud posture integration dashboard to be displayed', + async () => !!dashboard.getIntegrationDashboardContainer() + ); + const scoreElement = await dashboard.getKubernetesComplianceScore(); + + expect((await scoreElement.getVisibleText()) === '0%').to.be(true); // based on the ingested findings + }); + + // Blocked by https://github.com/elastic/kibana/issues/184621 + it.skip('todo - Access with invalid user role', async () => {}); + }); }); } diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings.ts b/x-pack/test/cloud_security_posture_functional/pages/findings.ts index f599648d0c2de..6819da2a03e09 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/findings.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/findings.ts @@ -23,7 +23,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const retry = getService('retry'); const supertest = getService('supertest'); const kibanaServer = getService('kibanaServer'); - const pageObjects = getPageObjects(['common', 'findings', 'header']); + const pageObjects = getPageObjects(['common', 'cspSecurity', 'findings', 'header']); const chance = new Chance(); const timeFiveHoursAgo = (Date.now() - 18000000).toString(); @@ -120,6 +120,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { let findings: typeof pageObjects.findings; let latestFindingsTable: typeof findings.latestFindingsTable; let distributionBar: typeof findings.distributionBar; + let cspSecurity = pageObjects.cspSecurity; beforeEach(async () => { await kibanaServer.savedObjects.clean({ @@ -129,6 +130,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { findings = pageObjects.findings; latestFindingsTable = findings.latestFindingsTable; distributionBar = findings.distributionBar; + cspSecurity = pageObjects.cspSecurity; // Before we start any test we must wait for cloud_security_posture plugin to complete its initialization await findings.waitForPluginInitialized(); @@ -391,5 +393,30 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(await latestFindingsTable.getFindingsCount('passed')).to.eql(passedFindingsCount); }); }); + + describe('Access with custom roles', async () => { + this.afterEach(async () => { + // force logout to prevent the next test from failing + await cspSecurity.logout(); + }); + + it('Access with valid user role', async () => { + await cspSecurity.logout(); + await cspSecurity.login('csp_read_user'); + await findings.navigateToLatestFindingsPage(); + pageObjects.header.waitUntilLoadingHasFinished(); + expect(await latestFindingsTable.getRowsCount()).to.be.greaterThan(0); + }); + + it('Access with invalid user role', async () => { + await cspSecurity.logout(); + await cspSecurity.login('csp_missing_latest_findings_access_user'); + + await findings.navigateToLatestFindingsPage(); + + pageObjects.header.waitUntilLoadingHasFinished(); + expect(await findings.getUnprivilegedPrompt()); + }); + }); }); } diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts b/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts index a7f36230bb1a5..ff77372b5ed23 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/findings_grouping.ts @@ -158,6 +158,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); after(async () => { + await findings.navigateToLatestFindingsPage(); + await pageObjects.header.waitUntilLoadingHasFinished(); const groupSelector = await findings.groupSelector(); await groupSelector.openDropDown(); await groupSelector.setValue('None'); diff --git a/x-pack/test/cloud_security_posture_functional/pages/index.ts b/x-pack/test/cloud_security_posture_functional/pages/index.ts index a1f9177f05c08..1edf38dc41ec9 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/index.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/index.ts @@ -8,8 +8,17 @@ import { FtrProviderContext } from '../ftr_provider_context'; // eslint-disable-next-line import/no-default-export -export default function ({ loadTestFile }: FtrProviderContext) { +export default function ({ getPageObjects, loadTestFile }: FtrProviderContext) { + const pageObjects = getPageObjects(['cspSecurity']); describe('Cloud Security Posture', function () { + let cspSecurity = pageObjects.cspSecurity; + + before(async () => { + cspSecurity = pageObjects.cspSecurity; + await cspSecurity.createRoles(); + await cspSecurity.createUsers(); + }); + loadTestFile(require.resolve('./rules')); loadTestFile(require.resolve('./findings_onboarding')); loadTestFile(require.resolve('./findings')); @@ -26,5 +35,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./findings_old_data')); loadTestFile(require.resolve('./vulnerabilities')); loadTestFile(require.resolve('./vulnerabilities_grouping')); + loadTestFile(require.resolve('./benchmark')); }); } From 4b5b00f6c631f376deae7024281ecd044de7d32c Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 6 Jun 2024 13:27:05 +0200 Subject: [PATCH 034/122] [security-in-core] flag APIs as deprecated (#184827) ## Summary Part of https://github.com/elastic/kibana/issues/174578 Flag as deprecated the APIs from the security plugin that are now re-exposed from Core --- x-pack/packages/security/plugin_types_public/src/plugin.ts | 6 ++++++ x-pack/packages/security/plugin_types_server/src/plugin.ts | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/x-pack/packages/security/plugin_types_public/src/plugin.ts b/x-pack/packages/security/plugin_types_public/src/plugin.ts index 672be02cf38d4..06f3574388a36 100644 --- a/x-pack/packages/security/plugin_types_public/src/plugin.ts +++ b/x-pack/packages/security/plugin_types_public/src/plugin.ts @@ -14,6 +14,8 @@ import type { UserProfileAPIClient } from './user_profile'; export interface SecurityPluginSetup { /** * Exposes authentication information about the currently logged in user. + * + * @deprecated in favor of Core's `security` service */ authc: AuthenticationServiceSetup; /** @@ -33,6 +35,8 @@ export interface SecurityPluginStart { navControlService: SecurityNavControlServiceStart; /** * Exposes authentication information about the currently logged in user. + * + * @deprecated in favor of Core's `security` service */ authc: AuthenticationServiceStart; /** @@ -41,6 +45,8 @@ export interface SecurityPluginStart { authz: AuthorizationServiceStart; /** * A set of methods to work with Kibana user profiles. + * + * @deprecated in favor of Core's `userProfile` service. */ userProfiles: UserProfileAPIClient; } diff --git a/x-pack/packages/security/plugin_types_server/src/plugin.ts b/x-pack/packages/security/plugin_types_server/src/plugin.ts index d3ee046c2d0cd..c8222163785bf 100644 --- a/x-pack/packages/security/plugin_types_server/src/plugin.ts +++ b/x-pack/packages/security/plugin_types_server/src/plugin.ts @@ -21,6 +21,8 @@ export interface SecurityPluginSetup { license: SecurityLicense; /** * Exposes services for audit logging. + * + * @deprecated in favor of Core's `security` service */ audit: AuditServiceSetup; /** @@ -35,6 +37,8 @@ export interface SecurityPluginSetup { export interface SecurityPluginStart { /** * Authentication services to confirm the user is who they say they are. + * + * @deprecated in favor of Core's `security` service */ authc: AuthenticationServiceStart; /** @@ -43,6 +47,8 @@ export interface SecurityPluginStart { authz: AuthorizationServiceSetup; /** * User profiles services to retrieve user profiles. + * + * @deprecated in favor of Core's `userProfile` service */ userProfiles: UserProfileServiceStart; } From 4ac05a265c9f3fccaac9028d33ef6416d35bfe1b Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 6 Jun 2024 13:34:12 +0200 Subject: [PATCH 035/122] [TableListView] Persist table sorting (#184667) ## Summary Close https://github.com/elastic/kibana/issues/175457 Persist table sorting option. Memory is separate per table (e.g. different for dashboard/visualization) --- .../src/components/index.ts | 2 +- .../src/components/table_sort_select.tsx | 37 ++++++++++++++++ .../table_list_view_table/src/reducer.tsx | 9 +--- .../src/table_list_view.test.tsx | 28 ++++++++++++- .../src/table_list_view_table.tsx | 42 +++++++++++-------- 5 files changed, 90 insertions(+), 28 deletions(-) diff --git a/packages/content-management/table_list_view_table/src/components/index.ts b/packages/content-management/table_list_view_table/src/components/index.ts index a4a09a5e6bbc6..0448fb90ecb4b 100644 --- a/packages/content-management/table_list_view_table/src/components/index.ts +++ b/packages/content-management/table_list_view_table/src/components/index.ts @@ -14,4 +14,4 @@ export { ItemDetails } from './item_details'; export { TableSortSelect } from './table_sort_select'; export { TagFilterPanel } from './tag_filter_panel'; -export type { SortColumnField } from './table_sort_select'; +export { type SortColumnField, getInitialSorting, saveSorting } from './table_sort_select'; diff --git a/packages/content-management/table_list_view_table/src/components/table_sort_select.tsx b/packages/content-management/table_list_view_table/src/components/table_sort_select.tsx index 9140c8ac3bc32..c9e06a29e9c8c 100644 --- a/packages/content-management/table_list_view_table/src/components/table_sort_select.tsx +++ b/packages/content-management/table_list_view_table/src/components/table_sort_select.tsx @@ -177,3 +177,40 @@ export function TableSortSelect({ tableSort, hasUpdatedAtMetadata, onChange }: P ); } + +const sortStorageKey = (tableId: string) => `tableSort:${tableId}`; +export function getInitialSorting(tableId: string): { + isDefault: boolean; + tableSort: { + field: SortColumnField; + direction: Direction; + }; +} { + try { + const storedSorting = localStorage.getItem(sortStorageKey(tableId)); + if (storedSorting) { + const tableSort = JSON.parse(storedSorting); + return { isDefault: false, tableSort }; + } + } catch (e) { + // ignore + } + + return { + isDefault: true, + tableSort: { + field: 'attributes.title' as const, + direction: 'asc', + }, + }; +} +export function saveSorting( + tableId: string, + tableSort: { field: SortColumnField; direction: Direction } +) { + try { + localStorage.setItem(sortStorageKey(tableId), JSON.stringify(tableSort)); + } catch (e) { + /* empty */ + } +} diff --git a/packages/content-management/table_list_view_table/src/reducer.tsx b/packages/content-management/table_list_view_table/src/reducer.tsx index e96f8fc394347..b4cf3691f9d75 100644 --- a/packages/content-management/table_list_view_table/src/reducer.tsx +++ b/packages/content-management/table_list_view_table/src/reducer.tsx @@ -11,8 +11,6 @@ import type { State } from './table_list_view_table'; import type { Action } from './actions'; export function getReducer() { - let sortColumnChanged = false; - return (state: State, action: Action): State => { switch (action.type) { case 'onFetchItems': { @@ -35,7 +33,7 @@ export function getReducer() { // Only change the table sort if it hasn't been changed already. // For example if its state comes from the URL, we don't want to override it here. - if (hasUpdatedAtMetadata && !sortColumnChanged) { + if (hasUpdatedAtMetadata && !state.sortColumnChanged) { tableSort = { field: 'updatedAt' as const, direction: 'desc' as const, @@ -89,10 +87,6 @@ export function getReducer() { }; } case 'onTableChange': { - if (action.data.sort) { - sortColumnChanged = true; - } - const tableSort = action.data.sort ?? state.tableSort; const pageIndex = action.data.page?.pageIndex ?? state.pagination.pageIndex; const pageSize = action.data.page?.pageSize ?? state.pagination.pageSize; @@ -109,6 +103,7 @@ export function getReducer() { }, tableSort, tableFilter, + sortColumnChanged: state.sortColumnChanged || Boolean(action.data.sort), }; } case 'showConfirmDeleteItemsModal': { diff --git a/packages/content-management/table_list_view_table/src/table_list_view.test.tsx b/packages/content-management/table_list_view_table/src/table_list_view.test.tsx index ce7ed6aa0bf80..c874747799480 100644 --- a/packages/content-management/table_list_view_table/src/table_list_view.test.tsx +++ b/packages/content-management/table_list_view_table/src/table_list_view.test.tsx @@ -72,6 +72,10 @@ describe('TableListView', () => { jest.useFakeTimers({ legacyFakeTimers: true }); }); + beforeEach(() => { + localStorage.clear(); + }); + afterAll(() => { jest.useRealTimers(); }); @@ -506,7 +510,7 @@ describe('TableListView', () => { ]); }); - test('filter select should change the sort order', async () => { + test('filter select should change the sort order and remember the order', async () => { let testBed: TestBed; await act(async () => { @@ -515,7 +519,7 @@ describe('TableListView', () => { }); }); - const { component, table, find } = testBed!; + let { component, table, find } = testBed!; const { openSortSelect } = getActions(testBed!); component.update(); @@ -544,6 +548,26 @@ describe('TableListView', () => { ['z-foo', twoDaysAgoToString], ['a-foo', yesterdayToString], ]); + + expect(localStorage.getItem('tableSort:test')).toBe( + '{"field":"attributes.title","direction":"desc"}' + ); + + component.unmount(); + await act(async () => { + testBed = await setupColumnSorting({ + findItems: jest.fn().mockResolvedValue({ total: hits.length, hits }), + }); + }); + + ({ component, table, find } = testBed!); + component.update(); + ({ tableCellsValues } = table.getMetaData('itemsInMemTable')); + + expect(tableCellsValues).toEqual([ + ['z-foo', twoDaysAgoToString], + ['a-foo', yesterdayToString], + ]); }); test('should update the select option when toggling the column header', async () => { diff --git a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx index 3c5051850cdd3..1053123e80191 100644 --- a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx +++ b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx @@ -43,7 +43,7 @@ import { import { useServices } from './services'; import type { SavedObjectsFindOptionsReference } from './services'; import { getReducer } from './reducer'; -import type { SortColumnField } from './components'; +import { type SortColumnField, getInitialSorting, saveSorting } from './components'; import { useTags } from './use_tags'; import { useInRouterContext, useUrlState } from './use_url_state'; import { RowActions, TableItemsRowActions } from './types'; @@ -144,6 +144,7 @@ export interface State({ return getReducer(); }, []); - const initialState = useMemo>( - () => ({ + const initialState = useMemo>(() => { + const initialSort = getInitialSorting(entityName); + return { items: [], hasNoItems: undefined, totalItems: 0, @@ -373,16 +375,13 @@ function TableListViewTableComp({ pageSize: initialPageSize, pageSizeOptions: uniq([10, 20, 50, initialPageSize]).sort(), }, - tableSort: { - field: 'attributes.title' as const, - direction: 'asc', - }, + tableSort: initialSort.tableSort, + sortColumnChanged: !initialSort.isDefault, tableFilter: { createdBy: [], }, - }), - [initialPageSize] - ); + }; + }, [initialPageSize, entityName]); const [state, dispatch] = useReducer(reducer, initialState); @@ -597,7 +596,7 @@ function TableListViewTableComp({ ), sortable: true, - width: '150px', + width: '120px', }); } @@ -660,7 +659,7 @@ function TableListViewTableComp({ name: i18n.translate('contentManagement.tableList.listing.table.actionTitle', { defaultMessage: 'Actions', }), - width: '100px', + width: `${32 * actions.length}px`, actions, }); } @@ -795,14 +794,18 @@ function TableListViewTableComp({ const onSortChange = useCallback( (field: SortColumnField, direction: Direction) => { + const sort = { + field, + direction, + }; + // persist the sorting changes caused by explicit user's interaction + saveSorting(entityName, sort); + updateTableSortFilterAndPagination({ - sort: { - field, - direction, - }, + sort, }); }, - [updateTableSortFilterAndPagination] + [entityName, updateTableSortFilterAndPagination] ); const onFilterChange = useCallback( @@ -838,6 +841,9 @@ function TableListViewTableComp({ field: fieldSerialized as SortColumnField, direction: criteria.sort.direction, }; + + // persist the sorting changes caused by explicit user's interaction + saveSorting(entityName, data.sort); } data.page = { @@ -847,7 +853,7 @@ function TableListViewTableComp({ updateTableSortFilterAndPagination(data); }, - [updateTableSortFilterAndPagination] + [updateTableSortFilterAndPagination, entityName] ); const deleteSelectedItems = useCallback(async () => { From 22155aefdc97180c1cc208cdd35a92dceefdd5bf Mon Sep 17 00:00:00 2001 From: Miriam <31922082+MiriamAparicio@users.noreply.github.com> Date: Thu, 6 Jun 2024 12:59:29 +0100 Subject: [PATCH 036/122] [ObsUX] [Infra] Add missing metrics to Docker container view (#184245) Closes https://github.com/elastic/kibana/issues/183354 Metric section ![image](https://github.com/elastic/kibana/assets/31922082/0d85da8b-a651-4557-ac09-e3eee2573c42) How to test - The feature is under a FF, on inventory page go to settings and enable Container view - In containers inventory, select a docker container, you find one, filter by any `docker.` field. Click on a container. - Container details page should be shown Network and DiskIO charts, as well as CPU and Memory, on Metrics section --- .../src/lib/infra/docker_container.ts | 8 +++ .../components/kpis/container_kpi_charts.tsx | 11 ++-- .../use_container_metrics_charts.test.ts | 4 ++ .../hooks/use_container_metrics_charts.ts | 6 ++- .../hooks/use_integration_check.ts | 2 +- .../overview/metrics/container_metrics.tsx | 24 ++++++--- .../container/metrics/charts/disk.ts | 50 +++++++++++++++++++ .../container/metrics/charts/index.ts | 4 ++ .../container/metrics/charts/network.ts | 47 +++++++++++++++++ .../container/metrics/formulas/disk.ts | 25 ++++++++++ .../container/metrics/formulas/index.ts | 6 +++ .../container/metrics/formulas/network.ts | 27 ++++++++++ .../host/metrics/charts/network.ts | 11 ++-- .../shared/charts/constants.ts | 8 +++ .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - .../test/functional/apps/infra/home_page.ts | 4 +- .../functional/apps/infra/node_details.ts | 2 +- 19 files changed, 217 insertions(+), 28 deletions(-) create mode 100644 x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/disk.ts create mode 100644 x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/network.ts create mode 100644 x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/disk.ts create mode 100644 x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/network.ts diff --git a/packages/kbn-apm-synthtrace-client/src/lib/infra/docker_container.ts b/packages/kbn-apm-synthtrace-client/src/lib/infra/docker_container.ts index 03f72ee61bc06..b0dab3da9dabb 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/infra/docker_container.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/infra/docker_container.ts @@ -21,6 +21,10 @@ export class DockerContainer extends Entity { ...this.fields, 'docker.cpu.total.pct': 25, 'docker.memory.usage.pct': 20, + 'docker.network.inbound.bytes': 100, + 'docker.network.outbound.bytes': 200, + 'docker.diskio.read.ops': 10, + 'docker.diskio.write.ops': 20, }); } } @@ -28,6 +32,10 @@ export class DockerContainer extends Entity { export interface DockerContainerMetricsDocument extends DockerContainerDocument { 'docker.cpu.total.pct': number; 'docker.memory.usage.pct': number; + 'docker.network.inbound.bytes': number; + 'docker.network.outbound.bytes': number; + 'docker.diskio.read.ops': number; + 'docker.diskio.write.ops': number; } class DockerContainerMetrics extends Serializable {} diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/components/kpis/container_kpi_charts.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/components/kpis/container_kpi_charts.tsx index 8e4a67526f72c..ca7f3e3787c46 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/components/kpis/container_kpi_charts.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/components/kpis/container_kpi_charts.tsx @@ -38,9 +38,14 @@ export const ContainerKpiCharts = ({ searchSessionId, loading = false, }: ContainerKpiChartsProps) => { - const isK8Container = useIntegrationCheck({ dependsOn: INTEGRATIONS.kubernetesContainer }); - - return isK8Container ? ( + const isDockerContainer = useIntegrationCheck({ dependsOn: INTEGRATIONS.docker }); + const isKubernetesContainer = useIntegrationCheck({ + dependsOn: INTEGRATIONS.kubernetesContainer, + }); + if (!isDockerContainer && !isKubernetesContainer) { + return null; + } + return isKubernetesContainer ? ( { const model = findInventoryModel('container'); - const { cpu, memory } = await model.metrics.getCharts(); + const { cpu, memory, network, diskIO } = await model.metrics.getCharts(); switch (metric) { case 'cpu': return [cpu.xy.dockerContainerCpuUsage]; case 'memory': return [memory.xy.dockerContainerMemoryUsage]; + case 'network': + return [network.xy.dockerContainerRxTx]; + case 'disk': + return [diskIO.xy.dockerContainerDiskIOReadWrite]; default: return []; } diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_integration_check.ts b/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_integration_check.ts index 000fee4705828..231cd2fdef8ff 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_integration_check.ts +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_integration_check.ts @@ -12,7 +12,7 @@ export const useIntegrationCheck = ({ dependsOn }: { dependsOn: string }) => { const { metadata } = useMetadataStateContext(); const hasIntegration = useMemo( - () => (metadata?.features ?? []).some((f) => f.name === dependsOn), + () => (metadata?.features ?? []).some((f) => f.name.startsWith(dependsOn)), [metadata?.features, dependsOn] ); diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/metrics/container_metrics.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/metrics/container_metrics.tsx index f14619005eadb..abe14d6d5807a 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/metrics/container_metrics.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/metrics/container_metrics.tsx @@ -20,20 +20,30 @@ interface Props { } export const ContainerMetrics = (props: Props) => { - const isK8sContainer = useIntegrationCheck({ dependsOn: INTEGRATIONS.kubernetesContainer }); + const isDockerContainer = useIntegrationCheck({ dependsOn: INTEGRATIONS.docker }); + const isKubernetesContainer = useIntegrationCheck({ + dependsOn: INTEGRATIONS.kubernetesContainer, + }); + + if (!isDockerContainer && !isKubernetesContainer) { + return null; + } return ( - {isK8sContainer ? ( - <> - - - - ) : ( + {isDockerContainer && ( <> + + + + )} + {!isDockerContainer && isKubernetesContainer && ( + <> + + )} diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/disk.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/disk.ts new file mode 100644 index 0000000000000..b3dcc2860ccae --- /dev/null +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/disk.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 { i18n } from '@kbn/i18n'; +import { LensConfigWithId } from '../../../types'; +import { formulas } from '../formulas'; +import { + DEFAULT_XY_FITTING_FUNCTION, + DEFAULT_XY_HIDDEN_AXIS_TITLE, + DEFAULT_XY_LEGEND, + DISK_IOPS_LABEL, +} from '../../../shared/charts/constants'; + +const dockerContainerDiskIOReadWrite: LensConfigWithId = { + id: 'diskIOReadWrite', + chartType: 'xy', + title: DISK_IOPS_LABEL, + layers: [ + { + seriesType: 'area', + type: 'series', + xAxis: '@timestamp', + yAxis: [ + { + ...formulas.dockerContainerDiskIORead, + label: i18n.translate('xpack.metricsData.assetDetails.metricsCharts.metric.label.read', { + defaultMessage: 'Read', + }), + }, + { + ...formulas.dockerContainerDiskIOWrite, + label: i18n.translate('xpack.metricsData.assetDetails.metricsCharts.metric.label.write', { + defaultMessage: 'Write', + }), + }, + ], + }, + ], + ...DEFAULT_XY_FITTING_FUNCTION, + ...DEFAULT_XY_LEGEND, + ...DEFAULT_XY_HIDDEN_AXIS_TITLE, +}; + +export const diskIO = { + xy: { dockerContainerDiskIOReadWrite }, +}; diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/index.ts index 6a83e00c9c5c8..f050a16c57ed4 100644 --- a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/index.ts +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/index.ts @@ -7,10 +7,14 @@ import { cpu } from './cpu'; import { memory } from './memory'; +import { network } from './network'; +import { diskIO } from './disk'; export const charts = { cpu, memory, + network, + diskIO, } as const; export type ContainerCharts = typeof charts; diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/network.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/network.ts new file mode 100644 index 0000000000000..29cc757d77279 --- /dev/null +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/charts/network.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + DEFAULT_XY_FITTING_FUNCTION, + DEFAULT_XY_HIDDEN_AXIS_TITLE, + DEFAULT_XY_LEGEND, + NETWORK_LABEL, + RX_LABEL, + TX_LABEL, +} from '../../../shared/charts/constants'; +import { LensConfigWithId } from '../../../types'; +import { formulas } from '../formulas'; + +const dockerContainerRxTx: LensConfigWithId = { + id: 'rxTx', + chartType: 'xy', + title: NETWORK_LABEL, + layers: [ + { + seriesType: 'area', + type: 'series', + xAxis: '@timestamp', + yAxis: [ + { + ...formulas.dockerContainerNetworkRx, + label: RX_LABEL, + }, + { + ...formulas.dockerContainerNetworkTx, + label: TX_LABEL, + }, + ], + }, + ], + ...DEFAULT_XY_FITTING_FUNCTION, + ...DEFAULT_XY_LEGEND, + ...DEFAULT_XY_HIDDEN_AXIS_TITLE, +}; + +export const network = { + xy: { dockerContainerRxTx }, +}; diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/disk.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/disk.ts new file mode 100644 index 0000000000000..ba0050bad97aa --- /dev/null +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/disk.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 type { LensBaseLayer } from '@kbn/lens-embeddable-utils/config_builder'; +import { DISK_READ_IOPS_LABEL, DISK_WRITE_IOPS_LABEL } from '../../../shared/charts/constants'; + +export const dockerContainerDiskIORead: LensBaseLayer = { + label: DISK_READ_IOPS_LABEL, + value: "counter_rate(max(docker.diskio.read.ops), kql='docker.diskio.read.ops: *')", + format: 'number', + decimals: 0, + normalizeByUnit: 's', +}; + +export const dockerContainerDiskIOWrite: LensBaseLayer = { + label: DISK_WRITE_IOPS_LABEL, + value: "counter_rate(max(docker.diskio.write.ops), kql='docker.diskio.write.ops: *')", + format: 'number', + decimals: 0, + normalizeByUnit: 's', +}; diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/index.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/index.ts index 2f5e4f7975f7a..5a878b048179a 100644 --- a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/index.ts +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/index.ts @@ -6,11 +6,17 @@ */ import { dockerContainerCpuUsage, k8sContainerCpuUsage } from './cpu'; +import { dockerContainerDiskIORead, dockerContainerDiskIOWrite } from './disk'; import { dockerContainerMemoryUsage, k8sContainerMemoryUsage } from './memory'; +import { dockerContainerNetworkRx, dockerContainerNetworkTx } from './network'; export const formulas = { dockerContainerCpuUsage, dockerContainerMemoryUsage, + dockerContainerNetworkRx, + dockerContainerNetworkTx, + dockerContainerDiskIORead, + dockerContainerDiskIOWrite, k8sContainerCpuUsage, k8sContainerMemoryUsage, } as const; diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/network.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/network.ts new file mode 100644 index 0000000000000..6c6600fc6463f --- /dev/null +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/container/metrics/formulas/network.ts @@ -0,0 +1,27 @@ +/* + * 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 { LensBaseLayer } from '@kbn/lens-embeddable-utils/config_builder'; +import { RX_LABEL, TX_LABEL } from '../../../shared/charts/constants'; + +export const dockerContainerNetworkRx: LensBaseLayer = { + label: RX_LABEL, + value: + "average(docker.network.inbound.bytes) * 8 / (max(metricset.period, kql='docker.network.inbound.bytes: *') / 1000)", + format: 'bits', + decimals: 1, + normalizeByUnit: 's', +}; + +export const dockerContainerNetworkTx: LensBaseLayer = { + label: TX_LABEL, + value: + "average(docker.network.outbound.bytes) * 8 / (max(metricset.period, kql='docker.network.outbound.bytes: *') / 1000)", + format: 'bits', + decimals: 1, + normalizeByUnit: 's', +}; diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts index d94dd48db8370..d166870f5bb4b 100644 --- a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/host/metrics/charts/network.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; import { LensConfigWithId } from '../../../types'; import { formulas } from '../formulas'; import { @@ -14,6 +13,8 @@ import { DEFAULT_XY_HIDDEN_LEGEND, DEFAULT_XY_LEGEND, NETWORK_LABEL, + RX_LABEL, + TX_LABEL, } from '../../../shared/charts/constants'; const rxTx: LensConfigWithId = { @@ -28,15 +29,11 @@ const rxTx: LensConfigWithId = { yAxis: [ { ...formulas.rx, - label: i18n.translate('xpack.metricsData.assetDetails.metricsCharts.network.label.rx', { - defaultMessage: 'Inbound (RX)', - }), + label: RX_LABEL, }, { ...formulas.tx, - label: i18n.translate('xpack.metricsData.assetDetails.metricsCharts.network.label.tx', { - defaultMessage: 'Outbound (TX)', - }), + label: TX_LABEL, }, ], }, diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/charts/constants.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/charts/constants.ts index 6d6d22c116f43..fb59022803331 100644 --- a/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/charts/constants.ts +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/inventory_models/shared/charts/constants.ts @@ -170,3 +170,11 @@ export const NETWORK_LABEL = i18n.translate( defaultMessage: 'Network', } ); + +export const RX_LABEL = i18n.translate('xpack.metricsData.assetDetails.metrics.label.networkRx', { + defaultMessage: 'Inbound (RX)', +}); + +export const TX_LABEL = i18n.translate('xpack.metricsData.assetDetails.metrics.label.networkTx', { + defaultMessage: 'Outbound (TX)', +}); diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 71c86aac906ce..6c6d4c4648945 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -44747,8 +44747,6 @@ "xpack.metricsData.assetDetails.metricsCharts.metric.label.read": "Lire", "xpack.metricsData.assetDetails.metricsCharts.metric.label.used": "Utilisé", "xpack.metricsData.assetDetails.metricsCharts.metric.label.write": "Écrire", - "xpack.metricsData.assetDetails.metricsCharts.network.label.rx": "Entrant (RX)", - "xpack.metricsData.assetDetails.metricsCharts.network.label.tx": "Sortant (TX)", "xpack.metricsData.hostsPage.goToMetricsSettings": "Vérifier les paramètres", "xpack.metricsData.inventoryModel.container.displayName": "Conteneurs Docker", "xpack.metricsData.inventoryModel.container.singularDisplayName": "Conteneur Docker", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 75a83002c3a40..a527c1302b66a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -44719,8 +44719,6 @@ "xpack.metricsData.assetDetails.metricsCharts.metric.label.read": "読み取り", "xpack.metricsData.assetDetails.metricsCharts.metric.label.used": "使用中", "xpack.metricsData.assetDetails.metricsCharts.metric.label.write": "書き込み", - "xpack.metricsData.assetDetails.metricsCharts.network.label.rx": "受信(RX)", - "xpack.metricsData.assetDetails.metricsCharts.network.label.tx": "送信(TX)", "xpack.metricsData.hostsPage.goToMetricsSettings": "設定を確認", "xpack.metricsData.inventoryModel.container.displayName": "Dockerコンテナー", "xpack.metricsData.inventoryModel.container.singularDisplayName": "Docker コンテナー", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 56d67e46ade68..482bbca9941e6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -44767,8 +44767,6 @@ "xpack.metricsData.assetDetails.metricsCharts.metric.label.read": "读取", "xpack.metricsData.assetDetails.metricsCharts.metric.label.used": "已使用", "xpack.metricsData.assetDetails.metricsCharts.metric.label.write": "写入", - "xpack.metricsData.assetDetails.metricsCharts.network.label.rx": "入站 (RX)", - "xpack.metricsData.assetDetails.metricsCharts.network.label.tx": "出站 (TX)", "xpack.metricsData.hostsPage.goToMetricsSettings": "检查设置", "xpack.metricsData.inventoryModel.container.displayName": "Docker 容器", "xpack.metricsData.inventoryModel.container.singularDisplayName": "Docker 容器", diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts index f1de6350b084f..e197715aadedf 100644 --- a/x-pack/test/functional/apps/infra/home_page.ts +++ b/x-pack/test/functional/apps/infra/home_page.ts @@ -295,7 +295,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { { metric: 'cpuUsage', value: '2,500.0%' }, { metric: 'memoryUsage', value: '2,000.0%' }, ].forEach(({ metric, value }) => { - it(`${metric} tile should show ${value}`, async () => { + it.skip(`${metric} tile should show ${value}`, async () => { await retry.tryForTime(3 * 1000, async () => { const tileValue = await pageObjects.assetDetails.getAssetDetailsKPITileValue( metric @@ -309,7 +309,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { { metric: 'cpu', chartsCount: 1 }, { metric: 'memory', chartsCount: 1 }, ].forEach(({ metric, chartsCount }) => { - it(`should render ${chartsCount} ${metric} chart(s) in the Metrics section`, async () => { + it.skip(`should render ${chartsCount} ${metric} chart(s) in the Metrics section`, async () => { const containers = await pageObjects.assetDetails.getOverviewTabDockerMetricCharts( metric ); diff --git a/x-pack/test/functional/apps/infra/node_details.ts b/x-pack/test/functional/apps/infra/node_details.ts index 47792ec4bb2ba..4318644c81bb5 100644 --- a/x-pack/test/functional/apps/infra/node_details.ts +++ b/x-pack/test/functional/apps/infra/node_details.ts @@ -663,7 +663,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { { metric: 'cpu', chartsCount: 1 }, { metric: 'memory', chartsCount: 1 }, ].forEach(({ metric, chartsCount }) => { - it(`should render ${chartsCount} ${metric} chart(s) in the Metrics section`, async () => { + it.skip(`should render ${chartsCount} ${metric} chart(s) in the Metrics section`, async () => { const charts = await pageObjects.assetDetails.getOverviewTabDockerMetricCharts( metric ); From b4561e7c3e08817dc3d1c01499ee1f4303c8de11 Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Thu, 6 Jun 2024 14:30:38 +0200 Subject: [PATCH 037/122] [Security Solution] Change risk scoring sum max and simplify risk score calculations (#184638) ## Summary * Update the `RISK_SCORING_SUM_MAX` to the appropriate value based 10.000 alerts (read more on the original issue) * The following risk scoring engine lines can be simplified by no longer multiplying by 100, and instead using the value above directly. I also renamed the constants to improve reliability, I rounded `2.592375848672986` up to `2.5924` so the calculated score won't go above `100`. For `10.000` alerts with a risk score of `100` each the calculated risk score is `99.99906837960884` Risk score calculation for 10_00 alerts with 100 risk score ![Screenshot 2024-06-03 at 11 56 48](https://github.com/elastic/kibana/assets/1490444/00c876ea-388b-4322-b8f8-19fc65f9f833) Risk score calculation for 1_000 alerts with 100 risk score ![Screenshot 2024-06-03 at 11 57 29](https://github.com/elastic/kibana/assets/1490444/929746c2-19e9-4da1-b4b1-c6e56edfc77c) ### User Impact The entity's calculated risk score will slightly increase because we update the normalisation divisor from 261.2 to 2.5924. ### 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 --- .../asset_criticality/helpers.test.ts | 41 +---------- .../asset_criticality/helpers.ts | 19 ------ .../risk_score/calculate_risk_scores.ts | 17 ++--- .../entity_analytics/risk_score/constants.ts | 31 +++++++-- .../risk_score/painless/index.test.ts | 2 +- .../painless/risk_scoring_reduce.painless | 4 +- .../risk_score_calculation.ts | 8 +-- .../risk_score_entity_calculation.ts | 8 +-- .../risk_score_preview.ts | 68 +++++++++---------- .../risk_scoring_task/task_execution.ts | 4 +- 10 files changed, 79 insertions(+), 123 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.test.ts index 9ec395223c937..4c818c4d067e4 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { applyCriticalityToScore, normalize } from './helpers'; +import { applyCriticalityToScore } from './helpers'; describe('applyCriticalityToScore', () => { describe('integer scores', () => { @@ -61,42 +61,3 @@ describe('applyCriticalityToScore', () => { }); }); }); - -describe('normalize', () => { - it('returns 0 if the number is equal to the min', () => { - const result = normalize({ number: 0, min: 0, max: 100 }); - expect(result).toEqual(0); - }); - - it('returns 100 if the number is equal to the max', () => { - const result = normalize({ number: 100, min: 0, max: 100 }); - expect(result).toEqual(100); - }); - - it('returns 50 if the number is halfway between the min and max', () => { - const result = normalize({ number: 50, min: 0, max: 100 }); - expect(result).toEqual(50); - }); - - it('defaults to a min of 0', () => { - const result = normalize({ number: 50, max: 100 }); - expect(result).toEqual(50); - }); - - describe('when the domain is diffrent than the range', () => { - it('returns 0 if the number is equal to the min', () => { - const result = normalize({ number: 20, min: 20, max: 200 }); - expect(result).toEqual(0); - }); - - it('returns 100 if the number is equal to the max', () => { - const result = normalize({ number: 40, min: 30, max: 40 }); - expect(result).toEqual(100); - }); - - it('returns 50 if the number is halfway between the min and max', () => { - const result = normalize({ number: 20, min: 0, max: 40 }); - expect(result).toEqual(50); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.ts index 137f4763c4c38..3b3330d0d6536 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/helpers.ts @@ -65,22 +65,3 @@ export const bayesianUpdate = ({ const newProbability = priorProbability * modifier; return (max * newProbability) / (1 + newProbability); }; - -/** - * Normalizes a number to the range [0, 100] - * - * @param number - The number to be normalized - * @param min - The minimum possible value of the number. Defaults to 0. - * @param max - The maximum possible value of the number - * - * @returns The updated score with modifiers applied - */ -export const normalize = ({ - number, - min = 0, - max, -}: { - number: number; - min?: number; - max: number; -}) => ((number - min) / (max - min)) * 100; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/calculate_risk_scores.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/calculate_risk_scores.ts index 9f99a9ae4a561..27ef27b80070b 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/calculate_risk_scores.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/calculate_risk_scores.ts @@ -30,18 +30,14 @@ import { import { withSecuritySpan } from '../../../utils/with_security_span'; import type { AssetCriticalityRecord } from '../../../../common/api/entity_analytics'; import type { AssetCriticalityService } from '../asset_criticality/asset_criticality_service'; -import { - applyCriticalityToScore, - getCriticalityModifier, - normalize, -} from '../asset_criticality/helpers'; +import { applyCriticalityToScore, getCriticalityModifier } from '../asset_criticality/helpers'; import { getAfterKeyForIdentifierType, getFieldForIdentifier } from './helpers'; import type { CalculateRiskScoreAggregations, CalculateScoresParams, RiskScoreBucket, } from '../types'; -import { RISK_SCORING_SUM_MAX, RISK_SCORING_SUM_VALUE } from './constants'; +import { RIEMANN_ZETA_VALUE, RIEMANN_ZETA_S_VALUE } from './constants'; import { getPainlessScripts, type PainlessScripts } from './painless'; const formatForResponse = ({ @@ -82,10 +78,7 @@ const formatForResponse = ({ calculated_level: calculatedLevel, calculated_score: riskDetails.value.score, calculated_score_norm: normalizedScoreWithCriticality, - category_1_score: normalize({ - number: riskDetails.value.category_1_score, - max: RISK_SCORING_SUM_MAX, - }), + category_1_score: riskDetails.value.category_1_score / RIEMANN_ZETA_VALUE, // normalize value to be between 0-100 category_1_count: riskDetails.value.category_1_count, notes: riskDetails.value.notes, inputs: riskDetails.value.risk_inputs.map((riskInput) => ({ @@ -150,8 +143,8 @@ const buildIdentifierTypeAggregation = ({ map_script: scriptedMetricPainless.map, combine_script: scriptedMetricPainless.combine, params: { - p: RISK_SCORING_SUM_VALUE, - risk_cap: RISK_SCORING_SUM_MAX, + p: RIEMANN_ZETA_S_VALUE, + risk_cap: RIEMANN_ZETA_VALUE, global_identifier_type_weight: globalIdentifierTypeWeight || 1, }, reduce_script: scriptedMetricPainless.reduce, diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/constants.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/constants.ts index 6a691eac42734..5f008ebf3d796 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/constants.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/constants.ts @@ -6,15 +6,36 @@ */ /** - * The risk scoring algorithm uses a Riemann zeta function to sum an entity's risk inputs to a known, finite value (@see RISK_SCORING_SUM_MAX). It does so by assigning each input a weight based on its position in the list (ordered by score) of inputs. This value represents the complex variable s of Re(s) in traditional Riemann zeta function notation. + * The risk scoring algorithm uses a Riemann zeta function to sum an entity's risk inputs to a known, finite value (@see RIEMANN_ZETA_VALUE). + * It does so by assigning each input a weight based on its position in the list (ordered by score) of inputs. + * This value represents the complex variable s of Re(s) in traditional Riemann zeta function notation. + * + * Read more: https://en.wikipedia.org/wiki/Riemann_zeta_function */ -export const RISK_SCORING_SUM_VALUE = 1.5; +export const RIEMANN_ZETA_S_VALUE = 1.5; /** - * Represents the maximum possible risk score sum. This value is derived from RISK_SCORING_SUM_VALUE, but we store the precomputed value here to be used more conveniently in normalization. - * @see RISK_SCORING_SUM_VALUE + * Represents the value calculated by Riemann Zeta function for RIEMANN_ZETA_S_VALUE with 10.000 iterations (inputs) which is the default alertSampleSizePerShard. + * The maximum unnormalized risk score value is calculated by multiplying RIEMANN_ZETA_S_VALUE by the maximum alert risk_score (100). + * + * This value is derived from RIEMANN_ZETA_S_VALUE, but we store the precomputed value here to be used more conveniently in normalization. @see RIEMANN_ZETA_S_VALUE + * + * The Riemann Zeta value for different number of inputs is: + * | 𝑍(s,inputs) | + * | :---------------------------------------| + * | 𝑍(1.5,10)≈1.9953364933456017 | + * | 𝑍(1.5,100)≈2.412874098703719 | + * | 𝑍(1.5,1000)≈2.5491456029175756 | + * | 𝑍(1.5,10_000)≈2.5923758486729866 | + * | 𝑍(1.5,100_000)≈2.6060508091764736 | + * | 𝑍(1.5,1_000_000)≈2.6103753491852295 | + * | 𝑍(1.5,10_000_000)≈2.611742893169012 | + * | 𝑍(1.5,100_000_000)≈2.6121753486854478 | + * | 𝑍(1.5,1_000_000_000)≈2.6123121030481857 | + * + * Read more: https://en.wikipedia.org/wiki/Riemann_zeta_function */ -export const RISK_SCORING_SUM_MAX = 261.2; +export const RIEMANN_ZETA_VALUE = 2.5924; /** * This value represents the maximum possible risk score after normalization. diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/index.test.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/index.test.ts index e21a6afeff326..5d25cf38761fe 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/index.test.ts @@ -17,7 +17,7 @@ describe('getPainlessScripts', () => { "combine": "return state;", "init": "state.inputs = []", "map": "Map fields = new HashMap();fields.put('id', doc['kibana.alert.uuid'].value);fields.put('index', doc['_index'].value);fields.put('time', doc['@timestamp'].value);fields.put('rule_name', doc['kibana.alert.rule.name'].value);fields.put('category', doc['event.kind'].value);fields.put('score', doc['kibana.alert.risk_score'].value);state.inputs.add(fields); ", - "reduce": "Map results = new HashMap();results['notes'] = [];results['category_1_score'] = 0.0;results['category_1_count'] = 0;results['risk_inputs'] = [];results['score'] = 0.0;def inputs = states[0].inputs;Collections.sort(inputs, (a, b) -> b.get('score').compareTo(a.get('score')));for (int i = 0; i < inputs.length; i++) { double current_score = inputs[i].score / Math.pow(i + 1, params.p); if (i < 10) { inputs[i][\\"contribution\\"] = 100 * current_score / params.risk_cap; results['risk_inputs'].add(inputs[i]); } results['category_1_score'] += current_score; results['category_1_count'] += 1; results['score'] += current_score;}results['score'] *= params.global_identifier_type_weight;results['normalized_score'] = 100 * results['score'] / params.risk_cap;return results;", + "reduce": "Map results = new HashMap();results['notes'] = [];results['category_1_score'] = 0.0;results['category_1_count'] = 0;results['risk_inputs'] = [];results['score'] = 0.0;def inputs = states[0].inputs;Collections.sort(inputs, (a, b) -> b.get('score').compareTo(a.get('score')));for (int i = 0; i < inputs.length; i++) { double current_score = inputs[i].score / Math.pow(i + 1, params.p); if (i < 10) { inputs[i]['contribution'] = current_score / params.risk_cap; results['risk_inputs'].add(inputs[i]); } results['category_1_score'] += current_score; results['category_1_count'] += 1; results['score'] += current_score;}results['score'] *= params.global_identifier_type_weight;results['normalized_score'] = results['score'] / params.risk_cap;return results;", } `); }); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/risk_scoring_reduce.painless b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/risk_scoring_reduce.painless index 629a925522590..69295bf07330c 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/risk_scoring_reduce.painless +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_score/painless/risk_scoring_reduce.painless @@ -22,7 +22,7 @@ for (int i = 0; i < inputs.length; i++) { double current_score = inputs[i].score / Math.pow(i + 1, params.p); if (i < 10) { - inputs[i]["contribution"] = 100 * current_score / params.risk_cap; + inputs[i]['contribution'] = current_score / params.risk_cap; results['risk_inputs'].add(inputs[i]); } @@ -36,6 +36,6 @@ for (int i = 0; i < inputs.length; i++) { } results['score'] *= params.global_identifier_type_weight; -results['normalized_score'] = 100 * results['score'] / params.risk_cap; +results['normalized_score'] = results['score'] / params.risk_cap; return results; diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_calculation.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_calculation.ts index 1dd6b0f9e5766..29451ef9dacbe 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_calculation.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_calculation.ts @@ -138,8 +138,8 @@ export default ({ getService }: FtrProviderContext): void => { expect(score).to.eql({ calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 8.039816232771823, - category_1_score: 8.039816232771821, + calculated_score_norm: 8.10060175898781, + category_1_score: 8.10060175898781, category_1_count: 1, id_field: 'host.name', id_value: 'host-1', @@ -353,8 +353,8 @@ export default ({ getService }: FtrProviderContext): void => { criticality_modifier: 1.5, calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 11.59366948840633, - category_1_score: 8.039816232771821, + calculated_score_norm: 11.677912063468526, + category_1_score: 8.10060175898781, category_1_count: 1, id_field: 'host.name', id_value: 'host-1', diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_entity_calculation.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_entity_calculation.ts index e3ddfbbda4ef2..2f7b7d44898c1 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_entity_calculation.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_entity_calculation.ts @@ -126,8 +126,8 @@ export default ({ getService }: FtrProviderContext): void => { const expectedScore = { calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 8.039816232771823, - category_1_score: 8.039816232771821, + calculated_score_norm: 8.10060175898781, + category_1_score: 8.10060175898781, category_1_count: 1, id_field: 'host.name', id_value: 'host-1', @@ -176,8 +176,8 @@ export default ({ getService }: FtrProviderContext): void => { criticality_modifier: 1.5, calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 11.59366948840633, - category_1_score: 8.039816232771821, + calculated_score_norm: 11.677912063468526, + category_1_score: 8.10060175898781, category_1_count: 1, id_field: 'host.name', id_value: 'host-1', diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_preview.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_preview.ts index 28ebe8dae5f56..dfd7efe8d6583 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_preview.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_score_preview.ts @@ -116,9 +116,9 @@ export default ({ getService }: FtrProviderContext): void => { expect(score).to.eql({ calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 8.039816232771823, + calculated_score_norm: 8.10060175898781, category_1_count: 1, - category_1_score: 8.039816232771821, + category_1_score: 8.10060175898781, id_field: 'host.name', id_value: 'host-1', }); @@ -144,18 +144,18 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 8.039816232771823, + calculated_score_norm: 8.10060175898781, category_1_count: 1, - category_1_score: 8.039816232771821, + category_1_score: 8.10060175898781, id_field: 'host.name', id_value: 'host-1', }, { calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 8.039816232771823, + calculated_score_norm: 8.10060175898781, category_1_count: 1, - category_1_score: 8.039816232771821, + category_1_score: 8.10060175898781, id_field: 'host.name', id_value: 'host-2', }, @@ -177,9 +177,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Unknown', calculated_score: 28.42462120245875, - calculated_score_norm: 10.88232052161514, + calculated_score_norm: 10.964596976723788, category_1_count: 2, - category_1_score: 10.882320521615142, + category_1_score: 10.964596976723788, id_field: 'host.name', id_value: 'host-1', }, @@ -199,9 +199,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Unknown', calculated_score: 47.25513506055279, - calculated_score_norm: 18.091552473412246, + calculated_score_norm: 18.228334771081926, category_1_count: 30, - category_1_score: 18.091552473412246, + category_1_score: 18.228334771081926, id_field: 'host.name', id_value: 'host-1', }, @@ -224,18 +224,18 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Unknown', calculated_score: 47.25513506055279, - calculated_score_norm: 18.091552473412246, + calculated_score_norm: 18.228334771081926, category_1_count: 30, - category_1_score: 18.091552473412246, + category_1_score: 18.228334771081926, id_field: 'host.name', id_value: 'host-1', }, { calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 8.039816232771823, + calculated_score_norm: 8.10060175898781, category_1_count: 1, - category_1_score: 8.039816232771821, + category_1_score: 8.10060175898781, id_field: 'host.name', id_value: 'host-2', }, @@ -255,9 +255,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Unknown', calculated_score: 50.67035607277805, - calculated_score_norm: 19.399064346392823, + calculated_score_norm: 19.545732168175455, category_1_count: 100, - category_1_score: 19.399064346392823, + category_1_score: 19.545732168175455, id_field: 'host.name', id_value: 'host-1', }, @@ -280,9 +280,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Critical', calculated_score: 241.2874098703716, - calculated_score_norm: 92.37649688758484, + calculated_score_norm: 93.07491508654975, category_1_count: 100, - category_1_score: 92.37649688758484, + category_1_score: 93.07491508654975, id_field: 'host.name', id_value: 'host-1', }, @@ -311,9 +311,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Critical', calculated_score: 254.91456029175757, - calculated_score_norm: 97.59362951445543, + calculated_score_norm: 98.33149216623883, category_1_count: 1000, - category_1_score: 97.59362951445543, + category_1_score: 98.33149216623883, id_field: 'host.name', id_value: 'host-1', }, @@ -407,9 +407,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'High', calculated_score: 225.1106801442913, - calculated_score_norm: 86.18326192354185, + calculated_score_norm: 86.83485578779946, category_1_count: 100, - category_1_score: 86.18326192354185, + category_1_score: 86.83485578779946, id_field: 'host.name', id_value: 'host-1', }, @@ -436,9 +436,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Moderate', calculated_score: 120.6437049351858, - calculated_score_norm: 46.18824844379242, + calculated_score_norm: 46.537457543274876, category_1_count: 100, - category_1_score: 92.37649688758484, + category_1_score: 93.07491508654975, id_field: 'host.name', id_value: 'host-1', }, @@ -463,9 +463,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Moderate', calculated_score: 168.9011869092601, - calculated_score_norm: 64.66354782130938, + calculated_score_norm: 65.15244056058482, category_1_count: 100, - category_1_score: 92.37649688758484, + category_1_score: 93.07491508654975, id_field: 'user.name', id_value: 'user-1', }, @@ -492,9 +492,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'Low', calculated_score: 93.23759116471251, - calculated_score_norm: 35.695861854790394, + calculated_score_norm: 35.96574261869793, category_1_count: 50, - category_1_score: 89.23965463697598, + category_1_score: 89.91435654674481, id_field: 'host.name', id_value: 'host-1', }, @@ -504,9 +504,9 @@ export default ({ getService }: FtrProviderContext): void => { { calculated_level: 'High', calculated_score: 186.47518232942502, - calculated_score_norm: 71.39172370958079, + calculated_score_norm: 71.93148523739586, category_1_count: 50, - category_1_score: 89.23965463697598, + category_1_score: 89.91435654674481, id_field: 'user.name', id_value: 'user-1', }, @@ -547,18 +547,18 @@ export default ({ getService }: FtrProviderContext): void => { criticality_modifier: 2.0, calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 14.8830616583983, + calculated_score_norm: 14.987153868113044, category_1_count: 1, - category_1_score: 8.039816232771821, + category_1_score: 8.10060175898781, id_field: 'host.name', id_value: 'host-1', }, { calculated_level: 'Unknown', calculated_score: 21, - calculated_score_norm: 8.039816232771823, + calculated_score_norm: 8.10060175898781, category_1_count: 1, - category_1_score: 8.039816232771821, + category_1_score: 8.10060175898781, id_field: 'host.name', id_value: 'host-2', }, diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_scoring_task/task_execution.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_scoring_task/task_execution.ts index bcdcd9085a7c1..d53ffc707b396 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_scoring_task/task_execution.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_scoring_task/task_execution.ts @@ -274,9 +274,9 @@ export default ({ getService }: FtrProviderContext): void => { criticality_modifier: 2, calculated_level: 'Moderate', calculated_score: 79.81345973382406, - calculated_score_norm: 46.809565696393314, + calculated_score_norm: 47.08016240063269, category_1_count: 10, - category_1_score: 30.55645472198471, + category_1_score: 30.787478681462762, }, ]); }); From 78b31bbeaf75ce99b374d11e3917eddeadc7e932 Mon Sep 17 00:00:00 2001 From: Rickyanto Ang Date: Thu, 6 Jun 2024 05:52:30 -0700 Subject: [PATCH 038/122] [Cloud Security][Quick Wins] Fix for Rules Flyout (#184050) ## Summary Part of Quick Wins, fix for Rules Flyout closing when user clicks on Toaster/Pop up https://github.com/elastic/kibana/assets/8703149/a0d2e7ed-daff-46fd-973e-c268b950e72f --- .../cloud_security_posture/public/pages/rules/rules_flyout.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx index 3777646917e4a..2301a4a8ebcfe 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx @@ -99,7 +99,6 @@ export const RuleFlyout = ({ onClose, rule }: RuleFlyoutProps) => { return ( Date: Thu, 6 Jun 2024 15:10:15 +0200 Subject: [PATCH 039/122] [Security Solution] `DetectionRulesClient`: move public methods out and add APM spans (#184820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Partially addresses: https://github.com/elastic/kibana/issues/184364** ## Summary This PR is second step in refactoring our newly added `detectionRulesClient`. Changes in this PR: - every public method was extracted into its own file for readability - `_createRule`, `_updateRule`, `_patchRule` and `_upgradePrebuiltRuleWithTypeChange` private methods were removed, their code inlined into the public methods - `toggleRuleEnabledOnUpdate`, `validateMlAuth` and `ClientError` were moved to `utils.ts` - methods are now wrapped in `withSecuritySpan` to report perf stats to APM - renamed `*.rules_management_client.test.ts` -> `*.detection_rules_client.test.ts` - now using the whole `detectionRulesClient` in tests, not just separate methods - simplified parameters of `createDetectionRulesClient`. Now 2 parameters are needed instead of 5, **DetectionRulesClient method showing up in APM** Scherm­afbeelding 2024-06-05 om 14 00 36 **Extracted methods** Upon reviewing the private methods in `detection_rules_client.ts`, it became apparent that extracting these methods into separate files may not be the most effective approach to improve readability. The primary reason is that these private methods do not provide clear abstractions, making them difficult to name appropriately. Take `_updateRule` as an example. This method combines an existing rule with a rule update to create an InternalRuleUpdate object, which is then passed to `rulesClient.update`. If we were to extract this into a separate file, we would need to import it for use in the public `updateRule` method. This would result in an `updateRule` method that calls `_updateRule`, creating confusion about what the inner `_updateRule` does. Also, extracting only private methods does not significantly improve readability, as these methods do not contain a large amount of code. So I ended up inlining the code from most of these private methods directly into the public methods. --- .../__mocks__/detection_rules_client.ts | 47 +- ...ustom_rule.detection_rules_client.test.ts} | 56 +-- .../rule_management/create_custom_rule.ts | 36 ++ ...built_rule.detection_rules_client.test.ts} | 53 +-- .../rule_management/create_prebuilt_rule.ts | 41 ++ ...elete_rule.detection_rules_client.test.ts} | 12 +- .../logic/rule_management/delete_rule.ts | 23 + .../rule_management/detection_rules_client.ts | 442 ++---------------- ...mport_rule.detection_rules_client.test.ts} | 81 ++-- .../logic/rule_management/import_rule.ts | 75 +++ ...patch_rule.detection_rules_client.test.ts} | 24 +- .../logic/rule_management/patch_rule.ts | 60 +++ ...pdate_rule.detection_rules_client.test.ts} | 2 +- .../logic/rule_management/update_rule.ts | 59 +++ ...built_rule.detection_rules_client.test.ts} | 18 +- .../rule_management/upgrade_prebuilt_rule.ts | 90 ++++ .../logic/rule_management/utils.ts | 38 ++ .../server/lib/machine_learning/authz.ts | 2 +- .../server/request_context_factory.ts | 20 +- 19 files changed, 587 insertions(+), 592 deletions(-) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/{create_custom_rule.rule_management_client.test.ts => create_custom_rule.detection_rules_client.test.ts} (76%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/{create_prebuilt_rule.rule_management_client.test.ts => create_prebuilt_rule.detection_rules_client.test.ts} (81%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/{delete_rule.rule_management_client.test.ts => delete_rule.detection_rules_client.test.ts} (60%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/{import_rule.rule_management_client.test.ts => import_rule.detection_rules_client.test.ts} (83%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/{patch_rule.rule_management_client.test.ts => patch_rule.detection_rules_client.test.ts} (90%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/{update_rule.rule_management_client.test.ts => update_rule.detection_rules_client.test.ts} (99%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/{upgrade_prebuilt_rule.rule_management_client.test.ts => upgrade_prebuilt_rule.detection_rules_client.test.ts} (88%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/utils.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/detection_rules_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/detection_rules_client.ts index d320cfbe5315a..2411de933fb1f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/detection_rules_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/detection_rules_client.ts @@ -5,19 +5,7 @@ * 2.0. */ -import type { - IDetectionRulesClient, - CreateRuleOptions, - _UpdateRuleProps, - _PatchRuleProps, -} from '../detection_rules_client'; -import type { RulesClient } from '@kbn/alerting-plugin/server'; -import type { - RuleCreateProps, - RuleObjectId, -} from '../../../../../../../common/api/detection_engine'; -import type { PrebuiltRuleAsset } from '../../../../prebuilt_rules'; -import type { RuleAlertType } from '../../../../rule_schema'; +import type { IDetectionRulesClient } from '../detection_rules_client'; export type DetectionRulesClientMock = jest.Mocked; @@ -39,36 +27,3 @@ export const detectionRulesClientMock: { } = { create: createDetectionRulesClientMock, }; - -/* Mocks for internal methods */ -export const _createRule: jest.Mock< - ( - rulesClient: RulesClient, - params: RuleCreateProps, - options: CreateRuleOptions - ) => Promise -> = jest.fn(); - -export const _updateRule: jest.Mock< - (rulesClient: RulesClient, updateRulePayload: _UpdateRuleProps) => Promise -> = jest.fn(); - -export const patchRuleMock: jest.Mock< - (rulesClient: RulesClient, patchRulePayload: _PatchRuleProps) => Promise -> = jest.fn(); - -export const _upgradePrebuiltRuleWithTypeChange: jest.Mock< - ( - rulesClient: RulesClient, - ruleAsset: PrebuiltRuleAsset, - existingRule: RuleAlertType - ) => Promise -> = jest.fn(); - -export const _toggleRuleEnabledOnUpdate: jest.Mock< - (rulesClient: RulesClient, existingRule: RuleAlertType, enabled: boolean) => Promise -> = jest.fn(); - -export const _deleteRule: jest.Mock< - (rulesClient: RulesClient, deleteRulePayload: { ruleId: RuleObjectId }) => Promise -> = jest.fn(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.rule_management_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.detection_rules_client.test.ts similarity index 76% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.rule_management_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.detection_rules_client.test.ts index 7cf68102d6a83..6053d5109676c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.rule_management_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.detection_rules_client.test.ts @@ -7,8 +7,6 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { createCustomRule } from './detection_rules_client'; - import { getCreateRulesSchemaMock, getCreateMachineLearningRulesSchemaMock, @@ -17,23 +15,28 @@ import { import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../../common/constants'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; +import { createDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); describe('DetectionRulesClient.createCustomRule', () => { let rulesClient: ReturnType; + let detectionRulesClient: IDetectionRulesClient; + const mlAuthz = (buildMlAuthz as jest.Mock)(); beforeEach(() => { jest.resetAllMocks(); rulesClient = rulesClientMock.create(); + detectionRulesClient = createDetectionRulesClient(rulesClient, mlAuthz); }); it('should create a rule with the correct parameters and options', async () => { const params = getCreateRulesSchemaMock(); - await createCustomRule(rulesClient, { params }, mlAuthz); + await detectionRulesClient.createCustomRule({ params }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -44,8 +47,6 @@ describe('DetectionRulesClient.createCustomRule', () => { immutable: false, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); @@ -56,18 +57,16 @@ describe('DetectionRulesClient.createCustomRule', () => { }); await expect( - createCustomRule(rulesClient, { params: getCreateMachineLearningRulesSchemaMock() }, mlAuthz) + detectionRulesClient.createCustomRule({ params: getCreateMachineLearningRulesSchemaMock() }) ).rejects.toThrow('mocked MLAuth error'); expect(rulesClient.create).not.toHaveBeenCalled(); }); it('calls the rulesClient with legacy ML params', async () => { - await createCustomRule( - rulesClient, - { params: getCreateMachineLearningRulesSchemaMock() }, - mlAuthz - ); + await detectionRulesClient.createCustomRule({ + params: getCreateMachineLearningRulesSchemaMock(), + }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -78,23 +77,17 @@ describe('DetectionRulesClient.createCustomRule', () => { immutable: false, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); it('calls the rulesClient with ML params', async () => { - await createCustomRule( - rulesClient, - { - params: { - ...getCreateMachineLearningRulesSchemaMock(), - machine_learning_job_id: ['new_job_1', 'new_job_2'], - }, + await detectionRulesClient.createCustomRule({ + params: { + ...getCreateMachineLearningRulesSchemaMock(), + machine_learning_job_id: ['new_job_1', 'new_job_2'], }, - mlAuthz - ); + }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -105,8 +98,6 @@ describe('DetectionRulesClient.createCustomRule', () => { immutable: false, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); @@ -115,13 +106,9 @@ describe('DetectionRulesClient.createCustomRule', () => { const params = getCreateThreatMatchRulesSchemaMock(); delete params.threat_indicator_path; - await createCustomRule( - rulesClient, - { - params, - }, - mlAuthz - ); + await detectionRulesClient.createCustomRule({ + params, + }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -131,14 +118,13 @@ describe('DetectionRulesClient.createCustomRule', () => { immutable: false, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); it('does not populate a threatIndicatorPath value for other rules if empty', async () => { - await createCustomRule(rulesClient, { params: getCreateRulesSchemaMock() }, mlAuthz); + await detectionRulesClient.createCustomRule({ params: getCreateRulesSchemaMock() }); + expect(rulesClient.create).not.toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ @@ -147,8 +133,6 @@ describe('DetectionRulesClient.createCustomRule', () => { immutable: false, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.ts new file mode 100644 index 0000000000000..c8951d5ff4a65 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.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 type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { RuleCreateProps } from '../../../../../../common/api/detection_engine'; +import type { MlAuthz } from '../../../../machine_learning/authz'; +import type { RuleAlertType, RuleParams } from '../../../rule_schema'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import { convertCreateAPIToInternalSchema } from '../../normalization/rule_converters'; + +import { validateMlAuth } from './utils'; + +export interface CreateCustomRuleProps { + params: RuleCreateProps; +} + +export const createCustomRule = async ( + rulesClient: RulesClient, + createCustomRulePayload: CreateCustomRuleProps, + mlAuthz: MlAuthz +): Promise => + withSecuritySpan('DetectionRulesClient.createCustomRule', async () => { + const { params } = createCustomRulePayload; + await validateMlAuth(mlAuthz, params.type); + + const internalRule = convertCreateAPIToInternalSchema(params, { immutable: false }); + const rule = await rulesClient.create({ + data: internalRule, + }); + + return rule; + }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.rule_management_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.detection_rules_client.test.ts similarity index 81% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.rule_management_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.detection_rules_client.test.ts index b99f94344332f..c6d80ad412dc5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.rule_management_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.detection_rules_client.test.ts @@ -7,8 +7,6 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { createPrebuiltRule } from './detection_rules_client'; - import { getCreateRulesSchemaMock, getCreateMachineLearningRulesSchemaMock, @@ -17,23 +15,28 @@ import { import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../../common/constants'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; +import { createDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); describe('DetectionRulesClient.createPrebuiltRule', () => { let rulesClient: ReturnType; + let detectionRulesClient: IDetectionRulesClient; + const mlAuthz = (buildMlAuthz as jest.Mock)(); beforeEach(() => { jest.resetAllMocks(); rulesClient = rulesClientMock.create(); + detectionRulesClient = createDetectionRulesClient(rulesClient, mlAuthz); }); it('creates a rule with the correct parameters and options', async () => { const ruleAsset = { ...getCreateRulesSchemaMock(), version: 1, rule_id: 'rule-id' }; - await createPrebuiltRule(rulesClient, { ruleAsset }, mlAuthz); + await detectionRulesClient.createPrebuiltRule({ ruleAsset }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -45,8 +48,6 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { immutable: true, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); @@ -57,7 +58,7 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { throw new Error('mocked MLAuth error'); }); - await expect(createPrebuiltRule(rulesClient, { ruleAsset }, mlAuthz)).rejects.toThrow( + await expect(detectionRulesClient.createPrebuiltRule({ ruleAsset })).rejects.toThrow( 'mocked MLAuth error' ); @@ -70,13 +71,9 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { version: 1, rule_id: 'rule-id', }; - await createPrebuiltRule( - rulesClient, - { - ruleAsset, - }, - mlAuthz - ); + await detectionRulesClient.createPrebuiltRule({ + ruleAsset, + }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -88,8 +85,6 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { immutable: true, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); @@ -101,13 +96,9 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { version: 1, rule_id: 'rule-id', }; - await createPrebuiltRule( - rulesClient, - { - ruleAsset, - }, - mlAuthz - ); + await detectionRulesClient.createPrebuiltRule({ + ruleAsset, + }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -119,8 +110,6 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { immutable: true, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); @@ -129,13 +118,9 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { const ruleAsset = { ...getCreateThreatMatchRulesSchemaMock(), version: 1, rule_id: 'rule-id' }; delete ruleAsset.threat_indicator_path; - await createPrebuiltRule( - rulesClient, - { - ruleAsset, - }, - mlAuthz - ); + await detectionRulesClient.createPrebuiltRule({ + ruleAsset, + }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -146,15 +131,13 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { immutable: true, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); it('does not populate a threatIndicatorPath value for other rules if empty', async () => { const ruleAsset = { ...getCreateRulesSchemaMock(), version: 1, rule_id: 'rule-id' }; - await createPrebuiltRule(rulesClient, { ruleAsset }, mlAuthz); + await detectionRulesClient.createPrebuiltRule({ ruleAsset }); expect(rulesClient.create).not.toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ @@ -164,8 +147,6 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { immutable: true, }), }), - options: {}, - allowMissingConnectorSecrets: undefined, }) ); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.ts new file mode 100644 index 0000000000000..7cf13cec63822 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.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 type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { PrebuiltRuleAsset } from '../../../prebuilt_rules'; +import type { MlAuthz } from '../../../../machine_learning/authz'; +import type { RuleAlertType, RuleParams } from '../../../rule_schema'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import { convertCreateAPIToInternalSchema } from '../../normalization/rule_converters'; + +import { validateMlAuth } from './utils'; + +export interface CreatePrebuiltRuleProps { + ruleAsset: PrebuiltRuleAsset; +} + +export const createPrebuiltRule = async ( + rulesClient: RulesClient, + createPrebuiltRulePayload: CreatePrebuiltRuleProps, + mlAuthz: MlAuthz +): Promise => + withSecuritySpan('DetectionRulesClient.createPrebuiltRule', async () => { + const { ruleAsset } = createPrebuiltRulePayload; + + await validateMlAuth(mlAuthz, ruleAsset.type); + + const internalRule = convertCreateAPIToInternalSchema(ruleAsset, { + immutable: true, + defaultEnabled: false, + }); + + const rule = await rulesClient.create({ + data: internalRule, + }); + + return rule; + }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.rule_management_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.detection_rules_client.test.ts similarity index 60% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.rule_management_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.detection_rules_client.test.ts index d811e5fa21ce0..2182927a373df 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.rule_management_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.detection_rules_client.test.ts @@ -6,18 +6,26 @@ */ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { deleteRule } from './detection_rules_client'; +import { buildMlAuthz } from '../../../../machine_learning/authz'; +import { createDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client'; + +jest.mock('../../../../machine_learning/authz'); describe('DetectionRulesClient.deleteRule', () => { let rulesClient: ReturnType; + let detectionRulesClient: IDetectionRulesClient; + + const mlAuthz = (buildMlAuthz as jest.Mock)(); beforeEach(() => { rulesClient = rulesClientMock.create(); + detectionRulesClient = createDetectionRulesClient(rulesClient, mlAuthz); }); it('should call rulesClient.delete passing the expected ruleId', async () => { const ruleId = 'ruleId'; - await deleteRule(rulesClient, { + await detectionRulesClient.deleteRule({ ruleId, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.ts new file mode 100644 index 0000000000000..a2b4acfc6a58b --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { RuleObjectId } from '../../../../../../common/api/detection_engine'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; + +export interface DeleteRuleProps { + ruleId: RuleObjectId; +} + +export const deleteRule = async ( + rulesClient: RulesClient, + deleteRulePayload: DeleteRuleProps +): Promise => + withSecuritySpan('DetectionRulesClient.deleteRule', async () => { + const { ruleId } = deleteRulePayload; + await rulesClient.delete({ id: ruleId }); + }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts index b756943b7de84..c976f6d247ac5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts @@ -6,97 +6,25 @@ */ import type { RulesClient } from '@kbn/alerting-plugin/server'; - -import type { KibanaRequest } from '@kbn/core-http-server'; -import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; -import type { SharedServices } from '@kbn/ml-plugin/server/shared_services'; -import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; import type { MlAuthz } from '../../../../machine_learning/authz'; -import { buildMlAuthz } from '../../../../machine_learning/authz'; -import type { - RuleCreateProps, - RuleObjectId, - RuleToImport, - PatchRuleRequestBody, - RuleUpdateProps, -} from '../../../../../../common/api/detection_engine'; - -import type { PrebuiltRuleAsset } from '../../../prebuilt_rules'; -import { readRules } from './read_rules'; +import type { RuleAlertType } from '../../../rule_schema'; -import { - convertPatchAPIToInternalSchema, - convertUpdateAPIToInternalSchema, - convertCreateAPIToInternalSchema, -} from '../../normalization/rule_converters'; -import { transformAlertToRuleAction } from '../../../../../../common/detection_engine/transform_actions'; -import type { RuleAlertType, RuleParams } from '../../../rule_schema'; -import { createBulkErrorObject } from '../../../routes/utils'; -import { getIdError } from '../../utils/utils'; -import { throwAuthzError } from '../../../../machine_learning/validation'; - -class ClientError extends Error { - public readonly statusCode: number; - constructor(message: string, statusCode: number) { - super(message); - this.statusCode = statusCode; - } -} +import type { CreateCustomRuleProps } from './create_custom_rule'; +import type { CreatePrebuiltRuleProps } from './create_prebuilt_rule'; +import type { UpdateRuleProps } from './update_rule'; +import type { PatchRuleProps } from './patch_rule'; +import type { DeleteRuleProps } from './delete_rule'; +import type { UpgradePrebuiltRuleProps } from './upgrade_prebuilt_rule'; +import type { ImportRuleProps } from './import_rule'; -export interface CreateRuleOptions { - /* Optionally pass an ID to use for the rule document. If not provided, an ID will be generated. */ - /* This is the ES document ID, NOT the rule_id */ - id?: string; - immutable?: boolean; - defaultEnabled?: boolean; - allowMissingConnectorSecrets?: boolean; -} - -export interface _UpdateRuleProps { - existingRule: RuleAlertType; - ruleUpdate: RuleUpdateProps; -} - -export interface _PatchRuleProps { - existingRule: RuleAlertType; - nextParams: PatchRuleRequestBody; -} - -interface CreateCustomRuleProps { - params: RuleCreateProps; -} - -interface CreatePrebuiltRuleProps { - ruleAsset: PrebuiltRuleAsset; -} - -interface UpdateRuleProps { - ruleUpdate: RuleUpdateProps; -} - -interface PatchRuleProps { - nextParams: PatchRuleRequestBody; -} - -interface DeleteRuleProps { - ruleId: RuleObjectId; -} - -interface UpgradePrebuiltRuleProps { - ruleAsset: PrebuiltRuleAsset; -} - -interface ImportRuleOptions { - allowMissingConnectorSecrets?: boolean; -} - -interface ImportRuleProps { - ruleToImport: RuleToImport; - overwriteRules?: boolean; - options: ImportRuleOptions; -} +import { createCustomRule } from './create_custom_rule'; +import { createPrebuiltRule } from './create_prebuilt_rule'; +import { updateRule } from './update_rule'; +import { patchRule } from './patch_rule'; +import { deleteRule } from './delete_rule'; +import { upgradePrebuiltRule } from './upgrade_prebuilt_rule'; +import { importRule } from './import_rule'; export interface IDetectionRulesClient { createCustomRule: (createCustomRulePayload: CreateCustomRuleProps) => Promise; @@ -114,317 +42,39 @@ export interface IDetectionRulesClient { export const createDetectionRulesClient = ( rulesClient: RulesClient, - request: KibanaRequest, - savedObjectsClient: SavedObjectsClientContract, - licensing: LicensingApiRequestHandlerContext, - ml?: SharedServices -): IDetectionRulesClient => { - const mlAuthz = buildMlAuthz({ - license: licensing.license, - ml, - request, - savedObjectsClient, - }); - - const client = { - createCustomRule: async ( - createCustomRulePayload: CreateCustomRuleProps - ): Promise => { - return createCustomRule(rulesClient, createCustomRulePayload, mlAuthz); - }, - - createPrebuiltRule: async ( - createPrebuiltRulePayload: CreatePrebuiltRuleProps - ): Promise => { - return createPrebuiltRule(rulesClient, createPrebuiltRulePayload, mlAuthz); - }, - - updateRule: async (updateRulePayload: UpdateRuleProps): Promise => { - return updateRule(rulesClient, updateRulePayload, mlAuthz); - }, - - patchRule: async (patchRulePayload: PatchRuleProps): Promise => { - return patchRule(rulesClient, patchRulePayload, mlAuthz); - }, - - deleteRule: async (deleteRulePayload: DeleteRuleProps): Promise => { - return deleteRule(rulesClient, deleteRulePayload); - }, - - upgradePrebuiltRule: async ( - upgradePrebuiltRulePayload: UpgradePrebuiltRuleProps - ): Promise => { - return upgradePrebuiltRule(rulesClient, upgradePrebuiltRulePayload, mlAuthz); - }, - - importRule: async (importRulePayload: ImportRuleProps): Promise => { - return importRule(rulesClient, importRulePayload, mlAuthz); - }, - }; - - return client; -}; - -export const createCustomRule = async ( - rulesClient: RulesClient, - createCustomRulePayload: CreateCustomRuleProps, - mlAuthz: MlAuthz -): Promise => { - const { params } = createCustomRulePayload; - await _validateMlAuth(mlAuthz, params.type); - - const rule = await _createRule(rulesClient, params, { immutable: false }); - return rule; -}; - -export const createPrebuiltRule = async ( - rulesClient: RulesClient, - createPrebuiltRulePayload: CreatePrebuiltRuleProps, - mlAuthz: MlAuthz -): Promise => { - const { ruleAsset } = createPrebuiltRulePayload; - - await _validateMlAuth(mlAuthz, ruleAsset.type); - - const rule = await _createRule(rulesClient, ruleAsset, { - immutable: true, - defaultEnabled: false, - }); - - return rule; -}; - -export const updateRule = async ( - rulesClient: RulesClient, - updateRulePayload: UpdateRuleProps, mlAuthz: MlAuthz -): Promise => { - const { ruleUpdate } = updateRulePayload; - const { rule_id: ruleId, id } = ruleUpdate; - - await _validateMlAuth(mlAuthz, ruleUpdate.type); - - const existingRule = await readRules({ - rulesClient, - ruleId, - id, - }); - - if (existingRule == null) { - const error = getIdError({ id, ruleId }); - throw new ClientError(error.message, error.statusCode); - } - - const update = await _updateRule(rulesClient, { ruleUpdate, existingRule }); - - await _toggleRuleEnabledOnUpdate(rulesClient, existingRule, ruleUpdate.enabled); - - return { ...update, enabled: ruleUpdate.enabled ?? existingRule.enabled }; -}; - -export const patchRule = async ( - rulesClient: RulesClient, - patchRulePayload: PatchRuleProps, - mlAuthz: MlAuthz -): Promise => { - const { nextParams } = patchRulePayload; - const { rule_id: ruleId, id } = nextParams; - - const existingRule = await readRules({ - rulesClient, - ruleId, - id, - }); - - if (existingRule == null) { - const error = getIdError({ id, ruleId }); - throw new ClientError(error.message, error.statusCode); - } - - await _validateMlAuth(mlAuthz, nextParams.type ?? existingRule.params.type); - - const update = await _patchRule(rulesClient, { existingRule, nextParams }); - - await _toggleRuleEnabledOnUpdate(rulesClient, existingRule, nextParams.enabled); - - if (nextParams.enabled != null) { - return { ...update, enabled: nextParams.enabled }; - } else { - return update; - } -}; - -export const deleteRule = async ( - rulesClient: RulesClient, - deleteRulePayload: DeleteRuleProps -): Promise => { - const { ruleId } = deleteRulePayload; - await rulesClient.delete({ id: ruleId }); -}; - -export const upgradePrebuiltRule = async ( - rulesClient: RulesClient, - upgradePrebuiltRulePayload: UpgradePrebuiltRuleProps, - mlAuthz: MlAuthz -): Promise => { - const { ruleAsset } = upgradePrebuiltRulePayload; - - await _validateMlAuth(mlAuthz, ruleAsset.type); - - const existingRule = await readRules({ - rulesClient, - ruleId: ruleAsset.rule_id, - id: undefined, - }); - - if (!existingRule) { - throw new ClientError(`Failed to find rule ${ruleAsset.rule_id}`, 500); - } - - // If rule has change its type during upgrade, delete and recreate it - if (ruleAsset.type !== existingRule.params.type) { - return _upgradePrebuiltRuleWithTypeChange(rulesClient, ruleAsset, existingRule); - } - - // Else, simply patch it. - await _patchRule(rulesClient, { existingRule, nextParams: ruleAsset }); - - const updatedRule = await readRules({ - rulesClient, - ruleId: ruleAsset.rule_id, - id: undefined, - }); - - if (!updatedRule) { - throw new ClientError(`Rule ${ruleAsset.rule_id} not found after upgrade`, 500); - } - - return updatedRule; -}; - -export const importRule = async ( - rulesClient: RulesClient, - importRulePayload: ImportRuleProps, - mlAuthz: MlAuthz -): Promise => { - const { ruleToImport, overwriteRules, options } = importRulePayload; - - await _validateMlAuth(mlAuthz, ruleToImport.type); - - const existingRule = await readRules({ - rulesClient, - ruleId: ruleToImport.rule_id, - id: undefined, - }); - - if (!existingRule) { - return _createRule(rulesClient, ruleToImport, { - immutable: false, - allowMissingConnectorSecrets: options?.allowMissingConnectorSecrets, - }); - } else if (existingRule && overwriteRules) { - return _updateRule(rulesClient, { - existingRule, - ruleUpdate: ruleToImport, - }); - } else { - throw createBulkErrorObject({ - ruleId: existingRule.params.ruleId, - statusCode: 409, - message: `rule_id: "${existingRule.params.ruleId}" already exists`, - }); - } -}; - -/* -------- Internal Methods -------- */ -const _createRule = async ( - rulesClient: RulesClient, - params: RuleCreateProps, - options: CreateRuleOptions -) => { - const rulesClientCreateRuleOptions = options.id ? { id: options.id } : {}; - - const internalRule = convertCreateAPIToInternalSchema(params, options); - const rule = await rulesClient.create({ - data: internalRule, - options: rulesClientCreateRuleOptions, - allowMissingConnectorSecrets: options.allowMissingConnectorSecrets, - }); - - return rule; -}; - -const _updateRule = async ( - rulesClient: RulesClient, - updateRulePayload: _UpdateRuleProps -): Promise => { - const { ruleUpdate, existingRule } = updateRulePayload; - - const newInternalRule = convertUpdateAPIToInternalSchema({ - existingRule, - ruleUpdate, - }); - - const update = await rulesClient.update({ - id: existingRule.id, - data: newInternalRule, - }); - - return update; -}; - -const _patchRule = async ( - rulesClient: RulesClient, - patchRulePayload: _PatchRuleProps -): Promise => { - const { nextParams, existingRule } = patchRulePayload; - - const patchedRule = convertPatchAPIToInternalSchema(nextParams, existingRule); - - const update = await rulesClient.update({ - id: existingRule.id, - data: patchedRule, - }); - - return update; -}; +): IDetectionRulesClient => ({ + createCustomRule: async ( + createCustomRulePayload: CreateCustomRuleProps + ): Promise => { + return createCustomRule(rulesClient, createCustomRulePayload, mlAuthz); + }, + + createPrebuiltRule: async ( + createPrebuiltRulePayload: CreatePrebuiltRuleProps + ): Promise => { + return createPrebuiltRule(rulesClient, createPrebuiltRulePayload, mlAuthz); + }, -const _upgradePrebuiltRuleWithTypeChange = async ( - rulesClient: RulesClient, - ruleAsset: PrebuiltRuleAsset, - existingRule: RuleAlertType -) => { - // If we're trying to change the type of a prepackaged rule, we need to delete the old one - // and replace it with the new rule, keeping the enabled setting, actions, throttle, id, - // and exception lists from the old rule - await rulesClient.delete({ id: existingRule.id }); + updateRule: async (updateRulePayload: UpdateRuleProps): Promise => { + return updateRule(rulesClient, updateRulePayload, mlAuthz); + }, - return _createRule( - rulesClient, - { - ...ruleAsset, - enabled: existingRule.enabled, - exceptions_list: existingRule.params.exceptionsList, - actions: existingRule.actions.map(transformAlertToRuleAction), - timeline_id: existingRule.params.timelineId, - timeline_title: existingRule.params.timelineTitle, - }, - { immutable: true, defaultEnabled: existingRule.enabled, id: existingRule.id } - ); -}; + patchRule: async (patchRulePayload: PatchRuleProps): Promise => { + return patchRule(rulesClient, patchRulePayload, mlAuthz); + }, -const _toggleRuleEnabledOnUpdate = async ( - rulesClient: RulesClient, - existingRule: RuleAlertType, - updatedRuleEnabled?: boolean -) => { - if (existingRule.enabled && updatedRuleEnabled === false) { - await rulesClient.disable({ id: existingRule.id }); - } else if (!existingRule.enabled && updatedRuleEnabled === true) { - await rulesClient.enable({ id: existingRule.id }); - } -}; + deleteRule: async (deleteRulePayload: DeleteRuleProps): Promise => { + return deleteRule(rulesClient, deleteRulePayload); + }, -const _validateMlAuth = async (mlAuthz: MlAuthz, ruleType: Type) => { - throwAuthzError(await mlAuthz.validateRuleType(ruleType)); -}; + upgradePrebuiltRule: async ( + upgradePrebuiltRulePayload: UpgradePrebuiltRuleProps + ): Promise => { + return upgradePrebuiltRule(rulesClient, upgradePrebuiltRulePayload, mlAuthz); + }, + + importRule: async (importRulePayload: ImportRuleProps): Promise => { + return importRule(rulesClient, importRulePayload, mlAuthz); + }, +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.rule_management_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.detection_rules_client.test.ts similarity index 83% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.rule_management_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.detection_rules_client.test.ts index cc7ae2bf28038..f783c5963c2be 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.rule_management_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.detection_rules_client.test.ts @@ -6,13 +6,14 @@ */ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { importRule } from './detection_rules_client'; import { readRules } from './read_rules'; import { getCreateRulesSchemaMock } from '../../../../../../common/api/detection_engine/model/rule_schema/mocks'; import { getRuleMock } from '../../../routes/__mocks__/request_responses'; import { getQueryRuleParams } from '../../../rule_schema/mocks'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; +import { createDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); @@ -21,6 +22,8 @@ jest.mock('./read_rules'); describe('DetectionRulesClient.importRule', () => { let rulesClient: ReturnType; + let detectionRulesClient: IDetectionRulesClient; + const mlAuthz = (buildMlAuthz as jest.Mock)(); const immutable = false as const; // Can only take value of false const allowMissingConnectorSecrets = true; @@ -39,19 +42,16 @@ describe('DetectionRulesClient.importRule', () => { beforeEach(() => { rulesClient = rulesClientMock.create(); + detectionRulesClient = createDetectionRulesClient(rulesClient, mlAuthz); }); it('calls rulesClient.create with the correct parameters when rule_id does not match an installed rule', async () => { (readRules as jest.Mock).mockResolvedValue(null); - await importRule( - rulesClient, - { - ruleToImport, - overwriteRules: true, - options: { allowMissingConnectorSecrets }, - }, - mlAuthz - ); + await detectionRulesClient.importRule({ + ruleToImport, + overwriteRules: true, + options: { allowMissingConnectorSecrets }, + }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -64,7 +64,6 @@ describe('DetectionRulesClient.importRule', () => { version: ruleToImport.version, }), }), - options: {}, allowMissingConnectorSecrets, }) ); @@ -76,15 +75,11 @@ describe('DetectionRulesClient.importRule', () => { }); await expect( - importRule( - rulesClient, - { - ruleToImport, - overwriteRules: true, - options: { allowMissingConnectorSecrets }, - }, - mlAuthz - ) + detectionRulesClient.importRule({ + ruleToImport, + overwriteRules: true, + options: { allowMissingConnectorSecrets }, + }) ).rejects.toThrow('mocked MLAuth error'); expect(rulesClient.create).not.toHaveBeenCalled(); @@ -94,15 +89,11 @@ describe('DetectionRulesClient.importRule', () => { describe('when rule_id matches an installed rule', () => { it('calls rulesClient.update with the correct parameters when overwriteRules is true', async () => { (readRules as jest.Mock).mockResolvedValue(existingRule); - await importRule( - rulesClient, - { - ruleToImport, - overwriteRules: true, - options: { allowMissingConnectorSecrets }, - }, - mlAuthz - ); + await detectionRulesClient.importRule({ + ruleToImport, + overwriteRules: true, + options: { allowMissingConnectorSecrets }, + }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -136,18 +127,14 @@ describe('DetectionRulesClient.importRule', () => { }; (readRules as jest.Mock).mockResolvedValue(existingRuleWithTimestampOverride); - await importRule( - rulesClient, - { - ruleToImport: { - ...ruleToImport, - timestamp_override: undefined, - }, - overwriteRules: true, - options: { allowMissingConnectorSecrets }, + await detectionRulesClient.importRule({ + ruleToImport: { + ...ruleToImport, + timestamp_override: undefined, }, - mlAuthz - ); + overwriteRules: true, + options: { allowMissingConnectorSecrets }, + }); expect(rulesClient.create).not.toHaveBeenCalled(); expect(rulesClient.update).toHaveBeenCalledWith( @@ -164,15 +151,11 @@ describe('DetectionRulesClient.importRule', () => { it('rejects when overwriteRules is false', async () => { (readRules as jest.Mock).mockResolvedValue(existingRule); await expect( - importRule( - rulesClient, - { - ruleToImport, - overwriteRules: false, - options: { allowMissingConnectorSecrets }, - }, - mlAuthz - ) + detectionRulesClient.importRule({ + ruleToImport, + overwriteRules: false, + options: { allowMissingConnectorSecrets }, + }) ).rejects.toMatchObject({ error: { status_code: 409, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.ts new file mode 100644 index 0000000000000..643d59a0c495f --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { MlAuthz } from '../../../../machine_learning/authz'; +import type { RuleAlertType, RuleParams } from '../../../rule_schema'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import type { RuleToImport } from '../../../../../../common/api/detection_engine'; +import { createBulkErrorObject } from '../../../routes/utils'; +import { + convertCreateAPIToInternalSchema, + convertUpdateAPIToInternalSchema, +} from '../../normalization/rule_converters'; + +import { validateMlAuth } from './utils'; + +import { readRules } from './read_rules'; + +interface ImportRuleOptions { + allowMissingConnectorSecrets?: boolean; +} + +export interface ImportRuleProps { + ruleToImport: RuleToImport; + overwriteRules?: boolean; + options: ImportRuleOptions; +} + +export const importRule = async ( + rulesClient: RulesClient, + importRulePayload: ImportRuleProps, + mlAuthz: MlAuthz +): Promise => + withSecuritySpan('DetectionRulesClient.importRule', async () => { + const { ruleToImport, overwriteRules, options } = importRulePayload; + + await validateMlAuth(mlAuthz, ruleToImport.type); + + const existingRule = await readRules({ + rulesClient, + ruleId: ruleToImport.rule_id, + id: undefined, + }); + + if (!existingRule) { + const internalRule = convertCreateAPIToInternalSchema(ruleToImport, { + immutable: false, + }); + + return rulesClient.create({ + data: internalRule, + allowMissingConnectorSecrets: options.allowMissingConnectorSecrets, + }); + } else if (existingRule && overwriteRules) { + const newInternalRule = convertUpdateAPIToInternalSchema({ + existingRule, + ruleUpdate: ruleToImport, + }); + + return rulesClient.update({ + id: existingRule.id, + data: newInternalRule, + }); + } else { + throw createBulkErrorObject({ + ruleId: existingRule.params.ruleId, + statusCode: 409, + message: `rule_id: "${existingRule.params.ruleId}" already exists`, + }); + } + }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.rule_management_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.detection_rules_client.test.ts similarity index 90% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.rule_management_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.detection_rules_client.test.ts index 29bc4c678ac2d..59d250606e285 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.rule_management_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.detection_rules_client.test.ts @@ -13,10 +13,11 @@ import { getCreateMachineLearningRulesSchemaMock, getCreateRulesSchemaMock, } from '../../../../../../common/api/detection_engine/model/rule_schema/mocks'; -import { patchRule } from './detection_rules_client'; import { readRules } from './read_rules'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; +import { createDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); @@ -25,10 +26,13 @@ jest.mock('./read_rules'); describe('DetectionRulesClient.patchRule', () => { let rulesClient: ReturnType; + let detectionRulesClient: IDetectionRulesClient; + const mlAuthz = (buildMlAuthz as jest.Mock)(); beforeEach(() => { rulesClient = rulesClientMock.create(); + detectionRulesClient = createDetectionRulesClient(rulesClient, mlAuthz); }); it('calls the rulesClient with expected params', async () => { @@ -37,7 +41,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - await patchRule(rulesClient, { nextParams }, mlAuthz); + await detectionRulesClient.patchRule({ nextParams }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -58,7 +62,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - const rule = await patchRule(rulesClient, { nextParams }, mlAuthz); + const rule = await detectionRulesClient.patchRule({ nextParams }); expect(rule.enabled).toBe(true); }); @@ -69,7 +73,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getMlRuleParams())); - await patchRule(rulesClient, { nextParams }, mlAuthz); + await detectionRulesClient.patchRule({ nextParams }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ @@ -91,7 +95,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getMlRuleParams())); - await patchRule(rulesClient, { nextParams }, mlAuthz); + await detectionRulesClient.patchRule({ nextParams }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -117,7 +121,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - await patchRule(rulesClient, { nextParams }, mlAuthz); + await detectionRulesClient.patchRule({ nextParams }); expect(rulesClient.disable).toHaveBeenCalledWith( expect.objectContaining({ @@ -138,7 +142,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - await patchRule(rulesClient, { nextParams }, mlAuthz); + await detectionRulesClient.patchRule({ nextParams }); expect(rulesClient.enable).toHaveBeenCalledWith( expect.objectContaining({ @@ -157,7 +161,7 @@ describe('DetectionRulesClient.patchRule', () => { enabled: true, }; - await expect(patchRule(rulesClient, { nextParams }, mlAuthz)).rejects.toThrow( + await expect(detectionRulesClient.patchRule({ nextParams })).rejects.toThrow( 'mocked MLAuth error' ); @@ -183,7 +187,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - await patchRule(rulesClient, { nextParams }, mlAuthz); + await detectionRulesClient.patchRule({ nextParams }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -221,7 +225,7 @@ describe('DetectionRulesClient.patchRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - await patchRule(rulesClient, { nextParams }, mlAuthz); + await detectionRulesClient.patchRule({ nextParams }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.ts new file mode 100644 index 0000000000000..dad3d74a6f208 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { PatchRuleRequestBody } from '../../../../../../common/api/detection_engine'; +import type { MlAuthz } from '../../../../machine_learning/authz'; +import type { RuleAlertType } from '../../../rule_schema'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import { getIdError } from '../../utils/utils'; +import { convertPatchAPIToInternalSchema } from '../../normalization/rule_converters'; + +import { validateMlAuth, ClientError, toggleRuleEnabledOnUpdate } from './utils'; + +import { readRules } from './read_rules'; + +export interface PatchRuleProps { + nextParams: PatchRuleRequestBody; +} + +export const patchRule = async ( + rulesClient: RulesClient, + patchRulePayload: PatchRuleProps, + mlAuthz: MlAuthz +): Promise => + withSecuritySpan('DetectionRulesClient.patchRule', async () => { + const { nextParams } = patchRulePayload; + const { rule_id: ruleId, id } = nextParams; + + const existingRule = await readRules({ + rulesClient, + ruleId, + id, + }); + + if (existingRule == null) { + const error = getIdError({ id, ruleId }); + throw new ClientError(error.message, error.statusCode); + } + + await validateMlAuth(mlAuthz, nextParams.type ?? existingRule.params.type); + + const patchedRule = convertPatchAPIToInternalSchema(nextParams, existingRule); + + const update = await rulesClient.update({ + id: existingRule.id, + data: patchedRule, + }); + + await toggleRuleEnabledOnUpdate(rulesClient, existingRule, nextParams.enabled); + + if (nextParams.enabled != null) { + return { ...update, enabled: nextParams.enabled }; + } else { + return update; + } + }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.rule_management_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.detection_rules_client.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.rule_management_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.detection_rules_client.test.ts index b0ee5a6426775..f538672444b0e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.rule_management_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.detection_rules_client.test.ts @@ -13,7 +13,7 @@ import { getCreateMachineLearningRulesSchemaMock, getCreateRulesSchemaMock, } from '../../../../../../common/api/detection_engine/model/rule_schema/mocks'; -import { updateRule } from './detection_rules_client'; +import { updateRule } from './update_rule'; import { readRules } from './read_rules'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.ts new file mode 100644 index 0000000000000..4370e4f457448 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.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 type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { RuleUpdateProps } from '../../../../../../common/api/detection_engine'; +import type { MlAuthz } from '../../../../machine_learning/authz'; +import type { RuleAlertType } from '../../../rule_schema'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import { getIdError } from '../../utils/utils'; +import { convertUpdateAPIToInternalSchema } from '../../normalization/rule_converters'; + +import { validateMlAuth, ClientError, toggleRuleEnabledOnUpdate } from './utils'; + +import { readRules } from './read_rules'; + +export interface UpdateRuleProps { + ruleUpdate: RuleUpdateProps; +} + +export const updateRule = async ( + rulesClient: RulesClient, + updateRulePayload: UpdateRuleProps, + mlAuthz: MlAuthz +): Promise => + withSecuritySpan('DetectionRulesClient.updateRule', async () => { + const { ruleUpdate } = updateRulePayload; + const { rule_id: ruleId, id } = ruleUpdate; + + await validateMlAuth(mlAuthz, ruleUpdate.type); + + const existingRule = await readRules({ + rulesClient, + ruleId, + id, + }); + + if (existingRule == null) { + const error = getIdError({ id, ruleId }); + throw new ClientError(error.message, error.statusCode); + } + + const newInternalRule = convertUpdateAPIToInternalSchema({ + existingRule, + ruleUpdate, + }); + + const update = await rulesClient.update({ + id: existingRule.id, + data: newInternalRule, + }); + + await toggleRuleEnabledOnUpdate(rulesClient, existingRule, ruleUpdate.enabled); + + return { ...update, enabled: ruleUpdate.enabled ?? existingRule.enabled }; + }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.rule_management_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.detection_rules_client.test.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.rule_management_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.detection_rules_client.test.ts index 1997df6f3fff1..50dc69b660c0f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.rule_management_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.detection_rules_client.test.ts @@ -7,8 +7,6 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { upgradePrebuiltRule } from './detection_rules_client'; - import { getCreateEqlRuleSchemaMock, getCreateRulesSchemaMock, @@ -21,6 +19,8 @@ import { getEqlRuleParams, getQueryRuleParams } from '../../../rule_schema/mocks import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; +import { createDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); @@ -28,10 +28,13 @@ jest.mock('./read_rules'); describe('DetectionRulesClient.upgradePrebuiltRule', () => { let rulesClient: ReturnType; + let detectionRulesClient: IDetectionRulesClient; + const mlAuthz = (buildMlAuthz as jest.Mock)(); beforeEach(() => { rulesClient = rulesClientMock.create(); + detectionRulesClient = createDetectionRulesClient(rulesClient, mlAuthz); }); it('throws if no matching rule_id is found', async () => { @@ -42,7 +45,7 @@ describe('DetectionRulesClient.upgradePrebuiltRule', () => { }; (readRules as jest.Mock).mockResolvedValue(null); - await expect(upgradePrebuiltRule(rulesClient, { ruleAsset }, mlAuthz)).rejects.toThrow( + await expect(detectionRulesClient.upgradePrebuiltRule({ ruleAsset })).rejects.toThrow( `Failed to find rule ${ruleAsset.rule_id}` ); }); @@ -58,7 +61,7 @@ describe('DetectionRulesClient.upgradePrebuiltRule', () => { rule_id: 'rule-id', }; - await expect(upgradePrebuiltRule(rulesClient, { ruleAsset }, mlAuthz)).rejects.toThrow( + await expect(detectionRulesClient.upgradePrebuiltRule({ ruleAsset })).rejects.toThrow( 'mocked MLAuth error' ); @@ -100,12 +103,12 @@ describe('DetectionRulesClient.upgradePrebuiltRule', () => { }); it('deletes the old rule ', async () => { - await upgradePrebuiltRule(rulesClient, { ruleAsset }, mlAuthz); + await detectionRulesClient.upgradePrebuiltRule({ ruleAsset }); expect(rulesClient.delete).toHaveBeenCalled(); }); it('creates a new rule with the new type and expected params of the original rules', async () => { - await upgradePrebuiltRule(rulesClient, { ruleAsset }, mlAuthz); + await detectionRulesClient.upgradePrebuiltRule({ ruleAsset }); expect(rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ @@ -127,7 +130,6 @@ describe('DetectionRulesClient.upgradePrebuiltRule', () => { options: { id: installedRule.id, // id is maintained }, - allowMissingConnectorSecrets: undefined, }) ); }); @@ -151,7 +153,7 @@ describe('DetectionRulesClient.upgradePrebuiltRule', () => { }); it('patches the existing rule with the new params from the rule asset', async () => { - await upgradePrebuiltRule(rulesClient, { ruleAsset }, mlAuthz); + await detectionRulesClient.upgradePrebuiltRule({ ruleAsset }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts new file mode 100644 index 0000000000000..b516fc997055c --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts @@ -0,0 +1,90 @@ +/* + * 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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { PrebuiltRuleAsset } from '../../../prebuilt_rules'; +import type { MlAuthz } from '../../../../machine_learning/authz'; +import type { RuleAlertType, RuleParams } from '../../../rule_schema'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import { + convertPatchAPIToInternalSchema, + convertCreateAPIToInternalSchema, +} from '../../normalization/rule_converters'; +import { transformAlertToRuleAction } from '../../../../../../common/detection_engine/transform_actions'; + +import { validateMlAuth, ClientError } from './utils'; + +import { readRules } from './read_rules'; + +export interface UpgradePrebuiltRuleProps { + ruleAsset: PrebuiltRuleAsset; +} + +export const upgradePrebuiltRule = async ( + rulesClient: RulesClient, + upgradePrebuiltRulePayload: UpgradePrebuiltRuleProps, + mlAuthz: MlAuthz +): Promise => + withSecuritySpan('DetectionRulesClient.upgradePrebuiltRule', async () => { + const { ruleAsset } = upgradePrebuiltRulePayload; + + await validateMlAuth(mlAuthz, ruleAsset.type); + + const existingRule = await readRules({ + rulesClient, + ruleId: ruleAsset.rule_id, + id: undefined, + }); + + if (!existingRule) { + throw new ClientError(`Failed to find rule ${ruleAsset.rule_id}`, 500); + } + + if (ruleAsset.type !== existingRule.params.type) { + // If we're trying to change the type of a prepackaged rule, we need to delete the old one + // and replace it with the new rule, keeping the enabled setting, actions, throttle, id, + // and exception lists from the old rule + await rulesClient.delete({ id: existingRule.id }); + + const internalRule = convertCreateAPIToInternalSchema( + { + ...ruleAsset, + enabled: existingRule.enabled, + exceptions_list: existingRule.params.exceptionsList, + actions: existingRule.actions.map(transformAlertToRuleAction), + timeline_id: existingRule.params.timelineId, + timeline_title: existingRule.params.timelineTitle, + }, + { immutable: true, defaultEnabled: existingRule.enabled } + ); + + return rulesClient.create({ + data: internalRule, + options: { id: existingRule.id }, + }); + } + + // Else, simply patch it. + const patchedRule = convertPatchAPIToInternalSchema(ruleAsset, existingRule); + + await rulesClient.update({ + id: existingRule.id, + data: patchedRule, + }); + + const updatedRule = await readRules({ + rulesClient, + ruleId: ruleAsset.rule_id, + id: undefined, + }); + + if (!updatedRule) { + throw new ClientError(`Rule ${ruleAsset.rule_id} not found after upgrade`, 500); + } + + return updatedRule; + }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/utils.ts new file mode 100644 index 0000000000000..0173ba5aea370 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/utils.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 type { RulesClient } from '@kbn/alerting-plugin/server'; + +import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { MlAuthz } from '../../../../machine_learning/authz'; + +import type { RuleAlertType } from '../../../rule_schema'; +import { throwAuthzError } from '../../../../machine_learning/validation'; + +export const toggleRuleEnabledOnUpdate = async ( + rulesClient: RulesClient, + existingRule: RuleAlertType, + updatedRuleEnabled?: boolean +) => { + if (existingRule.enabled && updatedRuleEnabled === false) { + await rulesClient.disable({ id: existingRule.id }); + } else if (!existingRule.enabled && updatedRuleEnabled === true) { + await rulesClient.enable({ id: existingRule.id }); + } +}; + +export const validateMlAuth = async (mlAuthz: MlAuthz, ruleType: Type) => { + throwAuthzError(await mlAuthz.validateRuleType(ruleType)); +}; + +export class ClientError extends Error { + public readonly statusCode: number; + constructor(message: string, statusCode: number) { + super(message); + this.statusCode = statusCode; + } +} diff --git a/x-pack/plugins/security_solution/server/lib/machine_learning/authz.ts b/x-pack/plugins/security_solution/server/lib/machine_learning/authz.ts index f96866d968e4b..aa880c79393d3 100644 --- a/x-pack/plugins/security_solution/server/lib/machine_learning/authz.ts +++ b/x-pack/plugins/security_solution/server/lib/machine_learning/authz.ts @@ -28,7 +28,7 @@ export interface MlAuthz { * @param ml {@link MlPluginSetup} ML services to fetch ML capabilities * @param request A {@link KibanaRequest} representing the authenticated user * - * @returns A {@link MLAuthz} service object + * @returns A {@link MlAuthz} service object */ export const buildMlAuthz = ({ license, diff --git a/x-pack/plugins/security_solution/server/request_context_factory.ts b/x-pack/plugins/security_solution/server/request_context_factory.ts index f2e090b389ff6..a47535772dd83 100644 --- a/x-pack/plugins/security_solution/server/request_context_factory.ts +++ b/x-pack/plugins/security_solution/server/request_context_factory.ts @@ -29,6 +29,7 @@ import { RiskEngineDataClient } from './lib/entity_analytics/risk_engine/risk_en import { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_score_data_client'; import { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality'; import { createDetectionRulesClient } from './lib/detection_engine/rule_management/logic/rule_management/detection_rules_client'; +import { buildMlAuthz } from './lib/machine_learning/authz'; export interface IRequestContextFactory { create( @@ -113,14 +114,19 @@ export class RequestContextFactory implements IRequestContextFactory { getAuditLogger, - getDetectionRulesClient: () => - createDetectionRulesClient( - startPlugins.alerting.getRulesClientWithRequest(request), + getDetectionRulesClient: () => { + const mlAuthz = buildMlAuthz({ + license: licensing.license, + ml: plugins.ml, request, - coreContext.savedObjects.client, - licensing, - plugins.ml - ), + savedObjectsClient: coreContext.savedObjects.client, + }); + + return createDetectionRulesClient( + startPlugins.alerting.getRulesClientWithRequest(request), + mlAuthz + ); + }, getDetectionEngineHealthClient: memoize(() => ruleMonitoringService.createDetectionEngineHealthClient({ From 5f2e0c613a5bef0b30bf4dd3cb05f29405ef19b0 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 6 Jun 2024 09:13:23 -0400 Subject: [PATCH 040/122] [Observability Onboarding] Update links for integration buttons in observability solutions (#184477) ## Summary Continuation of https://github.com/elastic/kibana/pull/184164. Changes the integration links for metrics and logs to link to the new onboarding flow. --- .../infra/public/pages/logs/shared/page_template.tsx | 10 +++++----- .../infra/public/pages/metrics/page_template.tsx | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_template.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_template.tsx index 31b8718d9c850..c0dfc79641dde 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_template.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/shared/page_template.tsx @@ -8,7 +8,7 @@ import React, { useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { OBSERVABILITY_ONBOARDING_LOCATOR } from '@kbn/deeplinks-observability'; import { NoDataConfig } from '@kbn/shared-ux-page-kibana-template'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; @@ -29,13 +29,13 @@ export const LogsPageTemplate: React.FC = ({ observabilityShared: { navigation: { PageTemplate }, }, + share, docLinks, }, } = useKibanaContextForPlugin(); - const { http } = useKibana().services; - const basePath = http!.basePath.get(); - + const onboardingLocator = share.url.locators.get(OBSERVABILITY_ONBOARDING_LOCATOR); + const href = onboardingLocator?.getRedirectUrl({ category: 'logs' }); const { setScreenContext } = observabilityAIAssistant?.service || {}; useEffect(() => { @@ -79,7 +79,7 @@ export const LogsPageTemplate: React.FC = ({ defaultMessage: 'Use the Elastic Agent or Beats to send logs to Elasticsearch. We make it easy with integrations for many popular systems and apps.', }), - href: basePath + `/app/integrations/browse`, + href, }, }, docsLink: docLinks.links.observability.guide, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/page_template.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/page_template.tsx index 74128ad8eb41e..d48b77404767d 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/page_template.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/page_template.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import { OBSERVABILITY_ONBOARDING_LOCATOR } from '@kbn/deeplinks-observability'; import { i18n } from '@kbn/i18n'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-shared-plugin/public'; import type { NoDataConfig } from '@kbn/shared-ux-page-kibana-template'; @@ -30,10 +31,13 @@ export const MetricsPageTemplate: React.FC = observabilityShared: { navigation: { PageTemplate }, }, + share, docLinks, }, } = useKibanaContextForPlugin(); + const onboardingLocator = share.url.locators.get(OBSERVABILITY_ONBOARDING_LOCATOR); + const href = onboardingLocator?.getRedirectUrl({ category: 'infra' }); const { source, error: sourceError, loadSource, isLoading } = useSourceContext(); const { error: dataViewLoadError, refetch: loadDataView } = useMetricsDataViewContext(); const { remoteClustersExist, metricIndicesExist } = source?.status ?? {}; @@ -48,6 +52,7 @@ export const MetricsPageTemplate: React.FC = beats: { title: noMetricIndicesPromptPrimaryActionTitle, description: noMetricIndicesPromptDescription, + href, }, }, docsLink: docLinks.links.observability.guide, From 1c255c611a7caf2c10a126d8424c403e8763de2c Mon Sep 17 00:00:00 2001 From: Rachel Shen Date: Thu, 6 Jun 2024 07:31:24 -0600 Subject: [PATCH 041/122] [Fix] Add isLoading state to Global Search (#183866) ## Summary This is a clean up PR for the global search. This PR keeps the height of the svg until it loads. This PR sets up the `isLoading` prop provided by EUI. --- .../public/components/search_bar.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx index 04e519a83b534..726c41f399450 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx @@ -71,6 +71,7 @@ export const SearchBar: FC = (opts) => { const [searchableTypes, setSearchableTypes] = useState([]); const [showAppend, setShowAppend] = useState(true); const UNKNOWN_TAG_ID = '__unknown__'; + const [isLoading, setIsLoading] = useState(false); useEffect(() => { if (initialLoad) { @@ -126,7 +127,9 @@ export const SearchBar: FC = (opts) => { searchSubscription.current = null; } + setIsLoading(true); const suggestions = loadSuggestions(searchValue.toLowerCase()); + setIsLoading(false); let aggregatedResults: GlobalSearchResult[] = []; if (searchValue.length !== 0) { @@ -152,7 +155,7 @@ export const SearchBar: FC = (opts) => { // so the SearchOption won't highlight anything if only one call is fired // in practice, this is hard to spot, unlikely to happen, and is a negligible issue setSearchTerm(rawParams.term ?? ''); - + setIsLoading(true); searchSubscription.current = globalSearch.find(searchParams, {}).subscribe({ next: ({ results }) => { if (searchValue.length > 0) { @@ -169,11 +172,14 @@ export const SearchBar: FC = (opts) => { setOptions(aggregatedResults, suggestions, searchParams.tags); }, error: (err) => { + setIsLoading(false); // Not doing anything on error right now because it'll either just show the previous // results or empty results which is basically what we want anyways reportEvent.error({ message: err, searchValue }); }, - complete: () => {}, + complete: () => { + setIsLoading(false); + }, }); } }, @@ -320,6 +326,7 @@ export const SearchBar: FC = (opts) => { return ( Date: Thu, 6 Jun 2024 15:49:41 +0200 Subject: [PATCH 042/122] [OAS] Refactor `description` -> `summary` (#184651) ## Summary Per [the OAS docs](https://swagger.io/specification/), they have an info object with a `summary` and `description` field. This PR refactors the existing router `description` field to to OAS `summary` (that is how it has been used) and introduces a "new" `description` field that will be used for the longer form descriptions. ## Resources * https://swagger.io/specification/ --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: lcawl --- oas_docs/bundle.json | 8 ++---- .../http/core-http-server/src/router/route.ts | 28 ++++++++++++++++++- .../core-http-server/src/versioning/types.ts | 19 +++++++++++-- .../src/routes/status.ts | 2 +- .../__snapshots__/generate_oas.test.ts.snap | 16 ++++++----- .../src/generate_oas.test.util.ts | 5 ++-- .../src/process_router.test.ts | 2 -- .../src/process_router.ts | 4 +-- .../src/process_versioned_router.ts | 3 +- .../http/short_urls/register_create_route.ts | 2 +- .../http/short_urls/register_delete_route.ts | 2 +- .../http/short_urls/register_get_route.ts | 2 +- .../http/short_urls/register_resolve_route.ts | 2 +- .../server/routes/connector/get/get.ts | 2 +- .../routes/connector/get_all/get_all.ts | 2 +- .../routes/connector/list_types/list_types.ts | 2 +- .../plugins/actions/server/routes/create.ts | 2 +- .../plugins/actions/server/routes/delete.ts | 2 +- .../plugins/actions/server/routes/execute.ts | 4 ++- .../actions/server/routes/legacy/create.ts | 2 +- .../actions/server/routes/legacy/delete.ts | 2 +- .../actions/server/routes/legacy/execute.ts | 2 +- .../actions/server/routes/legacy/get.ts | 2 +- .../actions/server/routes/legacy/get_all.ts | 2 +- .../server/routes/legacy/list_action_types.ts | 2 +- .../actions/server/routes/legacy/update.ts | 2 +- .../plugins/actions/server/routes/update.ts | 2 +- .../alerting/server/routes/disable_rule.ts | 2 +- .../alerting/server/routes/enable_rule.ts | 2 +- .../plugins/alerting/server/routes/health.ts | 2 +- .../alerting/server/routes/mute_all_rule.ts | 2 +- .../rule/apis/create/create_rule_route.ts | 2 +- .../rule/apis/delete/delete_rule_route.ts | 2 +- .../routes/rule/apis/find/find_rules_route.ts | 2 +- .../routes/rule/apis/get/get_rule_route.ts | 2 +- .../routes/rule/apis/mute_alert/mute_alert.ts | 2 +- .../rule/apis/update/update_rule_route.ts | 2 +- .../alerting/server/routes/rule_types.ts | 2 +- .../alerting/server/routes/unmute_alert.ts | 2 +- .../alerting/server/routes/unmute_all_rule.ts | 2 +- .../server/routes/update_rule_api_key.ts | 2 +- .../routes/api/cases/alerts/get_cases.ts | 2 +- .../server/routes/api/cases/delete_cases.ts | 2 +- .../server/routes/api/cases/find_cases.ts | 2 +- .../cases/server/routes/api/cases/get_case.ts | 2 +- .../server/routes/api/cases/patch_cases.ts | 2 +- .../server/routes/api/cases/post_case.ts | 2 +- .../server/routes/api/cases/push_case.ts | 2 +- .../api/cases/reporters/get_reporters.ts | 2 +- .../server/routes/api/cases/tags/get_tags.ts | 2 +- .../api/comments/delete_all_comments.ts | 2 +- .../routes/api/comments/delete_comment.ts | 2 +- .../routes/api/comments/find_comments.ts | 2 +- .../server/routes/api/comments/get_alerts.ts | 2 +- .../routes/api/comments/get_all_comment.ts | 2 +- .../server/routes/api/comments/get_comment.ts | 2 +- .../routes/api/comments/patch_comment.ts | 2 +- .../routes/api/comments/post_comment.ts | 2 +- .../routes/api/configure/get_configure.ts | 2 +- .../routes/api/configure/get_connectors.ts | 2 +- .../routes/api/configure/patch_configure.ts | 2 +- .../routes/api/configure/post_configure.ts | 2 +- .../server/routes/api/stats/get_status.ts | 2 +- .../api/user_actions/find_user_actions.ts | 2 +- .../api/user_actions/get_all_user_actions.ts | 2 +- .../plugins/features/server/routes/index.ts | 2 +- .../logstash/server/routes/pipeline/delete.ts | 2 +- .../logstash/server/routes/pipeline/load.ts | 2 +- .../logstash/server/routes/pipeline/save.ts | 2 +- .../server/routes/pipelines/delete.ts | 2 +- .../logstash/server/routes/pipelines/list.ts | 2 +- .../plugins/ml/server/routes/saved_objects.ts | 2 +- .../routes/authorization/roles/delete.ts | 2 +- .../server/routes/authorization/roles/get.ts | 2 +- .../routes/authorization/roles/get_all.ts | 2 +- .../server/routes/authorization/roles/put.ts | 2 +- .../session_management/invalidate.test.ts | 2 +- .../routes/session_management/invalidate.ts | 2 +- .../task_manager/server/routes/health.ts | 2 +- .../reindex_indices/batch_reindex_indices.ts | 4 +-- .../routes/reindex_indices/reindex_indices.ts | 6 ++-- .../upgrade_assistant/server/routes/status.ts | 2 +- 82 files changed, 142 insertions(+), 99 deletions(-) diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index cdd86729d7f8e..1dfcdd50639b3 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -499,8 +499,7 @@ "description": "Kibana's operational status. A minimal response is sent for unauthorized users." } } - }, - "description": "Get Kibana's current status." + } }, "503": { "content": { @@ -517,11 +516,10 @@ "description": "Kibana's operational status. A minimal response is sent for unauthorized users." } } - }, - "description": "Get Kibana's current status." + } } }, - "summary": "Get Kibana's current status.", + "summary": "Get Kibana's current status", "tags": [] } } diff --git a/packages/core/http/core-http-server/src/router/route.ts b/packages/core/http/core-http-server/src/router/route.ts index bb3e59cfcd00b..28f889d5dbdef 100644 --- a/packages/core/http/core-http-server/src/router/route.ts +++ b/packages/core/http/core-http-server/src/router/route.ts @@ -160,7 +160,33 @@ export interface RouteConfigOptions { idleSocket?: number; }; - /** A short, human-friendly description of this endpoint */ + /** + * Short summary of this route. Required for all routes used in OAS documentation. + * + * @example + * ```ts + * router.get({ + * path: '/api/foo/{id}', + * access: 'public', + * summary: `Get foo resources for an ID`, + * }) + * ``` + */ + summary?: string; + + /** + * Optional API description, which supports [CommonMark](https://spec.commonmark.org) markdown formatting + * + * @example + * ```ts + * router.get({ + * path: '/api/foo/{id}', + * access: 'public', + * summary: `Get foo resources for an ID`, + * description: `Foo resources require **X** and **Y** `read` permissions to access.`, + * }) + * ``` + */ description?: string; } diff --git a/packages/core/http/core-http-server/src/versioning/types.ts b/packages/core/http/core-http-server/src/versioning/types.ts index 8495f05210a36..af3173691415f 100644 --- a/packages/core/http/core-http-server/src/versioning/types.ts +++ b/packages/core/http/core-http-server/src/versioning/types.ts @@ -55,14 +55,29 @@ export type VersionedRouteConfig = Omit< enableQueryVersion?: boolean; /** - * Human-friendly description of this route, should be usable for documentation + * Short summary of this route. Required for all routes used in OAS documentation. * * @example * ```ts * router.get({ * path: '/api/foo/{id}', * access: 'public', - * description: `Retrieve foo resources given an ID. To retrieve a list of IDs use the GET /api/foo API.`, + * summary: `Get foo resources for an ID`, + * }) + * ``` + */ + summary?: string; + + /** + * Optional API description, which supports [CommonMark](https://spec.commonmark.org) markdown formatting + * + * @example + * ```ts + * router.get({ + * path: '/api/foo/{id}', + * access: 'public', + * summary: `Get foo resources for an ID`, + * description: `Foo resources require **X** and **Y** `read` permissions to access.`, * }) * ``` */ diff --git a/packages/core/status/core-status-server-internal/src/routes/status.ts b/packages/core/status/core-status-server-internal/src/routes/status.ts index 5557a4d60aaef..4b243240321d7 100644 --- a/packages/core/status/core-status-server-internal/src/routes/status.ts +++ b/packages/core/status/core-status-server-internal/src/routes/status.ts @@ -88,7 +88,7 @@ export const registerStatusRoute = ({ // ROUTE_TAG_ACCEPT_JWT from '@kbn/security-plugin/server' that cannot be imported here directly. tags: ['api', 'security:acceptJWT'], access: 'public', // needs to be public to allow access from "system" users like k8s readiness probes. - description: `Get Kibana's current status.`, + summary: `Get Kibana's current status`, }, validate: { request: { diff --git a/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap b/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap index 2c6186ff56984..fee1a8534a7ec 100644 --- a/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap +++ b/packages/kbn-router-to-openapispec/src/__snapshots__/generate_oas.test.ts.snap @@ -26,6 +26,7 @@ Object { "paths": Object { "/foo/{id}": Object { "get": Object { + "description": undefined, "operationId": "/foo/{id}#0", "parameters": Array [ Object { @@ -85,7 +86,6 @@ Object { }, }, }, - "description": "No description", }, }, "summary": "", @@ -133,6 +133,7 @@ Object { "paths": Object { "/bar": Object { "get": Object { + "description": undefined, "operationId": "/bar#0", "parameters": Array [ Object { @@ -221,6 +222,7 @@ Object { }, "/foo/{id}/{path*}": Object { "get": Object { + "description": "route description", "operationId": "/foo/{id}/{path*}#0", "parameters": Array [ Object { @@ -357,15 +359,15 @@ Object { }, }, }, - "description": "route", }, }, - "summary": "route", + "summary": "route summary", "tags": Array [ "bar", ], }, "post": Object { + "description": "route description", "operationId": "/foo/{id}/{path*}#1", "parameters": Array [ Object { @@ -502,10 +504,9 @@ Object { }, }, }, - "description": "route", }, }, - "summary": "route", + "summary": "route summary", "tags": Array [ "bar", ], @@ -576,6 +577,7 @@ Object { "paths": Object { "/recursive": Object { "get": Object { + "description": undefined, "operationId": "/recursive#0", "parameters": Array [ Object { @@ -611,7 +613,6 @@ Object { }, }, }, - "description": "No description", }, }, "summary": "", @@ -659,6 +660,7 @@ Object { "paths": Object { "/foo/{id}": Object { "get": Object { + "description": undefined, "operationId": "/foo/{id}#0", "parameters": Array [ Object { @@ -688,7 +690,6 @@ Object { "schema": Object {}, }, }, - "description": "No description", }, }, "summary": "", @@ -697,6 +698,7 @@ Object { }, "/test": Object { "get": Object { + "description": undefined, "operationId": "/test#0", "parameters": Array [ Object { diff --git a/packages/kbn-router-to-openapispec/src/generate_oas.test.util.ts b/packages/kbn-router-to-openapispec/src/generate_oas.test.util.ts index b4e273b3a5b7b..bed7d10c51d8e 100644 --- a/packages/kbn-router-to-openapispec/src/generate_oas.test.util.ts +++ b/packages/kbn-router-to-openapispec/src/generate_oas.test.util.ts @@ -55,7 +55,8 @@ export const getRouterDefaults = () => ({ method: 'get', options: { tags: ['foo', 'oas-tag:bar'], - description: 'route', + summary: 'route summary', + description: 'route description', }, validationSchemas: { request: { @@ -82,7 +83,7 @@ export const getVersionedRouterDefaults = () => ({ method: 'get', path: '/bar', options: { - description: 'versioned route', + summary: 'versioned route', access: 'public', options: { tags: ['ignore-me', 'oas-tag:versioned'], diff --git a/packages/kbn-router-to-openapispec/src/process_router.test.ts b/packages/kbn-router-to-openapispec/src/process_router.test.ts index 32888cfe1dd47..41850b31c5d46 100644 --- a/packages/kbn-router-to-openapispec/src/process_router.test.ts +++ b/packages/kbn-router-to-openapispec/src/process_router.test.ts @@ -45,7 +45,6 @@ describe('extractResponses', () => { }; expect(extractResponses(route, oasConverter)).toEqual({ 200: { - description: 'No description', content: { 'application/test+json; Elastic-Api-Version=2023-10-31': { schema: { @@ -60,7 +59,6 @@ describe('extractResponses', () => { }, }, 404: { - description: 'No description', content: { 'application/test2+json; Elastic-Api-Version=2023-10-31': { schema: { diff --git a/packages/kbn-router-to-openapispec/src/process_router.ts b/packages/kbn-router-to-openapispec/src/process_router.ts index ce9486b140dc4..393b745b6aab3 100644 --- a/packages/kbn-router-to-openapispec/src/process_router.ts +++ b/packages/kbn-router-to-openapispec/src/process_router.ts @@ -60,7 +60,8 @@ export const processRouter = ( } const operation: OpenAPIV3.OperationObject = { - summary: route.options.description ?? '', + summary: route.options.summary ?? '', + description: route.options.description, tags: route.options.tags ? extractTags(route.options.tags) : [], requestBody: !!validationSchemas?.body ? { @@ -103,7 +104,6 @@ export const extractResponses = (route: InternalRouterRoute, converter: OasConve const oasSchema = converter.convert(schema.body()); acc[statusCode] = { ...acc[statusCode], - description: route.options.description ?? 'No description', content: { ...((acc[statusCode] ?? {}) as OpenAPIV3.ResponseObject).content, [getVersionedContentTypeString( diff --git a/packages/kbn-router-to-openapispec/src/process_versioned_router.ts b/packages/kbn-router-to-openapispec/src/process_versioned_router.ts index 85246a5164306..cc873b26835cf 100644 --- a/packages/kbn-router-to-openapispec/src/process_versioned_router.ts +++ b/packages/kbn-router-to-openapispec/src/process_versioned_router.ts @@ -84,7 +84,8 @@ export const processVersionedRouter = ( const contentType = extractContentType(route.options.options?.body); const hasVersionFilter = Boolean(filters?.version); const operation: OpenAPIV3.OperationObject = { - summary: route.options.description ?? '', + summary: route.options.summary ?? '', + description: route.options.description, tags: route.options.options?.tags ? extractTags(route.options.options.tags) : [], requestBody: hasBody ? { diff --git a/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts index 0848fdfbfe605..3b8667d92cfb2 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts @@ -17,7 +17,7 @@ export const registerCreateRoute = (router: IRouter, url: ServerUrlService) => { path: '/api/short_url', options: { access: 'public', - description: `Create a short URL`, + summary: `Create a short URL`, }, validate: { body: schema.object({ diff --git a/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts index 258faff0d04a6..2df23f190c2d7 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts @@ -16,7 +16,7 @@ export const registerDeleteRoute = (router: IRouter, url: ServerUrlService) => { path: '/api/short_url/{id}', options: { access: 'public', - description: `Delete a short URL`, + summary: `Delete a short URL`, }, validate: { params: schema.object({ diff --git a/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts index ae108ccd11d97..8c7df947d4662 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts @@ -16,7 +16,7 @@ export const registerGetRoute = (router: IRouter, url: ServerUrlService) => { path: '/api/short_url/{id}', options: { access: 'public', - description: `Get a short URL`, + summary: `Get a short URL`, }, validate: { params: schema.object({ diff --git a/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts index 6076889945f36..e37f2c818dca8 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts @@ -17,7 +17,7 @@ export const registerResolveRoute = (router: IRouter, url: ServerUrlService) => path: '/api/short_url/_slug/{slug}', options: { access: 'public', - description: `Resolve a short URL`, + summary: `Resolve a short URL`, }, validate: { params: schema.object({ diff --git a/x-pack/plugins/actions/server/routes/connector/get/get.ts b/x-pack/plugins/actions/server/routes/connector/get/get.ts index 2a05405a6a722..bb15a2e2e5cf5 100644 --- a/x-pack/plugins/actions/server/routes/connector/get/get.ts +++ b/x-pack/plugins/actions/server/routes/connector/get/get.ts @@ -25,7 +25,7 @@ export const getConnectorRoute = ( path: `${BASE_ACTION_API_PATH}/connector/{id}`, options: { access: 'public', - description: `Get connector information`, + summary: `Get connector information`, }, validate: { params: getConnectorParamsSchemaV1, diff --git a/x-pack/plugins/actions/server/routes/connector/get_all/get_all.ts b/x-pack/plugins/actions/server/routes/connector/get_all/get_all.ts index e37edc2347a32..b5ffb4499b073 100644 --- a/x-pack/plugins/actions/server/routes/connector/get_all/get_all.ts +++ b/x-pack/plugins/actions/server/routes/connector/get_all/get_all.ts @@ -22,7 +22,7 @@ export const getAllConnectorsRoute = ( path: `${BASE_ACTION_API_PATH}/connectors`, options: { access: 'public', - description: `Get all connectors`, + summary: `Get all connectors`, }, validate: {}, }, diff --git a/x-pack/plugins/actions/server/routes/connector/list_types/list_types.ts b/x-pack/plugins/actions/server/routes/connector/list_types/list_types.ts index e09a828c9ff6c..4632a6fb9e83e 100644 --- a/x-pack/plugins/actions/server/routes/connector/list_types/list_types.ts +++ b/x-pack/plugins/actions/server/routes/connector/list_types/list_types.ts @@ -26,7 +26,7 @@ export const listTypesRoute = ( path: `${BASE_ACTION_API_PATH}/connector_types`, options: { access: 'public', - description: `Get connector types`, + summary: `Get connector types`, }, validate: { query: connectorTypesQuerySchemaV1, diff --git a/x-pack/plugins/actions/server/routes/create.ts b/x-pack/plugins/actions/server/routes/create.ts index 63cf948d318cd..a18cf4c61ef2c 100644 --- a/x-pack/plugins/actions/server/routes/create.ts +++ b/x-pack/plugins/actions/server/routes/create.ts @@ -55,7 +55,7 @@ export const createActionRoute = ( path: `${BASE_ACTION_API_PATH}/connector/{id?}`, options: { access: 'public', - description: 'Create a connector', + summary: 'Create a connector', }, validate: { params: schema.maybe( diff --git a/x-pack/plugins/actions/server/routes/delete.ts b/x-pack/plugins/actions/server/routes/delete.ts index c6a6c8afcbb72..950a3a8a60b17 100644 --- a/x-pack/plugins/actions/server/routes/delete.ts +++ b/x-pack/plugins/actions/server/routes/delete.ts @@ -25,7 +25,7 @@ export const deleteActionRoute = ( path: `${BASE_ACTION_API_PATH}/connector/{id}`, options: { access: 'public', - description: `Delete a connector`, + summary: `Delete a connector`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/actions/server/routes/execute.ts b/x-pack/plugins/actions/server/routes/execute.ts index d366feb7ce3ee..8b022e4d13f2c 100644 --- a/x-pack/plugins/actions/server/routes/execute.ts +++ b/x-pack/plugins/actions/server/routes/execute.ts @@ -41,7 +41,9 @@ export const executeActionRoute = ( path: `${BASE_ACTION_API_PATH}/connector/{id}/_execute`, options: { access: 'public', - description: `Run a connector`, + summary: `Run a connector`, + description: + 'You can use this API to test an action that involves interaction with Kibana services or integrations with third-party systems. You must have `read` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. If you use an index connector, you must also have `all`, `create`, `index`, or `write` indices privileges.', }, validate: { body: bodySchema, diff --git a/x-pack/plugins/actions/server/routes/legacy/create.ts b/x-pack/plugins/actions/server/routes/legacy/create.ts index bbdf528f21564..d4a7da1420f7f 100644 --- a/x-pack/plugins/actions/server/routes/legacy/create.ts +++ b/x-pack/plugins/actions/server/routes/legacy/create.ts @@ -31,7 +31,7 @@ export const createActionRoute = ( path: `${BASE_ACTION_API_PATH}/action`, options: { access: 'public', - description: `Create a connector`, + summary: `Create a connector`, }, validate: { body: bodySchema, diff --git a/x-pack/plugins/actions/server/routes/legacy/delete.ts b/x-pack/plugins/actions/server/routes/legacy/delete.ts index 57c4346084f57..0639019f73278 100644 --- a/x-pack/plugins/actions/server/routes/legacy/delete.ts +++ b/x-pack/plugins/actions/server/routes/legacy/delete.ts @@ -27,7 +27,7 @@ export const deleteActionRoute = ( path: `${BASE_ACTION_API_PATH}/action/{id}`, options: { access: 'public', - description: `Delete a connector`, + summary: `Delete a connector`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/actions/server/routes/legacy/execute.ts b/x-pack/plugins/actions/server/routes/legacy/execute.ts index f4ec794635263..ecf036617a28a 100644 --- a/x-pack/plugins/actions/server/routes/legacy/execute.ts +++ b/x-pack/plugins/actions/server/routes/legacy/execute.ts @@ -33,7 +33,7 @@ export const executeActionRoute = ( path: `${BASE_ACTION_API_PATH}/action/{id}/_execute`, options: { access: 'public', - description: `Run a connector`, + summary: `Run a connector`, }, validate: { body: bodySchema, diff --git a/x-pack/plugins/actions/server/routes/legacy/get.ts b/x-pack/plugins/actions/server/routes/legacy/get.ts index d47efc698c2fe..4c8d797205238 100644 --- a/x-pack/plugins/actions/server/routes/legacy/get.ts +++ b/x-pack/plugins/actions/server/routes/legacy/get.ts @@ -27,7 +27,7 @@ export const getActionRoute = ( path: `${BASE_ACTION_API_PATH}/action/{id}`, options: { access: 'public', - description: `Get connector information`, + summary: `Get connector information`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/actions/server/routes/legacy/get_all.ts b/x-pack/plugins/actions/server/routes/legacy/get_all.ts index 19fc32389c2ec..2ecd570cb3e76 100644 --- a/x-pack/plugins/actions/server/routes/legacy/get_all.ts +++ b/x-pack/plugins/actions/server/routes/legacy/get_all.ts @@ -22,7 +22,7 @@ export const getAllActionRoute = ( path: `${BASE_ACTION_API_PATH}`, options: { access: 'public', - description: `Get all connectors`, + summary: `Get all connectors`, }, validate: {}, }, diff --git a/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts b/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts index ef587d1ad11a6..fac078843e02d 100644 --- a/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts +++ b/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts @@ -26,7 +26,7 @@ export const listActionTypesRoute = ( path: `${BASE_ACTION_API_PATH}/list_action_types`, options: { access: 'public', - description: `Get connector types`, + summary: `Get connector types`, }, validate: {}, }, diff --git a/x-pack/plugins/actions/server/routes/legacy/update.ts b/x-pack/plugins/actions/server/routes/legacy/update.ts index 0959398dd1a69..59258434050e1 100644 --- a/x-pack/plugins/actions/server/routes/legacy/update.ts +++ b/x-pack/plugins/actions/server/routes/legacy/update.ts @@ -33,7 +33,7 @@ export const updateActionRoute = ( path: `${BASE_ACTION_API_PATH}/action/{id}`, options: { access: 'public', - description: `Update a connector`, + summary: `Update a connector`, }, validate: { body: bodySchema, diff --git a/x-pack/plugins/actions/server/routes/update.ts b/x-pack/plugins/actions/server/routes/update.ts index 68c7a8e9f9def..426deeb19aae3 100644 --- a/x-pack/plugins/actions/server/routes/update.ts +++ b/x-pack/plugins/actions/server/routes/update.ts @@ -51,7 +51,7 @@ export const updateActionRoute = ( path: `${BASE_ACTION_API_PATH}/connector/{id}`, options: { access: 'public', - description: `Update a connector`, + summary: `Update a connector`, }, validate: { body: bodySchema, diff --git a/x-pack/plugins/alerting/server/routes/disable_rule.ts b/x-pack/plugins/alerting/server/routes/disable_rule.ts index 6be1254fb9342..2b60cdbeedeaf 100644 --- a/x-pack/plugins/alerting/server/routes/disable_rule.ts +++ b/x-pack/plugins/alerting/server/routes/disable_rule.ts @@ -32,7 +32,7 @@ export const disableRuleRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}/_disable`, options: { access: 'public', - description: `Disable a rule`, + summary: `Disable a rule`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/alerting/server/routes/enable_rule.ts b/x-pack/plugins/alerting/server/routes/enable_rule.ts index 76c96fecaef5a..a6334a25138dc 100644 --- a/x-pack/plugins/alerting/server/routes/enable_rule.ts +++ b/x-pack/plugins/alerting/server/routes/enable_rule.ts @@ -24,7 +24,7 @@ export const enableRuleRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}/_enable`, options: { access: 'public', - description: `Enable a rule`, + summary: `Enable a rule`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/alerting/server/routes/health.ts b/x-pack/plugins/alerting/server/routes/health.ts index 5272876773b69..6d178e7bd186c 100644 --- a/x-pack/plugins/alerting/server/routes/health.ts +++ b/x-pack/plugins/alerting/server/routes/health.ts @@ -42,7 +42,7 @@ export const healthRoute = ( path: `${BASE_ALERTING_API_PATH}/_health`, options: { access: 'public', - description: `Get the health of the alerting framework`, + summary: `Get the health of the alerting framework`, }, validate: false, }, diff --git a/x-pack/plugins/alerting/server/routes/mute_all_rule.ts b/x-pack/plugins/alerting/server/routes/mute_all_rule.ts index ca1f31bae3cb2..185d44b95a50e 100644 --- a/x-pack/plugins/alerting/server/routes/mute_all_rule.ts +++ b/x-pack/plugins/alerting/server/routes/mute_all_rule.ts @@ -27,7 +27,7 @@ export const muteAllRuleRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}/_mute_all`, options: { access: 'public', - description: `Mute all alerts`, + summary: `Mute all alerts`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts index 7299da7e8dd39..5bb1eec92de26 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts @@ -34,7 +34,7 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt path: `${BASE_ALERTING_API_PATH}/rule/{id?}`, options: { access: 'public', - description: `Create a rule`, + summary: `Create a rule`, }, validate: { body: createBodySchemaV1, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts index bb862e3a7e5c9..3fe896cec9622 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts @@ -23,7 +23,7 @@ export const deleteRuleRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}`, options: { access: 'public', - description: `Delete a rule`, + summary: `Delete a rule`, }, validate: { params: deleteRuleRequestParamsSchemaV1, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts index ac2aa49956b3a..1cadb35969944 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts @@ -43,7 +43,7 @@ const buildFindRulesRoute = ({ path, options: { access: 'public', - description: `Get rules`, + summary: `Get rules`, }, validate: { query: findRulesRequestQuerySchemaV1, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts index 2764163641a97..e08c81a1d2e5c 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts @@ -78,7 +78,7 @@ export const getRuleRoute = ( router, options: { access: 'public', - description: `Get rule details`, + summary: `Get rule details`, }, }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts index 2e7747f53b1b4..91a254be09663 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts @@ -23,7 +23,7 @@ export const muteAlertRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{rule_id}/alert/{alert_id}/_mute`, options: { access: 'public', - description: `Mute an alert`, + summary: `Mute an alert`, }, validate: { params: muteAlertParamsSchemaV1, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts index 0edaf62ea7ddd..f13d3ac9ee31b 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts @@ -33,7 +33,7 @@ export const updateRuleRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}`, options: { access: 'public', - description: `Update a rule`, + summary: `Update a rule`, }, validate: { body: updateBodySchemaV1, diff --git a/x-pack/plugins/alerting/server/routes/rule_types.ts b/x-pack/plugins/alerting/server/routes/rule_types.ts index 5c20fc6df7d5d..1021b4c9a1431 100644 --- a/x-pack/plugins/alerting/server/routes/rule_types.ts +++ b/x-pack/plugins/alerting/server/routes/rule_types.ts @@ -57,7 +57,7 @@ export const ruleTypesRoute = ( path: `${BASE_ALERTING_API_PATH}/rule_types`, options: { access: 'public', - description: `Get rule types`, + summary: `Get rule types`, }, validate: {}, }, diff --git a/x-pack/plugins/alerting/server/routes/unmute_alert.ts b/x-pack/plugins/alerting/server/routes/unmute_alert.ts index 089f63911a902..b0d124e0d3945 100644 --- a/x-pack/plugins/alerting/server/routes/unmute_alert.ts +++ b/x-pack/plugins/alerting/server/routes/unmute_alert.ts @@ -34,7 +34,7 @@ export const unmuteAlertRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{rule_id}/alert/{alert_id}/_unmute`, options: { access: 'public', - description: `Unmute an alert`, + summary: `Unmute an alert`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts b/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts index 247f6377e4ad1..033f5b276828a 100644 --- a/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts +++ b/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts @@ -24,7 +24,7 @@ export const unmuteAllRuleRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}/_unmute_all`, options: { access: 'public', - description: `Unmute all alerts`, + summary: `Unmute all alerts`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts b/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts index 2838e206c92d7..8591f273eeeb3 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts @@ -24,7 +24,7 @@ export const updateRuleApiKeyRoute = ( path: `${BASE_ALERTING_API_PATH}/rule/{id}/_update_api_key`, options: { access: 'public', - description: `Update the API key for a rule`, + summary: `Update the API key for a rule`, }, validate: { params: paramSchema, diff --git a/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts index 6371b6ad546cd..e82c93039b2bc 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts @@ -21,7 +21,7 @@ export const getCasesByAlertIdRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Get cases for an alert`, + summary: `Get cases for an alert`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts index f36c13499aa70..a9b05c92e0f3d 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts @@ -16,7 +16,7 @@ export const deleteCaseRoute = createCasesRoute({ path: CASES_URL, routerOptions: { access: 'public', - description: `Delete cases`, + summary: `Delete cases`, }, params: { query: schema.object({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts index cfb5a7572894e..070bb4f125725 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts @@ -15,7 +15,7 @@ export const findCaseRoute = createCasesRoute({ path: `${CASES_URL}/_find`, routerOptions: { access: 'public', - description: `Search cases`, + summary: `Search cases`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts index c2522df7ddad7..b7557359b005e 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts @@ -32,7 +32,7 @@ export const getCaseRoute = createCasesRoute({ params, routerOptions: { access: 'public', - description: `Get a case`, + summary: `Get a case`, }, handler: async ({ context, request, response, logger, kibanaVersion }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts index 2ae12fba4111c..9a01378d0a86c 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts @@ -16,7 +16,7 @@ export const patchCaseRoute = createCasesRoute({ path: CASES_URL, routerOptions: { access: 'public', - description: `Update cases`, + summary: `Update cases`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/cases/post_case.ts b/x-pack/plugins/cases/server/routes/api/cases/post_case.ts index 5a65ed0851e91..f72819bf7536d 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/post_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/post_case.ts @@ -16,7 +16,7 @@ export const postCaseRoute = createCasesRoute({ path: CASES_URL, routerOptions: { access: 'public', - description: `Create a case`, + summary: `Create a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/cases/push_case.ts b/x-pack/plugins/cases/server/routes/api/cases/push_case.ts index d439b3f03dd79..2933a383aa13d 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/push_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/push_case.ts @@ -18,7 +18,7 @@ export const pushCaseRoute: CaseRoute = createCasesRoute({ path: CASE_PUSH_URL, routerOptions: { access: 'public', - description: `Push a case to an external service`, + summary: `Push a case to an external service`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts b/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts index 06ab468d9ce17..9945b5ffa13bf 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts @@ -15,7 +15,7 @@ export const getReportersRoute = createCasesRoute({ path: CASE_REPORTERS_URL, routerOptions: { access: 'public', - description: `Get all case creators`, + summary: `Get all case creators`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts b/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts index 366ba114c9d4e..1d34fb3e566b1 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts @@ -15,7 +15,7 @@ export const getTagsRoute = createCasesRoute({ path: CASE_TAGS_URL, routerOptions: { access: 'public', - description: `Get case tags`, + summary: `Get case tags`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts b/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts index c395f68fbb147..499b102dbed73 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts @@ -15,7 +15,7 @@ export const deleteAllCommentsRoute = createCasesRoute({ path: CASE_COMMENTS_URL, routerOptions: { access: 'public', - description: `Delete all alerts and comments from a case`, + summary: `Delete all alerts and comments from a case`, }, params: { params: schema.object({ diff --git a/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts index 47b9ad9992717..2d0e30bf49eca 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts @@ -22,7 +22,7 @@ export const deleteCommentRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Delete an alert or comment from a case`, + summary: `Delete an alert or comment from a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts b/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts index e5f18ba07610f..d44deffc1a9ae 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts @@ -22,7 +22,7 @@ export const findCommentsRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Get all alerts and comments for a case`, + summary: `Get all alerts and comments for a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts b/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts index bab7cd8971572..4de1d4690f3b3 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts @@ -22,7 +22,7 @@ export const getAllAlertsAttachedToCaseRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Get all alerts for a case`, + summary: `Get all alerts for a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts index a070c79541e1c..10f6b072636aa 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts @@ -28,7 +28,7 @@ export const getAllCommentsRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Gets all comments for a case`, + summary: `Gets all comments for a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts index e2f5968b66814..69382492ff40b 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts @@ -23,7 +23,7 @@ export const getCommentRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Get an alert or comment for a case`, + summary: `Get an alert or comment for a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts index 03fe0747f83df..ecd4bc6454e55 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts @@ -23,7 +23,7 @@ export const patchCommentRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Update an alert or comment in a case`, + summary: `Update an alert or comment in a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts index d2cbd96b880b9..8128439b74672 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts @@ -22,7 +22,7 @@ export const postCommentRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Add an alert or comment to a case`, + summary: `Add an alert or comment to a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts index fe5c65dd54ffa..e4d2c75689cd2 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts @@ -15,7 +15,7 @@ export const getCaseConfigureRoute = createCasesRoute({ path: CASE_CONFIGURE_URL, routerOptions: { access: 'public', - description: `Get case settings`, + summary: `Get case settings`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts b/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts index 53bc6d958115e..3201cb7005fb4 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts @@ -18,7 +18,7 @@ export const getConnectorsRoute = createCasesRoute({ routerOptions: { tags: ['access:casesGetConnectorsConfigure'], access: 'public', - description: `Get case connectors`, + summary: `Get case connectors`, }, handler: async ({ context, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts index dabc73325f286..c028013332866 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts @@ -17,7 +17,7 @@ export const patchCaseConfigureRoute = createCasesRoute({ path: CASE_CONFIGURE_DETAILS_URL, routerOptions: { access: 'public', - description: `Update case settings`, + summary: `Update case settings`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts index cf23dad956d16..6b6d6b1e48441 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts @@ -17,7 +17,7 @@ export const postCaseConfigureRoute = createCasesRoute({ path: CASE_CONFIGURE_URL, routerOptions: { access: 'public', - description: `Add case settings`, + summary: `Add case settings`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts index 5a39b2ce6eadc..1db0220365a02 100644 --- a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts +++ b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts @@ -21,7 +21,7 @@ export const getStatusRoute: CaseRoute = createCasesRoute({ options: { deprecated: true }, routerOptions: { access: 'public', - description: `Get case status summary`, + summary: `Get case status summary`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/user_actions/find_user_actions.ts b/x-pack/plugins/cases/server/routes/api/user_actions/find_user_actions.ts index bf43cdef22b4e..0a6c818cffa8b 100644 --- a/x-pack/plugins/cases/server/routes/api/user_actions/find_user_actions.ts +++ b/x-pack/plugins/cases/server/routes/api/user_actions/find_user_actions.ts @@ -22,7 +22,7 @@ export const findUserActionsRoute = createCasesRoute({ }, routerOptions: { access: 'public', - description: `Get user activity for a case`, + summary: `Get user activity for a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts index 7f42a340cd8be..e69e7197c1ece 100644 --- a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts +++ b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts @@ -26,7 +26,7 @@ export const getUserActionsRoute = createCasesRoute({ options: { deprecated: true }, routerOptions: { access: 'public', - description: `Get all user activity for a case`, + summary: `Get all user activity for a case`, }, handler: async ({ context, request, response }) => { try { diff --git a/x-pack/plugins/features/server/routes/index.ts b/x-pack/plugins/features/server/routes/index.ts index 621bf4a4b0e87..97273776df652 100644 --- a/x-pack/plugins/features/server/routes/index.ts +++ b/x-pack/plugins/features/server/routes/index.ts @@ -24,7 +24,7 @@ export function defineRoutes({ router, featureRegistry }: RouteDefinitionParams) options: { tags: ['access:features'], access: 'public', - description: `Get features`, + summary: `Get features`, }, validate: { query: schema.object({ ignoreValidLicenses: schema.boolean({ defaultValue: false }) }), diff --git a/x-pack/plugins/logstash/server/routes/pipeline/delete.ts b/x-pack/plugins/logstash/server/routes/pipeline/delete.ts index 83c6124b49e14..17de5261dc4b7 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/delete.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/delete.ts @@ -16,7 +16,7 @@ export function registerPipelineDeleteRoute(router: LogstashPluginRouter) { path: '/api/logstash/pipeline/{id}', options: { access: 'public', - description: `Delete a managed Logstash pipeline`, + summary: `Delete a managed Logstash pipeline`, }, validate: { params: schema.object({ diff --git a/x-pack/plugins/logstash/server/routes/pipeline/load.ts b/x-pack/plugins/logstash/server/routes/pipeline/load.ts index 33775866ccdec..cde032799b3f5 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/load.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/load.ts @@ -18,7 +18,7 @@ export function registerPipelineLoadRoute(router: LogstashPluginRouter) { path: '/api/logstash/pipeline/{id}', options: { access: 'public', - description: `Get a managed Logstash pipeline`, + summary: `Get a managed Logstash pipeline`, }, validate: { params: schema.object({ diff --git a/x-pack/plugins/logstash/server/routes/pipeline/save.ts b/x-pack/plugins/logstash/server/routes/pipeline/save.ts index c40bee2630c73..9e837bf9bd416 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/save.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/save.ts @@ -23,7 +23,7 @@ export function registerPipelineSaveRoute( path: '/api/logstash/pipeline/{id}', options: { access: 'public', - description: `Create a managed Logstash pipeline`, + summary: `Create a managed Logstash pipeline`, }, validate: { params: schema.object({ diff --git a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts index f6d3d795cdee6..edf235a7357b0 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts @@ -37,7 +37,7 @@ export function registerPipelinesDeleteRoute(router: LogstashPluginRouter) { { path: '/api/logstash/pipelines/delete', options: { - description: `Delete managed Logstash pipelines`, + summary: `Delete managed Logstash pipelines`, }, validate: { body: schema.object({ diff --git a/x-pack/plugins/logstash/server/routes/pipelines/list.ts b/x-pack/plugins/logstash/server/routes/pipelines/list.ts index e342acb72233b..30b4e1d08802c 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/list.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/list.ts @@ -28,7 +28,7 @@ export function registerPipelinesListRoute(router: LogstashPluginRouter) { { path: '/api/logstash/pipelines', options: { - description: `Get all managed Logstash pipelines`, + summary: `Get all managed Logstash pipelines`, }, validate: false, }, diff --git a/x-pack/plugins/ml/server/routes/saved_objects.ts b/x-pack/plugins/ml/server/routes/saved_objects.ts index a184a85eacd32..6d13b815ee338 100644 --- a/x-pack/plugins/ml/server/routes/saved_objects.ts +++ b/x-pack/plugins/ml/server/routes/saved_objects.ts @@ -78,7 +78,7 @@ export function savedObjectsRoutes( .get({ path: `${ML_EXTERNAL_BASE_PATH}/saved_objects/sync`, access: 'public', - description: 'Synchronize machine learning saved objects', + summary: 'Synchronize machine learning saved objects', options: { tags: [ 'access:ml:canCreateJob', diff --git a/x-pack/plugins/security/server/routes/authorization/roles/delete.ts b/x-pack/plugins/security/server/routes/authorization/roles/delete.ts index 9414646ef9e43..8a481c4b60cbf 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/delete.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/delete.ts @@ -16,7 +16,7 @@ export function defineDeleteRolesRoutes({ router }: RouteDefinitionParams) { { path: '/api/security/role/{name}', options: { - description: `Delete a role`, + summary: `Delete a role`, }, validate: { params: schema.object({ name: schema.string({ minLength: 1 }) }), diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get.ts b/x-pack/plugins/security/server/routes/authorization/roles/get.ts index e14ebd09c98ed..9109d89d956fd 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/get.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/get.ts @@ -22,7 +22,7 @@ export function defineGetRolesRoutes({ { path: '/api/security/role/{name}', options: { - description: `Get a role`, + summary: `Get a role`, }, validate: { params: schema.object({ name: schema.string({ minLength: 1 }) }), diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts b/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts index 5732f493bf25d..a7d995f0a2639 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts @@ -22,7 +22,7 @@ export function defineGetAllRolesRoutes({ { path: '/api/security/role', options: { - description: `Get all roles`, + summary: `Get all roles`, }, validate: false, }, diff --git a/x-pack/plugins/security/server/routes/authorization/roles/put.ts b/x-pack/plugins/security/server/routes/authorization/roles/put.ts index 337b0dc198b28..3a62b93819bd6 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/put.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.ts @@ -46,7 +46,7 @@ export function definePutRolesRoutes({ { path: '/api/security/role/{name}', options: { - description: `Create or update a role`, + summary: `Create or update a role`, }, validate: { params: schema.object({ name: schema.string({ minLength: 1, maxLength: 1024 }) }), diff --git a/x-pack/plugins/security/server/routes/session_management/invalidate.test.ts b/x-pack/plugins/security/server/routes/session_management/invalidate.test.ts index f1dad1c012f8c..ccd42b45718f8 100644 --- a/x-pack/plugins/security/server/routes/session_management/invalidate.test.ts +++ b/x-pack/plugins/security/server/routes/session_management/invalidate.test.ts @@ -44,7 +44,7 @@ describe('Invalidate sessions routes', () => { it('correctly defines route.', () => { expect(routeConfig.options).toEqual({ - description: 'Invalidate user sessions', + summary: 'Invalidate user sessions', tags: ['access:sessionManagement'], }); diff --git a/x-pack/plugins/security/server/routes/session_management/invalidate.ts b/x-pack/plugins/security/server/routes/session_management/invalidate.ts index 76a70a771b55c..1cf65bb9191c6 100644 --- a/x-pack/plugins/security/server/routes/session_management/invalidate.ts +++ b/x-pack/plugins/security/server/routes/session_management/invalidate.ts @@ -35,7 +35,7 @@ export function defineInvalidateSessionsRoutes({ router, getSession }: RouteDefi }, options: { tags: ['access:sessionManagement'], - description: `Invalidate user sessions`, + summary: `Invalidate user sessions`, }, }, async (_context, request, response) => { diff --git a/x-pack/plugins/task_manager/server/routes/health.ts b/x-pack/plugins/task_manager/server/routes/health.ts index 23539da937f93..38fd2e3b675ca 100644 --- a/x-pack/plugins/task_manager/server/routes/health.ts +++ b/x-pack/plugins/task_manager/server/routes/health.ts @@ -131,7 +131,7 @@ export function healthRoute(params: HealthRouteParams): { validate: false, options: { access: 'public', - description: `Get task manager health`, + summary: `Get task manager health`, }, }, async function ( diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts index 391306aa18723..d2eb315aa4a66 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts @@ -38,7 +38,7 @@ export function registerBatchReindexIndicesRoutes( path: `${BASE_PATH}/batch/queue`, options: { access: 'public', - description: `Get the batch reindex queue`, + summary: `Get the batch reindex queue`, }, validate: {}, }, @@ -77,7 +77,7 @@ export function registerBatchReindexIndicesRoutes( path: `${BASE_PATH}/batch`, options: { access: 'public', - description: `Batch start or resume reindex`, + summary: `Batch start or resume reindex`, }, validate: { body: schema.object({ diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts index 9b2b046169b77..11d34d48820e2 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts @@ -36,7 +36,7 @@ export function registerReindexIndicesRoutes( path: `${BASE_PATH}/{indexName}`, options: { access: 'public', - description: `Start or resume reindex`, + summary: `Start or resume reindex`, }, validate: { params: schema.object({ @@ -83,7 +83,7 @@ export function registerReindexIndicesRoutes( path: `${BASE_PATH}/{indexName}`, options: { access: 'public', - description: `Get reindex status`, + summary: `Get reindex status`, }, validate: { params: schema.object({ @@ -144,7 +144,7 @@ export function registerReindexIndicesRoutes( path: `${BASE_PATH}/{indexName}/cancel`, options: { access: 'public', - description: `Cancel reindex`, + summary: `Cancel reindex`, }, validate: { params: schema.object({ diff --git a/x-pack/plugins/upgrade_assistant/server/routes/status.ts b/x-pack/plugins/upgrade_assistant/server/routes/status.ts index 7a44981776319..de621da5a23b1 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/status.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/status.ts @@ -26,7 +26,7 @@ export function registerUpgradeStatusRoute({ path: `${API_BASE_PATH}/status`, options: { access: 'public', - description: `Get upgrade readiness status`, + summary: `Get upgrade readiness status`, }, validate: false, }, From 53b445833fa59cafd33ec86c40f61e5ae3770c18 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Thu, 6 Jun 2024 16:55:19 +0300 Subject: [PATCH 043/122] Add support for a declarative (via configuration) way to specify Kibana feature overrides (#180362) ## Summary This PR extends the features plugin to accept feature definition overrides via Kibana configuration. The functionality is limited to the Serverless offering only. Additionally, the PR updates Kibana serverless configurations to include overrides based on the "simplified feature toggles" proposals discussed with the solution teams. The configuration might look like this: ```yaml ## Fine-tune the feature privileges. xpack.features.overrides: dashboard: privileges: ### Dashboard's `All` feature privilege should implicitly ### grant `All` access to Maps and Visualize features. all.composedOf: - feature: "maps" privileges: [ "all" ] - feature: "visualize" privileges: [ "all" ] ### All Dashboard sub-feature privileges should be hidden: ### reporting capabilities will be granted via dedicated ### Reporting feature and short URL sub-feature privilege ### should be granted for both `All` and `Read`. subFeatures.privileges: download_csv_report.disabled: true url_create: disabled: true includeIn: "read" ### Maps feature is disabled since it's automatically granted by Dashboard feature. maps.disabled: true ``` ## How to test Log in as the `admin` using SAML and navigate to the `Custom roles` management section to edit role and see tuned role management UX:

![image](https://github.com/elastic/kibana/assets/1713708/5e27a49b-4382-4a91-bb85-eca929a27961) ### Search project ```bash yarn es serverless --projectType=es --ssl -E xpack.security.authc.native_roles.enabled=true yarn start --serverless=es --ssl --xpack.security.roleManagementEnabled=true ``` Refer to the proposal document, `config/serverless.yml`, and `config/serverless.es.yml` in this PR to see the specific changes made for your project type: ![image](https://github.com/elastic/kibana/assets/1713708/9f9d0341-32a1-4258-be3b-d3a809f5bacc) Create a custom `custom-search` role and re-login as the user with this role to test your project type (you need to manually type role name if the role selector):

### Observability project ```bash yarn es serverless --projectType=oblt --ssl -E xpack.security.authc.native_roles.enabled=true yarn start --serverless=oblt --ssl --xpack.security.roleManagementEnabled=true ``` Refer to the proposal document, `config/serverless.yml`, and `config/serverless.oblt.yml` in this PR to see the specific changes made for your project type: ![image](https://github.com/elastic/kibana/assets/1713708/1d2b360a-24ab-47f7-ac9b-8ad944949c32) Create a custom `custom-o11y` role and re-login as the user with this role to test your project type (you need to manually type role name if the role selector):

### Security project ```bash yarn es serverless --projectType=security --ssl -E xpack.security.authc.native_roles.enabled=true yarn start --serverless=security --ssl --xpack.security.roleManagementEnabled=true ``` Refer to the proposal document, `config/serverless.yml`, and `config/serverless.security.yml` in this PR to see the specific changes made for your project type: ![image](https://github.com/elastic/kibana/assets/1713708/2dbca002-59f1-44f0-9ab2-1dd205e48da8) Create a custom `custom-security` role and re-login as the user with this role to test your project type (you need to manually type role name if the role selector):

__Fixes: https://github.com/elastic/kibana/issues/178963__ --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 7 + config/serverless.es.yml | 16 + config/serverless.oblt.yml | 98 + config/serverless.security.yml | 37 + config/serverless.yml | 53 + .../common/feature_kibana_privileges.ts | 9 + .../feature_kibana_privileges_reference.ts | 20 + x-pack/plugins/features/common/index.ts | 1 + .../plugins/features/common/kibana_feature.ts | 11 + x-pack/plugins/features/common/sub_feature.ts | 2 +- x-pack/plugins/features/server/config.test.ts | 160 + x-pack/plugins/features/server/config.ts | 74 + .../features/server/feature_registry.test.ts | 265 + .../features/server/feature_registry.ts | 115 + .../plugins/features/server/feature_schema.ts | 2 + x-pack/plugins/features/server/index.ts | 5 +- x-pack/plugins/features/server/plugin.test.ts | 73 + x-pack/plugins/features/server/plugin.ts | 7 + x-pack/plugins/reporting/server/core.ts | 37 +- x-pack/plugins/reporting/server/features.ts | 74 + .../plugins/reporting/server/plugin.test.ts | 45 +- x-pack/plugins/reporting/server/plugin.ts | 10 +- .../roles/edit_role/edit_role_page.tsx | 2 +- .../kibana/feature_table/sub_feature_form.tsx | 4 +- .../roles/model/secured_sub_feature.ts | 40 +- .../roles/model/sub_feature_privilege.ts | 4 + .../privileges/privileges.test.ts | 942 +- .../authorization/privileges/privileges.ts | 91 +- .../security/server/lib/role_utils.test.ts | 168 +- .../plugins/security/server/lib/role_utils.ts | 29 +- .../common/platform_security/authorization.ts | 48 + .../observability/index.feature_flags.ts | 1 + .../platform_security/authorization.ts | 9585 +++++++++++++++++ .../observability/platform_security/index.ts | 14 + .../test_suites/search/index.feature_flags.ts | 1 + .../search/platform_security/authorization.ts | 1029 ++ .../search/platform_security/index.ts | 14 + .../security/index.feature_flags.ts | 1 + .../platform_security/authorization.ts | 2412 +++++ .../security/platform_security/index.ts | 14 + x-pack/test_serverless/tsconfig.json | 3 +- 41 files changed, 15408 insertions(+), 115 deletions(-) create mode 100644 x-pack/plugins/features/common/feature_kibana_privileges_reference.ts create mode 100644 x-pack/plugins/features/server/config.test.ts create mode 100644 x-pack/plugins/features/server/config.ts create mode 100644 x-pack/plugins/reporting/server/features.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/platform_security/index.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/search/platform_security/authorization.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/search/platform_security/index.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/platform_security/index.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d9a9f60eef539..322780e137b67 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1249,6 +1249,10 @@ x-pack/test/observability_ai_assistant_functional @elastic/obs-ai-assistant # Core /config/ @elastic/kibana-core +/config/serverless.yml @elastic/kibana-core @elastic/kibana-security +/config/serverless.es.yml @elastic/kibana-core @elastic/kibana-security +/config/serverless.oblt.yml @elastic/kibana-core @elastic/kibana-security +/config/serverless.security.yml @elastic/kibana-core @elastic/kibana-security /typings/ @elastic/kibana-core /test/analytics @elastic/kibana-core /packages/kbn-test/src/jest/setup/mocks.kbn_i18n_react.js @elastic/kibana-core @@ -1307,6 +1311,9 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/test/spaces_api_integration/ @elastic/kibana-security /x-pack/test/saved_object_api_integration/ @elastic/kibana-security /x-pack/test_serverless/**/test_suites/common/platform_security/ @elastic/kibana-security +/x-pack/test_serverless/**/test_suites/search/platform_security/ @elastic/kibana-security +/x-pack/test_serverless/**/test_suites/security/platform_security/ @elastic/kibana-security +/x-pack/test_serverless/**/test_suites/observability/platform_security/ @elastic/kibana-security /packages/core/http/core-http-server-internal/src/cdn_config/ @elastic/kibana-security @elastic/kibana-core #CC# /x-pack/plugins/security/ @elastic/kibana-security diff --git a/config/serverless.es.yml b/config/serverless.es.yml index ed71ce0d7819c..0a609b0d40b2c 100644 --- a/config/serverless.es.yml +++ b/config/serverless.es.yml @@ -12,6 +12,22 @@ xpack.serverless.observability.enabled: false enterpriseSearch.enabled: false xpack.fleet.enabled: false xpack.observabilityAIAssistant.enabled: false +xpack.osquery.enabled: false + +## Fine-tune the search solution feature privileges. Also, refer to `serverless.yml` for the project-agnostic overrides. +xpack.features.overrides: + ### Dashboards feature is moved from Analytics category to the Search one. + dashboard.category: "enterpriseSearch" + ### Dev Tools feature is moved from Analytics category to the Search one. + dev_tools.category: "enterpriseSearch" + ### Discover feature is moved from Analytics category to the Search one. + discover.category: "enterpriseSearch" + ### Machine Learning feature is moved from Analytics category to the Management one. + ml.category: "management" + ### Stack Alerts feature is moved from Analytics category to the Search one renamed to simply `Alerts`. + stackAlerts: + name: "Alerts" + category: "enterpriseSearch" ## Cloud settings xpack.cloud.serverless.project_type: search diff --git a/config/serverless.oblt.yml b/config/serverless.oblt.yml index 0d1add8e63f95..3cee8b352756e 100644 --- a/config/serverless.oblt.yml +++ b/config/serverless.oblt.yml @@ -8,6 +8,104 @@ xpack.uptime.enabled: true xpack.securitySolution.enabled: false xpack.search.notebooks.enabled: false +## Fine-tune the observability solution feature privileges. Also, refer to `serverless.yml` for the project-agnostic overrides. +xpack.features.overrides: + ### Applications feature privileges are fine-tuned to grant access to Logs, and Observability apps. + apm: + ### By default, this feature named as `APM and User Experience`, but should be renamed to `Applications`. + name: "Applications" + privileges: + # Infrastructure's `All` feature privilege should implicitly grant `All` access to Logs and Observability apps. + all.composedOf: + - feature: "logs" + privileges: [ "all" ] + - feature: "observability" + privileges: [ "all" ] + # Infrastructure's `Read` feature privilege should implicitly grant `Read` access to Logs and Observability apps. + read.composedOf: + - feature: "logs" + privileges: [ "read" ] + - feature: "observability" + privileges: [ "read" ] + ### Dashboards feature should be moved from Analytics category to the Observability one. + dashboard.category: "observability" + ### Discover feature should be moved from Analytics category to the Observability one and its privileges are + ### fine-tuned to grant access to Observability app. + discover: + category: "observability" + privileges: + # Discover `All` feature privilege should implicitly grant `All` access to Observability app. + all.composedOf: + - feature: "observability" + privileges: [ "all" ] + # Discover `Read` feature privilege should implicitly grant `Read` access to Observability app. + read.composedOf: + - feature: "observability" + privileges: [ "read" ] + ### Fleet feature privileges are fine-tuned to grant access to Logs app. + fleetv2: + privileges: + # Fleet `All` feature privilege should implicitly grant `All` access to Logs app. + all.composedOf: + - feature: "logs" + privileges: [ "all" ] + # Fleet `Read` feature privilege should implicitly grant `Read` access to Logs app. + read.composedOf: + - feature: "logs" + privileges: [ "read" ] + ### Infrastructure feature privileges are fine-tuned to grant access to Logs, and Observability apps. + infrastructure: + ### By default, this feature named as `Metrics`, but should be renamed to `Infrastructure`. + name: "Infrastructure" + privileges: + # Infrastructure's `All` feature privilege should implicitly grant `All` access to Logs and Observability apps. + all.composedOf: + - feature: "logs" + privileges: [ "all" ] + - feature: "observability" + privileges: [ "all" ] + # Infrastructure's `Read` feature privilege should implicitly grant `Read` access to Logs and Observability apps. + read.composedOf: + - feature: "logs" + privileges: [ "read" ] + - feature: "observability" + privileges: [ "read" ] + ### Logs feature is hidden in Role management since it's automatically granted by either Infrastructure, or Applications features. + logs.hidden: true + ### Machine Learning feature should be moved from Analytics category to the Observability one and renamed to `AI Ops`. + ml: + category: "observability" + order: 1200 + ### Observability feature is hidden in Role management since it's automatically granted by either Discover, + ### Infrastructure, Applications, Synthetics, or SLOs features. + observability.hidden: true + ### SLOs feature privileges are fine-tuned to grant access to Observability app. + slo: + privileges: + # SLOs `All` feature privilege should implicitly grant `All` access to Observability app. + all.composedOf: + - feature: "observability" + privileges: [ "all" ] + # SLOs `Read` feature privilege should implicitly grant `Read` access to Observability app. + read.composedOf: + - feature: "observability" + privileges: [ "read" ] + ### Stack alerts is hidden in Role management since it's not needed. + stackAlerts.hidden: true + ### Synthetics feature privileges are fine-tuned to grant access to Observability app. + uptime: + ### By default, this feature named as `Synthetics and Uptime`, but should be renamed to `Synthetics` since `Uptime` is not available. + name: "Synthetics" + privileges: + # Synthetics `All` feature privilege should implicitly grant `All` access to Observability app. + all.composedOf: + - feature: "observability" + privileges: [ "all" ] + # Synthetics `Read` feature privilege should implicitly grant `Read` access to Observability app. + read.composedOf: + - feature: "observability" + privileges: [ "read" ] + ## Enable the slo plugin xpack.slo.enabled: true diff --git a/config/serverless.security.yml b/config/serverless.security.yml index 88770178a3493..6f39182d1e2e6 100644 --- a/config/serverless.security.yml +++ b/config/serverless.security.yml @@ -9,6 +9,43 @@ xpack.observability.enabled: false xpack.observabilityAIAssistant.enabled: false xpack.search.notebooks.enabled: false +## Fine-tune the security solution feature privileges. Also, refer to `serverless.yml` for the project-agnostic overrides. +xpack.features.overrides: + ### Dashboard feature is hidden in Role management since it's automatically granted by SIEM feature. + dashboard.hidden: true + ### Discover feature is hidden in Role management since it's automatically granted by SIEM feature. + discover.hidden: true + ### Machine Learning feature is moved from Analytics category to the Security one as the last item. + ml: + category: "security" + order: 1101 + ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. + siem: + privileges: + ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and + ### Visualize features. + all.composedOf: + - feature: "discover" + privileges: [ "all" ] + - feature: "dashboard" + privileges: [ "all" ] + - feature: "visualize" + privileges: [ "all" ] + - feature: "maps" + privileges: [ "all" ] + # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and + # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, + ### Dashboard, and Visualize apps. + read.composedOf: + - feature: "discover" + privileges: [ "read" ] + - feature: "dashboard" + privileges: [ "read" ] + - feature: "visualize" + privileges: [ "read" ] + - feature: "maps" + privileges: [ "read" ] + ## Cloud settings xpack.cloud.serverless.project_type: security diff --git a/config/serverless.yml b/config/serverless.yml index 43ac498e0901d..6631441e3b5dd 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -8,6 +8,59 @@ xpack.fleet.internal.activeAgentsSoftLimit: 25000 xpack.fleet.internal.onlyAllowAgentUpgradeToKnownVersions: true xpack.fleet.internal.retrySetupOnBoot: true +## Fine-tune the feature privileges. +xpack.features.overrides: + dashboard: + privileges: + ### Dashboard's `All` feature privilege should implicitly grant `All` access to Maps and Visualize features. + all.composedOf: + - feature: "maps" + privileges: [ "all" ] + - feature: "visualize" + privileges: [ "all" ] + ### Dashboard's `Read` feature privilege should implicitly grant `Read` access to Maps and Visualize features. + ### Additionally, it should implicitly grant privilege to create short URLs in Visualize app. + read.composedOf: + - feature: "maps" + privileges: [ "read" ] + - feature: "visualize" + privileges: [ "read" ] + ### All Dashboard sub-feature privileges should be hidden: reporting capabilities will be granted via dedicated + ### Reporting feature and short URL sub-feature privilege should be granted for both `All` and `Read`. + subFeatures.privileges: + download_csv_report.disabled: true + generate_report.disabled: true + store_search_session.disabled: true + url_create: + disabled: true + includeIn: "read" + discover: + ### All Discover sub-feature privileges should be hidden: reporting capabilities will be granted via dedicated + ### Reporting feature and short URL sub-feature privilege should be granted for both `All` and `Read`. + subFeatures.privileges: + generate_report.disabled: true + store_search_session.disabled: true + url_create: + disabled: true + includeIn: "read" + ### Shared images feature is hidden in Role management since it's not needed. + filesSharedImage.hidden: true + ### Maps feature is hidden in Role management since it's automatically granted by Dashboard feature. + maps.hidden: true + ### Reporting feature is supposed to give access to reporting capabilities across different features. + reporting: + privileges: + all.composedOf: + - feature: "dashboard" + privileges: [ "download_csv_report" ] + - feature: "discover" + privileges: [ "generate_report" ] + ### Visualize feature is hidden in Role management since it's automatically granted by Dashboard feature. + visualize: + hidden: true + ### The short URL sub-feature privilege should be always granted. + subFeatures.privileges.url_create.includeIn: "read" + # Cloud links xpack.cloud.base_url: 'https://cloud.elastic.co' diff --git a/x-pack/plugins/features/common/feature_kibana_privileges.ts b/x-pack/plugins/features/common/feature_kibana_privileges.ts index 49c001c890b69..54913e08223c5 100644 --- a/x-pack/plugins/features/common/feature_kibana_privileges.ts +++ b/x-pack/plugins/features/common/feature_kibana_privileges.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { FeatureKibanaPrivilegesReference } from './feature_kibana_privileges_reference'; + /** * Feature privilege definition */ @@ -263,4 +265,11 @@ export interface FeatureKibanaPrivileges { * @see UICapabilities */ ui: readonly string[]; + + /** + * An optional list of other registered feature or sub-feature privileges that this privilege is composed of. When + * privilege is registered with Elasticsearch, it will be expanded to grant everything that referenced privileges + * grant. This property can only be set in the feature configuration overrides. + */ + composedOf?: readonly FeatureKibanaPrivilegesReference[]; } diff --git a/x-pack/plugins/features/common/feature_kibana_privileges_reference.ts b/x-pack/plugins/features/common/feature_kibana_privileges_reference.ts new file mode 100644 index 0000000000000..3835579fbdb59 --- /dev/null +++ b/x-pack/plugins/features/common/feature_kibana_privileges_reference.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. + */ + +/** + * Defines a reference to a set of privileges of a specific feature. + */ +export interface FeatureKibanaPrivilegesReference { + /** + * The ID of the feature. + */ + feature: string; + /** + * The set of IDs of feature or sub-feature privileges provided by the feature. + */ + privileges: readonly string[]; +} diff --git a/x-pack/plugins/features/common/index.ts b/x-pack/plugins/features/common/index.ts index 9db2a1073cd07..92cbcd76172d0 100644 --- a/x-pack/plugins/features/common/index.ts +++ b/x-pack/plugins/features/common/index.ts @@ -18,3 +18,4 @@ export type { SubFeaturePrivilegeGroupType, } from './sub_feature'; export { SubFeature } from './sub_feature'; +export type { FeatureKibanaPrivilegesReference } from './feature_kibana_privileges_reference'; diff --git a/x-pack/plugins/features/common/kibana_feature.ts b/x-pack/plugins/features/common/kibana_feature.ts index debcec588dee0..926aca01627a2 100644 --- a/x-pack/plugins/features/common/kibana_feature.ts +++ b/x-pack/plugins/features/common/kibana_feature.ts @@ -142,6 +142,13 @@ export interface KibanaFeatureConfig { description: string; privileges: readonly ReservedKibanaPrivilege[]; }; + + /** + * Indicates whether the feature is available as a standalone feature. The feature can still be + * referenced by other features, but it will not be displayed in any feature management UIs. By default, all features + * are visible. + */ + hidden?: boolean; } export class KibanaFeature { @@ -157,6 +164,10 @@ export class KibanaFeature { return this.config.id; } + public get hidden() { + return this.config.hidden; + } + public get name() { return this.config.name; } diff --git a/x-pack/plugins/features/common/sub_feature.ts b/x-pack/plugins/features/common/sub_feature.ts index e51fc42195797..a87dc2343e16d 100644 --- a/x-pack/plugins/features/common/sub_feature.ts +++ b/x-pack/plugins/features/common/sub_feature.ts @@ -70,7 +70,7 @@ export interface SubFeaturePrivilegeGroupConfig { * Configuration for a sub-feature privilege. */ export interface SubFeaturePrivilegeConfig - extends Omit { + extends Omit { /** * Identifier for this privilege. Must be unique across all other privileges within a feature. */ diff --git a/x-pack/plugins/features/server/config.test.ts b/x-pack/plugins/features/server/config.test.ts new file mode 100644 index 0000000000000..096a7f8b9477e --- /dev/null +++ b/x-pack/plugins/features/server/config.test.ts @@ -0,0 +1,160 @@ +/* + * 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 { ConfigSchema } from './config'; +import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; + +describe('config schema', () => { + it('generates proper defaults (no overrides)', () => { + expect(ConfigSchema.validate({})).toMatchInlineSnapshot(`Object {}`); + expect(ConfigSchema.validate({}, { serverless: true })).toMatchInlineSnapshot(`Object {}`); + }); + + it('does not allow overrides in non-serverless', () => { + expect(() => + ConfigSchema.validate( + { overrides: { featureA: { name: 'new name' } } }, + { serverless: false } + ) + ).toThrowErrorMatchingInlineSnapshot(`"[overrides]: a value wasn't expected to be present"`); + expect( + ConfigSchema.validate({ overrides: { featureA: { name: 'new name' } } }, { serverless: true }) + ).toMatchInlineSnapshot(` + Object { + "overrides": Object { + "featureA": Object { + "name": "new name", + }, + }, + } + `); + }); + + it('can override feature properties', () => { + expect( + ConfigSchema.validate( + { + overrides: { + featureA: { name: 'new name', hidden: true }, + featureB: { + order: 100, + category: 'management', + privileges: { + all: { + disabled: true, + }, + read: { + composedOf: [{ feature: 'featureC', privileges: ['all', 'read'] }], + }, + }, + }, + featureC: { + subFeatures: { + privileges: { + subOne: { + disabled: true, + includeIn: 'all', + }, + subTwo: { + includeIn: 'none', + }, + }, + }, + }, + }, + }, + { serverless: true } + ) + ).toMatchInlineSnapshot(` + Object { + "overrides": Object { + "featureA": Object { + "hidden": true, + "name": "new name", + }, + "featureB": Object { + "category": "management", + "order": 100, + "privileges": Object { + "all": Object { + "disabled": true, + }, + "read": Object { + "composedOf": Array [ + Object { + "feature": "featureC", + "privileges": Array [ + "all", + "read", + ], + }, + ], + }, + }, + }, + "featureC": Object { + "subFeatures": Object { + "privileges": Object { + "subOne": Object { + "disabled": true, + "includeIn": "all", + }, + "subTwo": Object { + "includeIn": "none", + }, + }, + }, + }, + }, + } + `); + }); + + it('properly validates category override', () => { + for (const category of Object.keys(DEFAULT_APP_CATEGORIES)) { + expect( + ConfigSchema.validate({ overrides: { featureA: { category } } }, { serverless: true }) + .overrides?.featureA.category + ).toBe(category); + } + + expect(() => + ConfigSchema.validate( + { overrides: { featureA: { category: 'unknown' } } }, + { serverless: true } + ) + ).toThrowErrorMatchingInlineSnapshot( + `"[overrides.featureA.category]: Unknown category \\"unknown\\". Should be one of kibana, enterpriseSearch, observability, security, management"` + ); + }); + it('properly validates sub-feature privilege inclusion override', () => { + for (const includeIn of ['all', 'read', 'none']) { + expect( + ConfigSchema.validate( + { overrides: { featureA: { subFeatures: { privileges: { subOne: { includeIn } } } } } }, + { serverless: true } + ).overrides?.featureA.subFeatures?.privileges.subOne.includeIn + ).toBe(includeIn); + } + + expect(() => + ConfigSchema.validate( + { + overrides: { + featureA: { subFeatures: { privileges: { subOne: { includeIn: 'write' } } } }, + }, + }, + { serverless: true } + ) + ).toThrowErrorMatchingInlineSnapshot(` + "[overrides.featureA.subFeatures.privileges.subOne.includeIn]: types that failed validation: + - [includeIn.0]: expected value to equal [all] + - [includeIn.1]: expected value to equal [read] + - [includeIn.2]: expected value to equal [none]" + `); + }); +}); diff --git a/x-pack/plugins/features/server/config.ts b/x-pack/plugins/features/server/config.ts new file mode 100644 index 0000000000000..c4941b0eef90e --- /dev/null +++ b/x-pack/plugins/features/server/config.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { offeringBasedSchema, schema, type TypeOf } from '@kbn/config-schema'; +import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; + +const privilegeOverrideSchema = schema.maybe( + schema.object({ + disabled: schema.maybe(schema.boolean()), + composedOf: schema.maybe( + schema.arrayOf( + schema.object({ + feature: schema.string(), + privileges: schema.arrayOf(schema.string()), + }) + ) + ), + }) +); + +export type ConfigType = TypeOf; +export type ConfigOverridesType = Required['overrides']; +export const ConfigSchema = schema.object({ + overrides: offeringBasedSchema({ + // Overrides are only exposed in Serverless offering. + serverless: schema.maybe( + // Key is the feature ID, value is a set of feature properties to override. + schema.recordOf( + schema.string(), + schema.object({ + hidden: schema.maybe(schema.boolean()), + name: schema.maybe(schema.string({ minLength: 1 })), + category: schema.maybe( + schema.string({ + validate(categoryName) { + if (!Object.hasOwn(DEFAULT_APP_CATEGORIES, categoryName)) { + return `Unknown category "${categoryName}". Should be one of ${Object.keys( + DEFAULT_APP_CATEGORIES + ).join(', ')}`; + } + }, + }) + ), + order: schema.maybe(schema.number()), + privileges: schema.maybe( + schema.object({ all: privilegeOverrideSchema, read: privilegeOverrideSchema }) + ), + subFeatures: schema.maybe( + schema.object({ + // Key is the ID of the sub-feature privilege, value is a set of privilege properties to override. + privileges: schema.recordOf( + schema.string(), + schema.object({ + disabled: schema.maybe(schema.boolean()), + includeIn: schema.maybe( + schema.oneOf([ + schema.literal('all'), + schema.literal('read'), + schema.literal('none'), + ]) + ), + }) + ), + }) + ), + }) + ) + ), + }), +}); diff --git a/x-pack/plugins/features/server/feature_registry.test.ts b/x-pack/plugins/features/server/feature_registry.test.ts index e0d0591c67d88..f27c93ac9129e 100644 --- a/x-pack/plugins/features/server/feature_registry.test.ts +++ b/x-pack/plugins/features/server/feature_registry.test.ts @@ -8,6 +8,7 @@ import { FeatureRegistry } from './feature_registry'; import { ElasticsearchFeatureConfig, KibanaFeatureConfig } from '../common'; import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; +import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; describe('FeatureRegistry', () => { describe('Kibana Features', () => { @@ -1930,6 +1931,270 @@ describe('FeatureRegistry', () => { expect(withSubFeature.subFeatures[0].privilegeGroups[0].privileges).toHaveLength(0); }); }); + + describe('#applyOverrides', () => { + let registry: FeatureRegistry; + beforeEach(() => { + registry = new FeatureRegistry(); + const features: KibanaFeatureConfig[] = [ + { + id: 'featureA', + name: 'Feature A', + app: [], + order: 1, + category: { id: 'fooA', label: 'fooA' }, + privileges: { + all: { ui: [], savedObject: { all: [], read: [] } }, + read: { ui: [], savedObject: { all: [], read: [] } }, + }, + }, + { + id: 'featureB', + name: 'Feature B', + app: [], + order: 2, + category: { id: 'fooB', label: 'fooB' }, + privileges: null, + }, + { + id: 'featureC', + name: 'Feature C', + app: [], + order: 1, + category: { id: 'fooC', label: 'fooC' }, + privileges: { + all: { ui: [], savedObject: { all: [], read: [] } }, + read: { ui: [], savedObject: { all: [], read: [] } }, + }, + subFeatures: [ + { + name: 'subFeatureC', + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + id: 'subFeatureCOne', + name: 'subFeature C One', + includeIn: 'all', + ui: [], + savedObject: { all: [], read: [] }, + }, + ], + }, + ], + }, + ], + }, + { + id: 'featureD', + name: 'Feature D', + app: [], + order: 1, + category: { id: 'fooD', label: 'fooD' }, + privileges: { + all: { ui: [], savedObject: { all: [], read: [] } }, + read: { ui: [], savedObject: { all: [], read: [] } }, + }, + }, + { + id: 'featureE', + name: 'Feature E', + app: [], + order: 1, + category: { id: 'fooE', label: 'fooE' }, + privileges: { + all: { + ui: [], + savedObject: { all: [], read: [] }, + alerting: { alert: { all: ['one'] } }, + }, + read: { ui: [], savedObject: { all: [], read: [] } }, + }, + alerting: ['one'], + }, + ]; + features.forEach((f) => registry.registerKibanaFeature(f)); + }); + + it('rejects overrides for unknown features', () => { + expect(() => + registry.applyOverrides({ unknownFeature: {} }) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot override feature \\"unknownFeature\\" since feature with such ID is not registered."` + ); + }); + + it('can override basic feature properties', () => { + registry.applyOverrides({ + featureA: { + hidden: true, + name: 'Feature A New', + category: 'management', + order: 123, + }, + }); + registry.lockRegistration(); + + const [featureA, featureB] = registry.getAllKibanaFeatures(); + expect(featureA.hidden).toBe(true); + expect(featureB.hidden).toBeUndefined(); + + expect(featureA.name).toBe('Feature A New'); + expect(featureB.name).toBe('Feature B'); + + expect(featureA.category).toEqual(DEFAULT_APP_CATEGORIES.management); + expect(featureB.category).toEqual({ id: 'fooB', label: 'fooB' }); + + expect(featureA.order).toBe(123); + expect(featureB.order).toBe(2); + }); + + it('rejects overrides for unknown privileges', () => { + expect(() => + registry.applyOverrides({ featureB: { privileges: { all: { disabled: true } } } }) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot override privilege \\"all\\" of feature \\"featureB\\" since \\"all\\" privilege is not registered."` + ); + }); + + it('rejects overrides for `composedOf` referring to unknown feature', () => { + expect(() => + registry.applyOverrides({ + featureA: { + privileges: { + all: { composedOf: [{ feature: 'featureF', privileges: ['all'] }] }, + }, + }, + }) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot compose privilege \\"all\\" of feature \\"featureA\\" with privileges of feature \\"featureF\\" since such feature is not registered."` + ); + }); + + it('rejects overrides for `composedOf` referring to unknown feature privilege', () => { + expect(() => + registry.applyOverrides({ + featureA: { + privileges: { + all: { composedOf: [{ feature: 'featureB', privileges: ['none'] }] }, + }, + }, + }) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot compose privilege \\"all\\" of feature \\"featureA\\" with privilege \\"none\\" of feature \\"featureB\\" since such privilege is not registered."` + ); + }); + + it('can override `composedOf` referring to both feature and sub-feature privileges', () => { + registry.applyOverrides({ + featureA: { + privileges: { + all: { + composedOf: [ + { feature: 'featureC', privileges: ['subFeatureCOne'] }, + { feature: 'featureD', privileges: ['all'] }, + ], + }, + read: { composedOf: [{ feature: 'featureD', privileges: ['read'] }] }, + }, + }, + }); + registry.lockRegistration(); + + const [featureA] = registry.getAllKibanaFeatures(); + expect(featureA.privileges).toEqual({ + all: { + ui: [], + savedObject: { all: ['telemetry'], read: ['config', 'config-global', 'url'] }, + composedOf: [ + { feature: 'featureC', privileges: ['subFeatureCOne'] }, + { feature: 'featureD', privileges: ['all'] }, + ], + }, + read: { + ui: [], + savedObject: { all: [], read: ['config', 'config-global', 'telemetry', 'url'] }, + composedOf: [{ feature: 'featureD', privileges: ['read'] }], + }, + }); + }); + + it('can override `composedOf` referring to a feature that requires custom RBAC', () => { + registry.applyOverrides({ + featureA: { + privileges: { + all: { composedOf: [{ feature: 'featureE', privileges: ['all'] }] }, + }, + }, + }); + registry.lockRegistration(); + + const [featureA] = registry.getAllKibanaFeatures(); + expect(featureA.privileges).toEqual({ + all: { + ui: [], + savedObject: { all: ['telemetry'], read: ['config', 'config-global', 'url'] }, + composedOf: [{ feature: 'featureE', privileges: ['all'] }], + }, + read: { + ui: [], + savedObject: { all: [], read: ['config', 'config-global', 'telemetry', 'url'] }, + }, + }); + }); + + it('rejects overrides for unknown sub-feature privileges', () => { + expect(() => + registry.applyOverrides({ + featureC: { subFeatures: { privileges: { all: { disabled: true } } } }, + }) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot override sub-feature privilege \\"all\\" of feature \\"featureC\\" since \\"all\\" sub-feature privilege is not registered. Known sub-feature privileges are: subFeatureCOne."` + ); + + expect(() => + registry.applyOverrides({ + featureA: { subFeatures: { privileges: { subFeatureCOne: { disabled: true } } } }, + }) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot override sub-feature privileges of feature \\"featureA\\" since it didn't register any."` + ); + }); + + it('can override sub-feature privileges', () => { + registry.applyOverrides({ + featureC: { + subFeatures: { privileges: { subFeatureCOne: { disabled: true, includeIn: 'none' } } }, + }, + }); + registry.lockRegistration(); + + const [, , featureC] = registry.getAllKibanaFeatures(); + expect(featureC.subFeatures).toEqual([ + { + config: { + name: 'subFeatureC', + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + disabled: true, + id: 'subFeatureCOne', + includeIn: 'none', + name: 'subFeature C One', + savedObject: { all: [], read: [] }, + ui: [], + }, + ], + }, + ], + }, + }, + ]); + }); + }); }); describe('Elasticsearch Features', () => { diff --git a/x-pack/plugins/features/server/feature_registry.ts b/x-pack/plugins/features/server/feature_registry.ts index 40c278b2fe4ed..4726335ee3d01 100644 --- a/x-pack/plugins/features/server/feature_registry.ts +++ b/x-pack/plugins/features/server/feature_registry.ts @@ -7,14 +7,17 @@ import { cloneDeep, uniq } from 'lodash'; import { ILicense } from '@kbn/licensing-plugin/server'; +import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; import { KibanaFeatureConfig, KibanaFeature, FeatureKibanaPrivileges, ElasticsearchFeatureConfig, ElasticsearchFeature, + SubFeaturePrivilegeConfig, } from '../common'; import { validateKibanaFeature, validateElasticsearchFeature } from './feature_schema'; +import type { ConfigOverridesType } from './config'; export class FeatureRegistry { private locked = false; @@ -61,6 +64,106 @@ export class FeatureRegistry { this.esFeatures[feature.id] = featureCopy; } + /** + * Updates definitions for the registered features using configuration overrides, if any. + */ + public applyOverrides(overrides: ConfigOverridesType) { + for (const [featureId, featureOverride] of Object.entries(overrides)) { + const feature = this.kibanaFeatures[featureId]; + if (!feature) { + throw new Error( + `Cannot override feature "${featureId}" since feature with such ID is not registered.` + ); + } + + if (featureOverride.hidden) { + feature.hidden = featureOverride.hidden; + } + + // Note that the name doesn't currently support localizable strings. We'll revisit this approach when i18n support + // becomes necessary. + if (featureOverride.name) { + feature.name = featureOverride.name; + } + + if (featureOverride.category) { + feature.category = DEFAULT_APP_CATEGORIES[featureOverride.category]; + } + + if (featureOverride.order != null) { + feature.order = featureOverride.order; + } + + if (featureOverride.privileges) { + for (const [privilegeId, privilegeOverride] of Object.entries(featureOverride.privileges)) { + const typedPrivilegeId = privilegeId as 'read' | 'all'; + const targetPrivilege = feature.privileges?.[typedPrivilegeId]; + if (!targetPrivilege) { + throw new Error( + `Cannot override privilege "${privilegeId}" of feature "${featureId}" since "${privilegeId}" privilege is not registered.` + ); + } + + for (const featureReference of privilegeOverride.composedOf ?? []) { + const referencedFeature = this.kibanaFeatures[featureReference.feature]; + if (!referencedFeature) { + throw new Error( + `Cannot compose privilege "${privilegeId}" of feature "${featureId}" with privileges of feature "${featureReference.feature}" since such feature is not registered.` + ); + } + + // Collect all known feature and sub-feature privileges for the referenced feature. + const knownPrivileges = new Map( + Object.entries(referencedFeature.privileges ?? {}).concat( + collectSubFeaturesPrivileges(referencedFeature) + ) + ); + + for (const privilegeReference of featureReference.privileges) { + const referencedPrivilege = knownPrivileges.get(privilegeReference); + if (!referencedPrivilege) { + throw new Error( + `Cannot compose privilege "${privilegeId}" of feature "${featureId}" with privilege "${privilegeReference}" of feature "${featureReference.feature}" since such privilege is not registered.` + ); + } + } + } + + // It's safe to assume that `feature.privileges` is defined here since we've checked it above. + feature.privileges![typedPrivilegeId] = { ...targetPrivilege, ...privilegeOverride }; + } + } + + if (featureOverride.subFeatures?.privileges) { + // Collect all known sub-feature privileges for the feature. + const knownPrivileges = new Map(collectSubFeaturesPrivileges(feature)); + if (knownPrivileges.size === 0) { + throw new Error( + `Cannot override sub-feature privileges of feature "${featureId}" since it didn't register any.` + ); + } + + for (const [privilegeId, privilegeOverride] of Object.entries( + featureOverride.subFeatures.privileges + )) { + const targetPrivilege = knownPrivileges.get(privilegeId); + if (!targetPrivilege) { + throw new Error( + `Cannot override sub-feature privilege "${privilegeId}" of feature "${featureId}" since "${privilegeId}" sub-feature privilege is not registered. Known sub-feature privileges are: ${Array.from( + knownPrivileges.keys() + )}.` + ); + } + + targetPrivilege.disabled = privilegeOverride.disabled; + if (privilegeOverride.includeIn) { + targetPrivilege.includeIn = privilegeOverride.includeIn; + } + } + } + } + } + public getAllKibanaFeatures(license?: ILicense, ignoreLicense = false): KibanaFeature[] { if (!this.locked) { throw new Error('Cannot retrieve Kibana features while registration is still open'); @@ -143,3 +246,15 @@ function applyAutomaticReadPrivilegeGrants( } }); } + +function collectSubFeaturesPrivileges(feature: KibanaFeatureConfig) { + return ( + feature.subFeatures?.flatMap((subFeature) => + subFeature.privilegeGroups.flatMap(({ privileges }) => + privileges.map( + (privilege) => [privilege.id, privilege] as [string, SubFeaturePrivilegeConfig] + ) + ) + ) ?? [] + ); +} diff --git a/x-pack/plugins/features/server/feature_schema.ts b/x-pack/plugins/features/server/feature_schema.ts index b332ea355dcc0..341bb926b277d 100644 --- a/x-pack/plugins/features/server/feature_schema.ts +++ b/x-pack/plugins/features/server/feature_schema.ts @@ -187,6 +187,8 @@ const kibanaSubFeatureSchema = schema.object({ ), }); +// NOTE: This schema intentionally omits the `composedOf` and `hidden` properties to discourage consumers from using +// them during feature registration. This is because these properties should only be set via configuration overrides. const kibanaFeatureSchema = schema.object({ id: schema.string({ validate(value: string) { diff --git a/x-pack/plugins/features/server/index.ts b/x-pack/plugins/features/server/index.ts index b40094dee92d4..48c292515ed27 100644 --- a/x-pack/plugins/features/server/index.ts +++ b/x-pack/plugins/features/server/index.ts @@ -5,7 +5,9 @@ * 2.0. */ -import { PluginInitializerContext } from '@kbn/core/server'; +import type { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server'; +import type { TypeOf } from '@kbn/config-schema'; +import { ConfigSchema } from './config'; // These exports are part of public Features plugin contract, any change in signature of exported // functions or removal of exports should be considered as a breaking change. Ideally we should @@ -22,6 +24,7 @@ export type { export { KibanaFeature, ElasticsearchFeature } from '../common'; export type { PluginSetupContract, PluginStartContract } from './plugin'; +export const config: PluginConfigDescriptor> = { schema: ConfigSchema }; export const plugin = async (initializerContext: PluginInitializerContext) => { const { FeaturesPlugin } = await import('./plugin'); return new FeaturesPlugin(initializerContext); diff --git a/x-pack/plugins/features/server/plugin.test.ts b/x-pack/plugins/features/server/plugin.test.ts index ca88da0458846..d353ee0588d5f 100644 --- a/x-pack/plugins/features/server/plugin.test.ts +++ b/x-pack/plugins/features/server/plugin.test.ts @@ -6,6 +6,7 @@ */ import { coreMock, savedObjectsServiceMock } from '@kbn/core/server/mocks'; +import { ConfigSchema } from './config'; import { FeaturesPlugin } from './plugin'; describe('Features Plugin', () => { @@ -120,4 +121,76 @@ describe('Features Plugin', () => { expect(coreSetup.capabilities.registerProvider).toHaveBeenCalledTimes(1); expect(coreSetup.capabilities.registerProvider).toHaveBeenCalledWith(expect.any(Function)); }); + + it('apply feature overrides', async () => { + const plugin = new FeaturesPlugin( + coreMock.createPluginInitializerContext( + ConfigSchema.validate( + { overrides: { featureA: { name: 'overriddenFeatureName', order: 321 } } }, + { serverless: true } + ) + ) + ); + const { registerKibanaFeature } = plugin.setup(coreSetup); + registerKibanaFeature({ + id: 'featureA', + name: 'featureAName', + app: [], + category: { id: 'foo', label: 'foo' }, + order: 123, + privileges: { + all: { savedObject: { all: ['one'], read: ['two'] }, ui: [] }, + read: { savedObject: { all: ['three'], read: ['four'] }, ui: [] }, + }, + }); + + const { getKibanaFeatures } = plugin.start(coreStart); + expect(getKibanaFeatures().find((feature) => feature.id === 'featureA')).toMatchInlineSnapshot(` + KibanaFeature { + "config": Object { + "app": Array [], + "category": Object { + "id": "foo", + "label": "foo", + }, + "id": "featureA", + "name": "overriddenFeatureName", + "order": 321, + "privileges": Object { + "all": Object { + "savedObject": Object { + "all": Array [ + "one", + "telemetry", + ], + "read": Array [ + "two", + "config", + "config-global", + "url", + ], + }, + "ui": Array [], + }, + "read": Object { + "savedObject": Object { + "all": Array [ + "three", + ], + "read": Array [ + "four", + "config", + "config-global", + "telemetry", + "url", + ], + }, + "ui": Array [], + }, + }, + }, + "subFeatures": Array [], + } + `); + }); }); diff --git a/x-pack/plugins/features/server/plugin.ts b/x-pack/plugins/features/server/plugin.ts index b396dc9a17972..c6e8cdd96556c 100644 --- a/x-pack/plugins/features/server/plugin.ts +++ b/x-pack/plugins/features/server/plugin.ts @@ -16,6 +16,7 @@ import { PluginInitializerContext, Capabilities as UICapabilities, } from '@kbn/core/server'; +import { ConfigType } from './config'; import { FeatureRegistry } from './feature_registry'; import { uiCapabilitiesForFeatures } from './ui_capabilities_for_features'; import { buildOSSFeatures } from './oss_features'; @@ -127,6 +128,12 @@ export class FeaturesPlugin public start(core: CoreStart): RecursiveReadonly { this.registerOssFeatures(core.savedObjects); + + const { overrides } = this.initializerContext.config.get(); + if (overrides) { + this.featureRegistry.applyOverrides(overrides); + } + this.featureRegistry.lockRegistration(); this.capabilities = uiCapabilitiesForFeatures( diff --git a/x-pack/plugins/reporting/server/core.ts b/x-pack/plugins/reporting/server/core.ts index 5a2b8c1533396..112b08e70df2a 100644 --- a/x-pack/plugins/reporting/server/core.ts +++ b/x-pack/plugins/reporting/server/core.ts @@ -8,7 +8,7 @@ import * as Rx from 'rxjs'; import { map, take } from 'rxjs'; -import type { +import { AnalyticsServiceStart, CoreSetup, DocLinksServiceSetup, @@ -237,41 +237,6 @@ export class ReportingCore { return exportTypes; } - /** - * If xpack.reporting.roles.enabled === true, register Reporting as a feature - * that is controlled by user role names - */ - public registerFeature() { - const { features } = this.getPluginSetupDeps(); - const deprecatedRoles = this.getDeprecatedAllowedRoles(); - - if (deprecatedRoles !== false) { - // refer to roles.allow configuration (deprecated path) - const allowedRoles = ['superuser', ...(deprecatedRoles ?? [])]; - const privileges = allowedRoles.map((role) => ({ - requiredClusterPrivileges: [], - requiredRoles: [role], - ui: [], - })); - - // self-register as an elasticsearch feature (deprecated) - features.registerElasticsearchFeature({ - id: 'reporting', - catalogue: ['reporting'], - management: { - insightsAndAlerting: ['reporting'], - }, - privileges, - }); - } else { - this.logger.debug( - `Reporting roles configuration is disabled. Please assign access to Reporting use Kibana feature controls for applications.` - ); - // trigger application to register Reporting as a subfeature - features.enableReportingUiCapabilities(); - } - } - /* * Returns configurable server info */ diff --git a/x-pack/plugins/reporting/server/features.ts b/x-pack/plugins/reporting/server/features.ts new file mode 100644 index 0000000000000..45666e2b2460d --- /dev/null +++ b/x-pack/plugins/reporting/server/features.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DEFAULT_APP_CATEGORIES, type Logger } from '@kbn/core/server'; +import { i18n } from '@kbn/i18n'; +import type { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; + +interface FeatureRegistrationOpts { + features: FeaturesPluginSetup; + deprecatedRoles: string[] | false; + isServerless: boolean; + logger: Logger; +} + +/** + * If xpack.reporting.roles.enabled === true, register Reporting as a feature + * that is controlled by user role names. Also, for Serverless register a + * 'shell' Reporting Kibana feature. + */ +export function registerFeatures({ + isServerless, + features, + deprecatedRoles, + logger, +}: FeatureRegistrationOpts) { + // Register a 'shell' feature specifically for Serverless. If granted, it will automatically provide access to + // reporting capabilities in other features, such as Discover, Dashboards, and Visualizations. On its own, this + // feature doesn't grant any additional privileges. + if (isServerless) { + features.registerKibanaFeature({ + id: 'reporting', + name: i18n.translate('xpack.reporting.features.reportingFeatureName', { + defaultMessage: 'Reporting', + }), + category: DEFAULT_APP_CATEGORIES.management, + app: [], + privileges: { + all: { savedObject: { all: [], read: [] }, ui: [] }, + // No read-only mode currently supported + read: { disabled: true, savedObject: { all: [], read: [] }, ui: [] }, + }, + }); + } + + if (deprecatedRoles !== false) { + // refer to roles.allow configuration (deprecated path) + const allowedRoles = ['superuser', ...(deprecatedRoles ?? [])]; + const privileges = allowedRoles.map((role) => ({ + requiredClusterPrivileges: [], + requiredRoles: [role], + ui: [], + })); + + // self-register as an elasticsearch feature (deprecated) + features.registerElasticsearchFeature({ + id: 'reporting', + catalogue: ['reporting'], + management: { + insightsAndAlerting: ['reporting'], + }, + privileges, + }); + } else { + logger.debug( + `Reporting roles configuration is disabled. Please assign access to Reporting use Kibana feature controls for applications.` + ); + // trigger application to register Reporting as a subfeature + features.enableReportingUiCapabilities(); + } +} diff --git a/x-pack/plugins/reporting/server/plugin.test.ts b/x-pack/plugins/reporting/server/plugin.test.ts index 8e1149b5d80f6..4abb64dc13e8b 100644 --- a/x-pack/plugins/reporting/server/plugin.test.ts +++ b/x-pack/plugins/reporting/server/plugin.test.ts @@ -5,8 +5,15 @@ * 2.0. */ -import type { CoreSetup, CoreStart, Logger } from '@kbn/core/server'; +import { + CoreSetup, + CoreStart, + DEFAULT_APP_CATEGORIES, + Logger, + type PackageInfo, +} from '@kbn/core/server'; import { coreMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { featuresPluginMock } from '@kbn/features-plugin/server/mocks'; import { createMockConfigSchema } from '@kbn/reporting-mocks-server'; import { CSV_REPORT_TYPE, CSV_REPORT_TYPE_V2 } from '@kbn/reporting-export-types-csv-common'; @@ -18,6 +25,7 @@ import { ReportingPlugin } from './plugin'; import { createMockPluginSetup, createMockPluginStart } from './test_helpers'; import type { ReportingSetupDeps } from './types'; import { ExportTypesRegistry } from '@kbn/reporting-server/export_types_registry'; +import { PluginSetupContract as FeaturesPluginSetupContract } from '@kbn/features-plugin/server'; const sleep = (time: number) => new Promise((r) => setTimeout(r, time)); @@ -30,6 +38,7 @@ describe('Reporting Plugin', () => { let pluginStart: ReportingInternalStart; let logger: jest.Mocked; let plugin: ReportingPlugin; + let featuresSetup: jest.Mocked; beforeEach(async () => { jest.clearAllMocks(); @@ -38,7 +47,10 @@ describe('Reporting Plugin', () => { initContext = coreMock.createPluginInitializerContext(configSchema); coreSetup = coreMock.createSetup(configSchema); coreStart = coreMock.createStart(); - pluginSetup = createMockPluginSetup({}) as unknown as ReportingSetupDeps; + featuresSetup = featuresPluginMock.createSetup(); + pluginSetup = createMockPluginSetup({ + features: featuresSetup, + }) as unknown as ReportingSetupDeps; pluginStart = await createMockPluginStart(coreStart, configSchema); logger = loggingSystemMock.createLogger(); @@ -143,4 +155,33 @@ describe('Reporting Plugin', () => { ); }); }); + + describe('features registration', () => { + it('does not register Kibana reporting feature in traditional build flavour', async () => { + plugin.setup(coreSetup, pluginSetup); + expect(featuresSetup.registerKibanaFeature).not.toHaveBeenCalled(); + expect(featuresSetup.enableReportingUiCapabilities).toHaveBeenCalledTimes(1); + }); + + it('registers Kibana reporting feature in serverless build flavour', async () => { + const serverlessInitContext = coreMock.createPluginInitializerContext(configSchema); + // Force type-cast to convert `ReadOnly` to mutable `PackageInfo`. + (serverlessInitContext.env.packageInfo as PackageInfo).buildFlavor = 'serverless'; + plugin = new ReportingPlugin(serverlessInitContext); + + plugin.setup(coreSetup, pluginSetup); + expect(featuresSetup.registerKibanaFeature).toHaveBeenCalledTimes(1); + expect(featuresSetup.registerKibanaFeature).toHaveBeenCalledWith({ + id: 'reporting', + name: 'Reporting', + category: DEFAULT_APP_CATEGORIES.management, + app: [], + privileges: { + all: { savedObject: { all: [], read: [] }, ui: [] }, + read: { disabled: true, savedObject: { all: [], read: [] }, ui: [] }, + }, + }); + expect(featuresSetup.enableReportingUiCapabilities).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/x-pack/plugins/reporting/server/plugin.ts b/x-pack/plugins/reporting/server/plugin.ts index ea4722ef5c30e..3e68310f76cf4 100644 --- a/x-pack/plugins/reporting/server/plugin.ts +++ b/x-pack/plugins/reporting/server/plugin.ts @@ -26,6 +26,7 @@ import type { } from './types'; import { ReportingRequestHandlerContext } from './types'; import { registerReportingEventTypes, registerReportingUsageCollector } from './usage'; +import { registerFeatures } from './features'; /* * @internal @@ -79,8 +80,13 @@ export class ReportingPlugin // async background setup (async () => { - // Feature registration relies on config, so it cannot be setup before here. - reportingCore.registerFeature(); + // Feature registration relies on config, depending on whether deprecated roles are enabled, so it cannot be setup before here. + registerFeatures({ + features: plugins.features, + deprecatedRoles: reportingCore.getDeprecatedAllowedRoles(), + isServerless: this.initContext.env.packageInfo.buildFlavor === 'serverless', + logger: this.logger, + }); this.logger.debug('Setup complete'); })().catch((e) => { this.logger.error(`Error in Reporting setup, reporting may not function properly`); diff --git a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx index 36e6a5782f784..ccdc71d119f08 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx @@ -308,7 +308,7 @@ function useFeatures( fatalErrors.add(err); }) .then((retrievedFeatures) => { - setFeatures(retrievedFeatures); + setFeatures(retrievedFeatures?.filter((feature) => !feature.hidden) ?? null); }); }, [fatalErrors, getFeatures]); diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/sub_feature_form.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/sub_feature_form.tsx index 90f26eee5a930..03ed9597fcb2d 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/sub_feature_form.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/sub_feature_form.tsx @@ -36,9 +36,7 @@ interface Props { } export const SubFeatureForm = (props: Props) => { - const groupsWithPrivileges = props.subFeature - .getPrivilegeGroups() - .filter((group) => group.privileges.length > 0); + const groupsWithPrivileges = props.subFeature.getPrivilegeGroups(); const getTooltip = () => { if (!props.subFeature.privilegesTooltip) { diff --git a/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts b/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts index 79e98625cb06f..11ac512cd5a18 100644 --- a/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts +++ b/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { SubFeatureConfig } from '@kbn/features-plugin/common'; +import type { SubFeatureConfig, SubFeaturePrivilegeGroupConfig } from '@kbn/features-plugin/common'; import { SubFeature } from '@kbn/features-plugin/common'; import { SubFeaturePrivilege } from './sub_feature_privilege'; @@ -14,6 +14,10 @@ import { SubFeaturePrivilegeGroup } from './sub_feature_privilege_group'; export class SecuredSubFeature extends SubFeature { public readonly privileges: SubFeaturePrivilege[]; public readonly privilegesTooltip: string; + /** + * A list of the privilege groups that have at least one enabled privilege. + */ + private readonly nonEmptyPrivilegeGroups: SubFeaturePrivilegeGroupConfig[]; constructor( config: SubFeatureConfig, @@ -23,14 +27,27 @@ export class SecuredSubFeature extends SubFeature { this.privilegesTooltip = config.privilegesTooltip || ''; - this.privileges = []; - for (const privilege of this.privilegeIterator()) { - this.privileges.push(privilege); - } + this.nonEmptyPrivilegeGroups = this.privilegeGroups.flatMap((group) => { + const filteredPrivileges = group.privileges.filter((privilege) => !privilege.disabled); + if (filteredPrivileges.length === 0) { + return []; + } + + // If some privileges are disabled, we need to update the group to reflect the change. + return [ + group.privileges.length === filteredPrivileges.length + ? group + : ({ ...group, privileges: filteredPrivileges } as SubFeaturePrivilegeGroupConfig), + ]; + }); + + this.privileges = Array.from(this.privilegeIterator()); } public getPrivilegeGroups() { - return this.privilegeGroups.map((pg) => new SubFeaturePrivilegeGroup(pg, this.actionMapping)); + return this.nonEmptyPrivilegeGroups.map( + (pg) => new SubFeaturePrivilegeGroup(pg, this.actionMapping) + ); } public *privilegeIterator({ @@ -38,10 +55,13 @@ export class SecuredSubFeature extends SubFeature { }: { predicate?: (privilege: SubFeaturePrivilege, feature: SecuredSubFeature) => boolean; } = {}): IterableIterator { - for (const group of this.privilegeGroups) { - yield* group.privileges - .map((gp) => new SubFeaturePrivilege(gp, this.actionMapping[gp.id])) - .filter((privilege) => predicate(privilege, this)); + for (const group of this.nonEmptyPrivilegeGroups) { + for (const gp of group.privileges) { + const privilege = new SubFeaturePrivilege(gp, this.actionMapping[gp.id]); + if (predicate(privilege, this)) { + yield privilege; + } + } } } diff --git a/x-pack/plugins/security/public/management/roles/model/sub_feature_privilege.ts b/x-pack/plugins/security/public/management/roles/model/sub_feature_privilege.ts index b5897654a6a38..e9b58ba8b2294 100644 --- a/x-pack/plugins/security/public/management/roles/model/sub_feature_privilege.ts +++ b/x-pack/plugins/security/public/management/roles/model/sub_feature_privilege.ts @@ -21,6 +21,10 @@ export class SubFeaturePrivilege extends KibanaPrivilege { return this.subPrivilegeConfig.name; } + public get disabled() { + return this.subPrivilegeConfig.disabled; + } + public get requireAllSpaces() { return this.subPrivilegeConfig.requireAllSpaces ?? false; } diff --git a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts index e27a30ae42445..93efd86f52f54 100644 --- a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts @@ -185,6 +185,293 @@ describe('features', () => { }); }); + test('actions should respect `composedOf` specified at the privilege', () => { + const features: KibanaFeature[] = [ + new KibanaFeature({ + id: 'foo', + name: 'Foo KibanaFeature', + app: [], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + savedObject: { + all: ['all-savedObject-all-1'], + read: ['all-savedObject-read-1'], + }, + ui: ['all-ui-1'], + }, + read: { + savedObject: { + all: ['read-savedObject-all-1'], + read: ['read-savedObject-read-1'], + }, + ui: ['read-ui-1'], + }, + }, + }), + new KibanaFeature({ + id: 'bar', + name: 'Bar KibanaFeature', + app: [], + category: { id: 'bar', label: 'bar' }, + privileges: { + all: { + savedObject: { + all: ['all-savedObject-all-2'], + read: ['all-savedObject-read-2'], + }, + ui: ['all-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['all'] }], + }, + read: { + savedObject: { + all: ['read-savedObject-all-2'], + read: ['read-savedObject-read-2'], + }, + ui: ['read-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['read'] }], + }, + }, + }), + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue(features); + const privileges = privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic); + + const expectedAllPrivileges = [ + actions.login, + actions.savedObject.get('all-savedObject-all-2', 'bulk_get'), + actions.savedObject.get('all-savedObject-all-2', 'get'), + actions.savedObject.get('all-savedObject-all-2', 'find'), + actions.savedObject.get('all-savedObject-all-2', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-all-2', 'close_point_in_time'), + actions.savedObject.get('all-savedObject-all-2', 'create'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_create'), + actions.savedObject.get('all-savedObject-all-2', 'update'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_update'), + actions.savedObject.get('all-savedObject-all-2', 'delete'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_delete'), + actions.savedObject.get('all-savedObject-all-2', 'share_to_space'), + actions.savedObject.get('all-savedObject-read-2', 'bulk_get'), + actions.savedObject.get('all-savedObject-read-2', 'get'), + actions.savedObject.get('all-savedObject-read-2', 'find'), + actions.savedObject.get('all-savedObject-read-2', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('bar', 'all-ui-2'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('all-savedObject-all-1', 'get'), + actions.savedObject.get('all-savedObject-all-1', 'find'), + actions.savedObject.get('all-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('all-savedObject-all-1', 'create'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('all-savedObject-all-1', 'update'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('all-savedObject-all-1', 'delete'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('all-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('all-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('all-savedObject-read-1', 'get'), + actions.savedObject.get('all-savedObject-read-1', 'find'), + actions.savedObject.get('all-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-read-1', 'close_point_in_time'), + actions.ui.get('foo', 'all-ui-1'), + ]; + + const expectedReadPrivileges = [ + actions.login, + actions.savedObject.get('read-savedObject-all-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-2', 'get'), + actions.savedObject.get('read-savedObject-all-2', 'find'), + actions.savedObject.get('read-savedObject-all-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'create'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-2', 'update'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-2', 'delete'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-2', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-2', 'get'), + actions.savedObject.get('read-savedObject-read-2', 'find'), + actions.savedObject.get('read-savedObject-read-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('bar', 'read-ui-2'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-1', 'get'), + actions.savedObject.get('read-savedObject-all-1', 'find'), + actions.savedObject.get('read-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'create'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-1', 'update'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-1', 'delete'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-1', 'get'), + actions.savedObject.get('read-savedObject-read-1', 'find'), + actions.savedObject.get('read-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-1', 'close_point_in_time'), + actions.ui.get('foo', 'read-ui-1'), + ]; + + const actual = privileges.get(); + expect(actual).toHaveProperty('features.bar', { + all: [...expectedAllPrivileges], + read: [...expectedReadPrivileges], + minimal_all: [...expectedAllPrivileges], + minimal_read: [...expectedReadPrivileges], + }); + }); + + test('actions should respect `composedOf` specified at the privilege even if the referenced feature is hidden', () => { + const features: KibanaFeature[] = [ + new KibanaFeature({ + hidden: true, + id: 'foo', + name: 'Foo KibanaFeature', + app: [], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + savedObject: { + all: ['all-savedObject-all-1'], + read: ['all-savedObject-read-1'], + }, + ui: ['all-ui-1'], + }, + read: { + savedObject: { + all: ['read-savedObject-all-1'], + read: ['read-savedObject-read-1'], + }, + ui: ['read-ui-1'], + }, + }, + }), + new KibanaFeature({ + id: 'bar', + name: 'Bar KibanaFeature', + app: [], + category: { id: 'bar', label: 'bar' }, + privileges: { + all: { + savedObject: { + all: ['all-savedObject-all-2'], + read: ['all-savedObject-read-2'], + }, + ui: ['all-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['all'] }], + }, + read: { + savedObject: { + all: ['read-savedObject-all-2'], + read: ['read-savedObject-read-2'], + }, + ui: ['read-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['read'] }], + }, + }, + }), + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue(features); + const privileges = privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic); + + const expectedAllPrivileges = [ + actions.login, + actions.savedObject.get('all-savedObject-all-2', 'bulk_get'), + actions.savedObject.get('all-savedObject-all-2', 'get'), + actions.savedObject.get('all-savedObject-all-2', 'find'), + actions.savedObject.get('all-savedObject-all-2', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-all-2', 'close_point_in_time'), + actions.savedObject.get('all-savedObject-all-2', 'create'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_create'), + actions.savedObject.get('all-savedObject-all-2', 'update'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_update'), + actions.savedObject.get('all-savedObject-all-2', 'delete'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_delete'), + actions.savedObject.get('all-savedObject-all-2', 'share_to_space'), + actions.savedObject.get('all-savedObject-read-2', 'bulk_get'), + actions.savedObject.get('all-savedObject-read-2', 'get'), + actions.savedObject.get('all-savedObject-read-2', 'find'), + actions.savedObject.get('all-savedObject-read-2', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('bar', 'all-ui-2'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('all-savedObject-all-1', 'get'), + actions.savedObject.get('all-savedObject-all-1', 'find'), + actions.savedObject.get('all-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('all-savedObject-all-1', 'create'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('all-savedObject-all-1', 'update'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('all-savedObject-all-1', 'delete'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('all-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('all-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('all-savedObject-read-1', 'get'), + actions.savedObject.get('all-savedObject-read-1', 'find'), + actions.savedObject.get('all-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-read-1', 'close_point_in_time'), + actions.ui.get('foo', 'all-ui-1'), + ]; + + const expectedReadPrivileges = [ + actions.login, + actions.savedObject.get('read-savedObject-all-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-2', 'get'), + actions.savedObject.get('read-savedObject-all-2', 'find'), + actions.savedObject.get('read-savedObject-all-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'create'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-2', 'update'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-2', 'delete'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-2', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-2', 'get'), + actions.savedObject.get('read-savedObject-read-2', 'find'), + actions.savedObject.get('read-savedObject-read-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('bar', 'read-ui-2'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-1', 'get'), + actions.savedObject.get('read-savedObject-all-1', 'find'), + actions.savedObject.get('read-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'create'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-1', 'update'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-1', 'delete'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-1', 'get'), + actions.savedObject.get('read-savedObject-read-1', 'find'), + actions.savedObject.get('read-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-1', 'close_point_in_time'), + actions.ui.get('foo', 'read-ui-1'), + ]; + + const actual = privileges.get(); + expect(actual).toHaveProperty('features.bar', { + all: [...expectedAllPrivileges], + read: [...expectedReadPrivileges], + minimal_all: [...expectedAllPrivileges], + minimal_read: [...expectedReadPrivileges], + }); + }); + test(`features with no privileges aren't listed`, () => { const features: KibanaFeature[] = [ new KibanaFeature({ @@ -192,7 +479,50 @@ describe('features', () => { name: 'Foo KibanaFeature', app: [], category: { id: 'foo', label: 'foo' }, - privileges: null, + privileges: null, + }), + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue(features); + const privileges = privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic); + + const actual = privileges.get(); + expect(actual).not.toHaveProperty('features.foo'); + }); + + test(`hidden features aren't listed`, () => { + const features: KibanaFeature[] = [ + new KibanaFeature({ + hidden: true, + id: 'foo', + name: 'Foo KibanaFeature', + app: [], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + management: { + 'all-management': ['all-management-1'], + }, + catalogue: ['all-catalogue-1'], + savedObject: { + all: ['all-savedObject-all-1'], + read: ['all-savedObject-read-1'], + }, + ui: ['all-ui-1'], + }, + read: { + management: { + 'read-management': ['read-management-1'], + }, + catalogue: ['read-catalogue-1'], + savedObject: { + all: ['read-savedObject-all-1'], + read: ['read-savedObject-read-1'], + }, + ui: ['read-ui-1'], + }, + }, }), ]; @@ -202,6 +532,12 @@ describe('features', () => { const actual = privileges.get(); expect(actual).not.toHaveProperty('features.foo'); + + const checkPredicate = (action: string) => action.includes('all-') || action.includes('read-'); + expect(actual.global.all.some(checkPredicate)).toBe(false); + expect(actual.global.read.some(checkPredicate)).toBe(false); + expect(actual.space.all.some(checkPredicate)).toBe(false); + expect(actual.space.read.some(checkPredicate)).toBe(false); }); }); @@ -377,69 +713,362 @@ describe('features', () => { ]); }); - test('actions defined in a feature privilege with name `read` are included in `read`', () => { - const features: KibanaFeature[] = [ + test('actions defined in any feature privilege of a hidden but referenced feature are included in `all`, ignoring the excludeFromBasePrivileges property', () => { + const getFeatures = ({ + excludeFromBasePrivileges, + }: { + excludeFromBasePrivileges: boolean; + }) => [ + new KibanaFeature({ + hidden: true, + excludeFromBasePrivileges, + id: 'foo', + name: 'Foo KibanaFeature', + app: [], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + management: { + 'all-management': ['all-management-1'], + }, + catalogue: ['all-catalogue-1'], + savedObject: { + all: ['all-savedObject-all-1'], + read: ['all-savedObject-read-1'], + }, + ui: ['all-ui-1'], + }, + read: { + management: { + 'read-management': ['read-management-1'], + }, + catalogue: ['read-catalogue-1'], + savedObject: { + all: ['read-savedObject-all-1'], + read: ['read-savedObject-read-1'], + }, + ui: ['read-ui-1'], + }, + }, + }), + new KibanaFeature({ + id: 'bar', + name: 'Bar KibanaFeature', + app: [], + category: { id: 'bar', label: 'bar' }, + privileges: { + all: { + management: { + 'all-management': ['all-management-2'], + }, + catalogue: ['all-catalogue-2'], + savedObject: { + all: ['all-savedObject-all-2'], + read: ['all-savedObject-read-2'], + }, + ui: ['all-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['all'] }], + }, + read: { + management: { + 'read-management': ['read-management-2'], + }, + catalogue: ['read-catalogue-2'], + savedObject: { + all: ['read-savedObject-all-2'], + read: ['read-savedObject-read-2'], + }, + ui: ['read-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['read'] }], + }, + }, + }), + ]; + + const expectedActions = [ + actions.login, + ...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []), + ...(expectGetFeatures ? [actions.api.get('features')] : []), + ...(expectGetFeatures ? [actions.api.get('taskManager')] : []), + ...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []), + ...(expectManageSpaces + ? [ + actions.space.manage, + actions.ui.get('spaces', 'manage'), + actions.ui.get('management', 'kibana', 'spaces'), + actions.ui.get('catalogue', 'spaces'), + ] + : []), + ...(expectEnterpriseSearch ? [actions.ui.get('enterpriseSearch', 'all')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'save')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), + actions.ui.get('catalogue', 'all-catalogue-2'), + actions.ui.get('management', 'all-management', 'all-management-2'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_get'), + actions.savedObject.get('all-savedObject-all-2', 'get'), + actions.savedObject.get('all-savedObject-all-2', 'find'), + actions.savedObject.get('all-savedObject-all-2', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-all-2', 'close_point_in_time'), + actions.savedObject.get('all-savedObject-all-2', 'create'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_create'), + actions.savedObject.get('all-savedObject-all-2', 'update'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_update'), + actions.savedObject.get('all-savedObject-all-2', 'delete'), + actions.savedObject.get('all-savedObject-all-2', 'bulk_delete'), + actions.savedObject.get('all-savedObject-all-2', 'share_to_space'), + actions.savedObject.get('all-savedObject-read-2', 'bulk_get'), + actions.savedObject.get('all-savedObject-read-2', 'get'), + actions.savedObject.get('all-savedObject-read-2', 'find'), + actions.savedObject.get('all-savedObject-read-2', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('bar', 'all-ui-2'), + actions.ui.get('catalogue', 'read-catalogue-2'), + actions.ui.get('management', 'read-management', 'read-management-2'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-2', 'get'), + actions.savedObject.get('read-savedObject-all-2', 'find'), + actions.savedObject.get('read-savedObject-all-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'create'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-2', 'update'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-2', 'delete'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-2', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-2', 'get'), + actions.savedObject.get('read-savedObject-read-2', 'find'), + actions.savedObject.get('read-savedObject-read-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('bar', 'read-ui-2'), + actions.ui.get('catalogue', 'all-catalogue-1'), + actions.ui.get('management', 'all-management', 'all-management-1'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('all-savedObject-all-1', 'get'), + actions.savedObject.get('all-savedObject-all-1', 'find'), + actions.savedObject.get('all-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('all-savedObject-all-1', 'create'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('all-savedObject-all-1', 'update'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('all-savedObject-all-1', 'delete'), + actions.savedObject.get('all-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('all-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('all-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('all-savedObject-read-1', 'get'), + actions.savedObject.get('all-savedObject-read-1', 'find'), + actions.savedObject.get('all-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('all-savedObject-read-1', 'close_point_in_time'), + actions.ui.get('foo', 'all-ui-1'), + actions.ui.get('catalogue', 'read-catalogue-1'), + actions.ui.get('management', 'read-management', 'read-management-1'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-1', 'get'), + actions.savedObject.get('read-savedObject-all-1', 'find'), + actions.savedObject.get('read-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'create'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-1', 'update'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-1', 'delete'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-1', 'get'), + actions.savedObject.get('read-savedObject-read-1', 'find'), + actions.savedObject.get('read-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-1', 'close_point_in_time'), + actions.ui.get('foo', 'read-ui-1'), + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue( + getFeatures({ excludeFromBasePrivileges: false }) + ); + expect( + privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic).get() + ).toHaveProperty(`${group}.all`, expectedActions); + + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue( + getFeatures({ excludeFromBasePrivileges: true }) + ); + expect( + privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic).get() + ).toHaveProperty(`${group}.all`, expectedActions); + }); + + test('actions defined in a feature privilege with name `read` are included in `read`', () => { + const features: KibanaFeature[] = [ + new KibanaFeature({ + id: 'foo', + name: 'Foo KibanaFeature', + app: [], + category: { id: 'foo', label: 'foo' }, + catalogue: ['ignore-me-1', 'ignore-me-2'], + management: { + foo: ['ignore-me-1', 'ignore-me-2'], + }, + privileges: { + all: { + management: { + 'ignore-me': ['ignore-me-1', 'ignore-me-2'], + }, + catalogue: ['ignore-me-1', 'ignore-me-2'], + savedObject: { + all: ['ignore-me-1', 'ignore-me-2'], + read: ['ignore-me-1', 'ignore-me-2'], + }, + ui: ['ignore-me-1', 'ignore-me-2'], + }, + read: { + management: { + 'read-management': ['read-management-1', 'read-management-2'], + }, + catalogue: ['read-catalogue-1', 'read-catalogue-2'], + savedObject: { + all: ['read-savedObject-all-1', 'read-savedObject-all-2'], + read: ['read-savedObject-read-1', 'read-savedObject-read-2'], + }, + ui: ['read-ui-1', 'read-ui-2'], + }, + }, + }), + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue(features); + const privileges = privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic); + + const actual = privileges.get(); + expect(actual).toHaveProperty(`${group}.read`, [ + actions.login, + ...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), + actions.ui.get('catalogue', 'read-catalogue-1'), + actions.ui.get('catalogue', 'read-catalogue-2'), + actions.ui.get('management', 'read-management', 'read-management-1'), + actions.ui.get('management', 'read-management', 'read-management-2'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-1', 'get'), + actions.savedObject.get('read-savedObject-all-1', 'find'), + actions.savedObject.get('read-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'create'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-1', 'update'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-1', 'delete'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-2', 'get'), + actions.savedObject.get('read-savedObject-all-2', 'find'), + actions.savedObject.get('read-savedObject-all-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-2', 'create'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-2', 'update'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-2', 'delete'), + actions.savedObject.get('read-savedObject-all-2', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-2', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-1', 'get'), + actions.savedObject.get('read-savedObject-read-1', 'find'), + actions.savedObject.get('read-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-1', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-read-2', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-2', 'get'), + actions.savedObject.get('read-savedObject-read-2', 'find'), + actions.savedObject.get('read-savedObject-read-2', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('foo', 'read-ui-1'), + actions.ui.get('foo', 'read-ui-2'), + ]); + }); + + test('actions defined in a feature privilege with name `read` of a hidden but referenced feature are included in `read`, ignoring the excludeFromBasePrivileges property', () => { + const getFeatures = ({ + excludeFromBasePrivileges, + }: { + excludeFromBasePrivileges: boolean; + }) => [ new KibanaFeature({ + hidden: true, + excludeFromBasePrivileges, id: 'foo', name: 'Foo KibanaFeature', app: [], category: { id: 'foo', label: 'foo' }, - catalogue: ['ignore-me-1', 'ignore-me-2'], - management: { - foo: ['ignore-me-1', 'ignore-me-2'], + privileges: { + all: { + management: { + 'all-management': ['all-management-1'], + }, + catalogue: ['all-catalogue-1'], + savedObject: { + all: ['all-savedObject-all-1'], + read: ['all-savedObject-read-1'], + }, + ui: ['all-ui-1'], + }, + read: { + management: { + 'read-management': ['read-management-1'], + }, + catalogue: ['read-catalogue-1'], + savedObject: { + all: ['read-savedObject-all-1'], + read: ['read-savedObject-read-1'], + }, + ui: ['read-ui-1'], + }, }, + }), + new KibanaFeature({ + id: 'bar', + name: 'Bar KibanaFeature', + app: [], + category: { id: 'bar', label: 'bar' }, privileges: { all: { management: { - 'ignore-me': ['ignore-me-1', 'ignore-me-2'], + 'all-management': ['all-management-2'], }, - catalogue: ['ignore-me-1', 'ignore-me-2'], + catalogue: ['all-catalogue-2'], savedObject: { - all: ['ignore-me-1', 'ignore-me-2'], - read: ['ignore-me-1', 'ignore-me-2'], + all: ['all-savedObject-all-2'], + read: ['all-savedObject-read-2'], }, - ui: ['ignore-me-1', 'ignore-me-2'], + ui: ['all-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['all'] }], }, read: { management: { - 'read-management': ['read-management-1', 'read-management-2'], + 'read-management': ['read-management-2'], }, - catalogue: ['read-catalogue-1', 'read-catalogue-2'], + catalogue: ['read-catalogue-2'], savedObject: { - all: ['read-savedObject-all-1', 'read-savedObject-all-2'], - read: ['read-savedObject-read-1', 'read-savedObject-read-2'], + all: ['read-savedObject-all-2'], + read: ['read-savedObject-read-2'], }, - ui: ['read-ui-1', 'read-ui-2'], + ui: ['read-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['read'] }], }, }, }), ]; - const mockFeaturesPlugin = featuresPluginMock.createSetup(); - mockFeaturesPlugin.getKibanaFeatures.mockReturnValue(features); - const privileges = privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic); - - const actual = privileges.get(); - expect(actual).toHaveProperty(`${group}.read`, [ + const expectedActions = [ actions.login, ...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []), ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), - actions.ui.get('catalogue', 'read-catalogue-1'), actions.ui.get('catalogue', 'read-catalogue-2'), - actions.ui.get('management', 'read-management', 'read-management-1'), actions.ui.get('management', 'read-management', 'read-management-2'), - actions.savedObject.get('read-savedObject-all-1', 'bulk_get'), - actions.savedObject.get('read-savedObject-all-1', 'get'), - actions.savedObject.get('read-savedObject-all-1', 'find'), - actions.savedObject.get('read-savedObject-all-1', 'open_point_in_time'), - actions.savedObject.get('read-savedObject-all-1', 'close_point_in_time'), - actions.savedObject.get('read-savedObject-all-1', 'create'), - actions.savedObject.get('read-savedObject-all-1', 'bulk_create'), - actions.savedObject.get('read-savedObject-all-1', 'update'), - actions.savedObject.get('read-savedObject-all-1', 'bulk_update'), - actions.savedObject.get('read-savedObject-all-1', 'delete'), - actions.savedObject.get('read-savedObject-all-1', 'bulk_delete'), - actions.savedObject.get('read-savedObject-all-1', 'share_to_space'), actions.savedObject.get('read-savedObject-all-2', 'bulk_get'), actions.savedObject.get('read-savedObject-all-2', 'get'), actions.savedObject.get('read-savedObject-all-2', 'find'), @@ -452,19 +1081,49 @@ describe('features', () => { actions.savedObject.get('read-savedObject-all-2', 'delete'), actions.savedObject.get('read-savedObject-all-2', 'bulk_delete'), actions.savedObject.get('read-savedObject-all-2', 'share_to_space'), - actions.savedObject.get('read-savedObject-read-1', 'bulk_get'), - actions.savedObject.get('read-savedObject-read-1', 'get'), - actions.savedObject.get('read-savedObject-read-1', 'find'), - actions.savedObject.get('read-savedObject-read-1', 'open_point_in_time'), - actions.savedObject.get('read-savedObject-read-1', 'close_point_in_time'), actions.savedObject.get('read-savedObject-read-2', 'bulk_get'), actions.savedObject.get('read-savedObject-read-2', 'get'), actions.savedObject.get('read-savedObject-read-2', 'find'), actions.savedObject.get('read-savedObject-read-2', 'open_point_in_time'), actions.savedObject.get('read-savedObject-read-2', 'close_point_in_time'), + actions.ui.get('bar', 'read-ui-2'), + actions.ui.get('catalogue', 'read-catalogue-1'), + actions.ui.get('management', 'read-management', 'read-management-1'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-all-1', 'get'), + actions.savedObject.get('read-savedObject-all-1', 'find'), + actions.savedObject.get('read-savedObject-all-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'close_point_in_time'), + actions.savedObject.get('read-savedObject-all-1', 'create'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_create'), + actions.savedObject.get('read-savedObject-all-1', 'update'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_update'), + actions.savedObject.get('read-savedObject-all-1', 'delete'), + actions.savedObject.get('read-savedObject-all-1', 'bulk_delete'), + actions.savedObject.get('read-savedObject-all-1', 'share_to_space'), + actions.savedObject.get('read-savedObject-read-1', 'bulk_get'), + actions.savedObject.get('read-savedObject-read-1', 'get'), + actions.savedObject.get('read-savedObject-read-1', 'find'), + actions.savedObject.get('read-savedObject-read-1', 'open_point_in_time'), + actions.savedObject.get('read-savedObject-read-1', 'close_point_in_time'), actions.ui.get('foo', 'read-ui-1'), - actions.ui.get('foo', 'read-ui-2'), - ]); + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue( + getFeatures({ excludeFromBasePrivileges: false }) + ); + expect( + privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic).get() + ).toHaveProperty(`${group}.read`, expectedActions); + + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue( + getFeatures({ excludeFromBasePrivileges: true }) + ); + expect( + privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic).get() + ).toHaveProperty(`${group}.read`, expectedActions); }); test('actions defined in a reserved privilege are not included in `all` or `read`', () => { @@ -596,6 +1255,104 @@ describe('features', () => { ]); }); + test('actions defined via `composedOf` in a feature with excludeFromBasePrivileges are not included in `all` or `read', () => { + const features: KibanaFeature[] = [ + new KibanaFeature({ + hidden: true, + id: 'foo', + name: 'Foo KibanaFeature', + app: [], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + management: { + 'all-management': ['all-management-1'], + }, + catalogue: ['all-catalogue-1'], + savedObject: { + all: ['all-savedObject-all-1'], + read: ['all-savedObject-read-1'], + }, + ui: ['all-ui-1'], + }, + read: { + management: { + 'read-management': ['read-management-1'], + }, + catalogue: ['read-catalogue-1'], + savedObject: { + all: ['read-savedObject-all-1'], + read: ['read-savedObject-read-1'], + }, + ui: ['read-ui-1'], + }, + }, + }), + new KibanaFeature({ + excludeFromBasePrivileges: true, + id: 'bar', + name: 'Bar KibanaFeature', + app: [], + category: { id: 'bar', label: 'bar' }, + privileges: { + all: { + management: { + 'all-management': ['all-management-2'], + }, + catalogue: ['all-catalogue-2'], + savedObject: { + all: ['all-savedObject-all-2'], + read: ['all-savedObject-read-2'], + }, + ui: ['all-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['all'] }], + }, + read: { + management: { + 'read-management': ['read-management-2'], + }, + catalogue: ['read-catalogue-2'], + savedObject: { + all: ['read-savedObject-all-2'], + read: ['read-savedObject-read-2'], + }, + ui: ['read-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['read'] }], + }, + }, + }), + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue(features); + const privileges = privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic); + + const actual = privileges.get(); + expect(actual).toHaveProperty(`${group}.all`, [ + actions.login, + ...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []), + ...(expectGetFeatures ? [actions.api.get('features')] : []), + ...(expectGetFeatures ? [actions.api.get('taskManager')] : []), + ...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []), + ...(expectManageSpaces + ? [ + actions.space.manage, + actions.ui.get('spaces', 'manage'), + actions.ui.get('management', 'kibana', 'spaces'), + actions.ui.get('catalogue', 'spaces'), + ] + : []), + ...(expectEnterpriseSearch ? [actions.ui.get('enterpriseSearch', 'all')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'save')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), + ]); + expect(actual).toHaveProperty(`${group}.read`, [ + actions.login, + ...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), + ]); + }); + test('actions defined in an individual feature privilege with excludeFromBasePrivileges are not included in `all` or `read`', () => { const features: KibanaFeature[] = [ new KibanaFeature({ @@ -665,6 +1422,105 @@ describe('features', () => { ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), ]); }); + + test('actions defined via `composedOf` in an individual feature privilege with excludeFromBasePrivileges are not included in `all` or `read`', () => { + const features: KibanaFeature[] = [ + new KibanaFeature({ + hidden: true, + id: 'foo', + name: 'Foo KibanaFeature', + app: [], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + management: { + 'all-management': ['all-management-1'], + }, + catalogue: ['all-catalogue-1'], + savedObject: { + all: ['all-savedObject-all-1'], + read: ['all-savedObject-read-1'], + }, + ui: ['all-ui-1'], + }, + read: { + management: { + 'read-management': ['read-management-1'], + }, + catalogue: ['read-catalogue-1'], + savedObject: { + all: ['read-savedObject-all-1'], + read: ['read-savedObject-read-1'], + }, + ui: ['read-ui-1'], + }, + }, + }), + new KibanaFeature({ + id: 'bar', + name: 'Bar KibanaFeature', + app: [], + category: { id: 'bar', label: 'bar' }, + privileges: { + all: { + excludeFromBasePrivileges: true, + management: { + 'all-management': ['all-management-2'], + }, + catalogue: ['all-catalogue-2'], + savedObject: { + all: ['all-savedObject-all-2'], + read: ['all-savedObject-read-2'], + }, + ui: ['all-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['all'] }], + }, + read: { + excludeFromBasePrivileges: true, + management: { + 'read-management': ['read-management-2'], + }, + catalogue: ['read-catalogue-2'], + savedObject: { + all: ['read-savedObject-all-2'], + read: ['read-savedObject-read-2'], + }, + ui: ['read-ui-2'], + composedOf: [{ feature: 'foo', privileges: ['read'] }], + }, + }, + }), + ]; + + const mockFeaturesPlugin = featuresPluginMock.createSetup(); + mockFeaturesPlugin.getKibanaFeatures.mockReturnValue(features); + const privileges = privilegesFactory(actions, mockFeaturesPlugin, mockLicenseServiceBasic); + + const actual = privileges.get(); + expect(actual).toHaveProperty(`${group}.all`, [ + actions.login, + ...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []), + ...(expectGetFeatures ? [actions.api.get('features')] : []), + ...(expectGetFeatures ? [actions.api.get('taskManager')] : []), + ...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []), + ...(expectManageSpaces + ? [ + actions.space.manage, + actions.ui.get('spaces', 'manage'), + actions.ui.get('management', 'kibana', 'spaces'), + actions.ui.get('catalogue', 'spaces'), + ] + : []), + ...(expectEnterpriseSearch ? [actions.ui.get('enterpriseSearch', 'all')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'save')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), + ]); + expect(actual).toHaveProperty(`${group}.read`, [ + actions.login, + ...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []), + ...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []), + ]); + }); }); } ); diff --git a/x-pack/plugins/security/server/authorization/privileges/privileges.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.ts index e9e8ccbfe8d92..ee1901520df85 100644 --- a/x-pack/plugins/security/server/authorization/privileges/privileges.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.ts @@ -7,6 +7,10 @@ import { uniq } from 'lodash'; +import type { + FeatureKibanaPrivileges, + FeatureKibanaPrivilegesReference, +} from '@kbn/features-plugin/common'; import type { PluginSetupContract as FeaturesPluginSetup, KibanaFeature, @@ -41,6 +45,10 @@ export function privilegesFactory( const readActionsSet = new Set(); basePrivilegeFeatures.forEach((feature) => { + if (feature.hidden) { + return; + } + for (const { privilegeId, privilege } of featuresService.featurePrivilegeIterator(feature, { augmentWithSubFeaturePrivileges: true, licenseHasAtLeast, @@ -56,9 +64,31 @@ export function privilegesFactory( } }); - const allActions = [...allActionsSet]; - const readActions = [...readActionsSet]; + // Remember privilege as composable to update it later, once actions for all referenced privileges are also + // calculated and registered. + const composableFeaturePrivileges: Array<{ + featureId: string; + privilegeId: string; + excludeFromBasePrivileges?: boolean; + composedOf: readonly FeatureKibanaPrivilegesReference[]; + }> = []; + const tryStoreComposableFeature = ( + feature: KibanaFeature, + privilegeId: string, + privilege: FeatureKibanaPrivileges + ) => { + if (privilege.composedOf) { + composableFeaturePrivileges.push({ + featureId: feature.id, + privilegeId, + composedOf: privilege.composedOf, + excludeFromBasePrivileges: + feature.excludeFromBasePrivileges || privilege.excludeFromBasePrivileges, + }); + } + }; + const hiddenFeatures = new Set(); const featurePrivileges: Record> = {}; for (const feature of features) { featurePrivileges[feature.id] = {}; @@ -66,20 +96,26 @@ export function privilegesFactory( augmentWithSubFeaturePrivileges: true, licenseHasAtLeast, })) { - featurePrivileges[feature.id][featurePrivilege.privilegeId] = [ + const fullPrivilegeId = featurePrivilege.privilegeId; + featurePrivileges[feature.id][fullPrivilegeId] = [ actions.login, ...uniq(featurePrivilegeBuilder.getActions(featurePrivilege.privilege, feature)), ]; + + tryStoreComposableFeature(feature, fullPrivilegeId, featurePrivilege.privilege); } for (const featurePrivilege of featuresService.featurePrivilegeIterator(feature, { augmentWithSubFeaturePrivileges: false, licenseHasAtLeast, })) { - featurePrivileges[feature.id][`minimal_${featurePrivilege.privilegeId}`] = [ + const minimalPrivilegeId = `minimal_${featurePrivilege.privilegeId}`; + featurePrivileges[feature.id][minimalPrivilegeId] = [ actions.login, ...uniq(featurePrivilegeBuilder.getActions(featurePrivilege.privilege, feature)), ]; + + tryStoreComposableFeature(feature, minimalPrivilegeId, featurePrivilege.privilege); } if ( @@ -97,10 +133,53 @@ export function privilegesFactory( } } - if (Object.keys(featurePrivileges[feature.id]).length === 0) { - delete featurePrivileges[feature.id]; + if (feature.hidden || Object.keys(featurePrivileges[feature.id]).length === 0) { + hiddenFeatures.add(feature.id); } } + + // Update composable feature privileges to include and deduplicate actions from the referenced privileges. + // Note that we should do it _before_ removing hidden features. Also, currently, feature privilege composition + // doesn't respect the minimum license level required by the feature whose privileges are being included in + // another feature. This could potentially enable functionality in a license lower than originally intended. It + // might or might not be desired, but we're accepting this for now, as every attempt to compose a feature + // undergoes a stringent review process. + for (const composableFeature of composableFeaturePrivileges) { + const composedActions = composableFeature.composedOf.flatMap((privilegeReference) => + privilegeReference.privileges.flatMap( + (privilege) => featurePrivileges[privilegeReference.feature][privilege] + ) + ); + featurePrivileges[composableFeature.featureId][composableFeature.privilegeId] = [ + ...new Set( + featurePrivileges[composableFeature.featureId][composableFeature.privilegeId].concat( + composedActions + ) + ), + ]; + + if (!composableFeature.excludeFromBasePrivileges) { + for (const action of composedActions) { + // Login action is special since it's added explicitly for feature and base privileges. + if (action === actions.login) { + continue; + } + + allActionsSet.add(action); + if (composableFeature.privilegeId === 'read') { + readActionsSet.add(action); + } + } + } + } + + // Remove hidden features to avoid registering standalone privileges for them. + for (const hiddenFeatureId of hiddenFeatures) { + delete featurePrivileges[hiddenFeatureId]; + } + + const allActions = [...allActionsSet]; + const readActions = [...readActionsSet]; return { features: featurePrivileges, global: { diff --git a/x-pack/plugins/security/server/lib/role_utils.test.ts b/x-pack/plugins/security/server/lib/role_utils.test.ts index ec808f231808d..ebd083b8ff60e 100644 --- a/x-pack/plugins/security/server/lib/role_utils.test.ts +++ b/x-pack/plugins/security/server/lib/role_utils.test.ts @@ -5,7 +5,13 @@ * 2.0. */ -import { transformPrivilegesToElasticsearchPrivileges } from './role_utils'; +import { KibanaFeature } from '@kbn/features-plugin/common'; +import { getKibanaRoleSchema } from '@kbn/security-plugin-types-server'; + +import { + transformPrivilegesToElasticsearchPrivileges, + validateKibanaPrivileges, +} from './role_utils'; import { ALL_SPACES_ID } from '../../common/constants'; describe('transformPrivilegesToElasticsearchPrivileges', () => { @@ -24,3 +30,163 @@ describe('transformPrivilegesToElasticsearchPrivileges', () => { ]); }); }); + +describe('validateKibanaPrivileges', () => { + test('properly validates sub-feature privileges', () => { + const existingKibanaFeatures = [ + new KibanaFeature({ + id: 'feature1', + name: 'Feature1', + app: ['app1'], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + app: ['foo'], + catalogue: ['foo'], + savedObject: { all: ['foo'], read: [] }, + ui: ['save', 'show'], + }, + read: { + app: ['foo'], + catalogue: ['foo'], + savedObject: { all: [], read: ['foo'] }, + ui: ['show'], + }, + }, + }), + new KibanaFeature({ + id: 'feature2', + name: 'Feature2', + app: ['app2'], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: { + app: ['foo'], + catalogue: ['foo'], + savedObject: { all: ['foo'], read: [] }, + ui: ['save', 'show'], + }, + read: { + app: ['foo'], + catalogue: ['foo'], + savedObject: { all: [], read: ['foo'] }, + ui: ['show'], + }, + }, + subFeatures: [ + { + name: 'subFeature1', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'subFeaturePrivilege1', + name: 'SubFeaturePrivilege1', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: [], + }, + { + disabled: true, + id: 'subFeaturePrivilege2', + name: 'SubFeaturePrivilege2', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: [], + }, + { + disabled: true, + id: 'subFeaturePrivilege3', + name: 'SubFeaturePrivilege3', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: [], + }, + ], + }, + ], + }, + { + name: 'subFeature2', + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + disabled: true, + id: 'subFeaturePrivilege4', + name: 'SubFeaturePrivilege4', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: [], + }, + { + id: 'subFeaturePrivilege5', + name: 'SubFeaturePrivilege5', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: [], + }, + ], + }, + ], + }, + ], + }), + ]; + + const { validationErrors: emptyErrors } = validateKibanaPrivileges( + existingKibanaFeatures, + getKibanaRoleSchema(() => ({ global: [], space: [] })).validate([ + { + feature: { + feature2: ['all', 'subFeaturePrivilege1', 'subFeaturePrivilege5'], + }, + }, + ]) + ); + expect(emptyErrors).toHaveLength(0); + + const { validationErrors: nonEmptyErrors1 } = validateKibanaPrivileges( + existingKibanaFeatures, + getKibanaRoleSchema(() => ({ global: [], space: [] })).validate([ + { + feature: { + feature2: [ + 'all', + 'subFeaturePrivilege1', + 'subFeaturePrivilege2', + 'subFeaturePrivilege5', + ], + }, + }, + ]) + ); + expect(nonEmptyErrors1).toEqual([ + 'Feature [feature2] does not support specified sub-feature privileges [subFeaturePrivilege2].', + ]); + + const { validationErrors: nonEmptyErrors2 } = validateKibanaPrivileges( + existingKibanaFeatures, + getKibanaRoleSchema(() => ({ global: [], space: [] })).validate([ + { + feature: { + feature2: [ + 'all', + 'subFeaturePrivilege1', + 'subFeaturePrivilege2', + 'subFeaturePrivilege3', + 'subFeaturePrivilege4', + 'subFeaturePrivilege5', + ], + }, + }, + ]) + ); + expect(nonEmptyErrors2).toEqual([ + 'Feature [feature2] does not support specified sub-feature privileges [subFeaturePrivilege2, subFeaturePrivilege3].', + 'Feature [feature2] does not support specified sub-feature privileges [subFeaturePrivilege4].', + ]); + }); +}); diff --git a/x-pack/plugins/security/server/lib/role_utils.ts b/x-pack/plugins/security/server/lib/role_utils.ts index 1df5254a38df0..5e714cb1f7623 100644 --- a/x-pack/plugins/security/server/lib/role_utils.ts +++ b/x-pack/plugins/security/server/lib/role_utils.ts @@ -69,12 +69,12 @@ export const validateKibanaPrivileges = ( const validationErrors = kibanaPrivileges.flatMap((priv) => { const forAllSpaces = priv.spaces.includes(ALL_SPACES_ID); - return Object.entries(priv.feature ?? {}).flatMap(([featureId, feature]) => { + return Object.entries(priv.feature ?? {}).flatMap(([featureId, featurePrivileges]) => { const errors: string[] = []; - const kibanaFeature = kibanaFeatures.find((f) => f.id === featureId); + const kibanaFeature = kibanaFeatures.find((f) => f.id === featureId && !f.hidden); if (!kibanaFeature) return errors; - if (feature.includes('all')) { + if (featurePrivileges.includes('all')) { if (kibanaFeature.privileges?.all.disabled) { errors.push(`Feature [${featureId}] does not support privilege [all].`); } @@ -88,7 +88,7 @@ export const validateKibanaPrivileges = ( } } - if (feature.includes('read')) { + if (featurePrivileges.includes('read')) { if (kibanaFeature.privileges?.read.disabled) { errors.push(`Feature [${featureId}] does not support privilege [read].`); } @@ -103,12 +103,25 @@ export const validateKibanaPrivileges = ( } kibanaFeature.subFeatures.forEach((subFeature) => { - if ( + // Check if the definition includes any sub-feature privileges. + const subFeaturePrivileges = subFeature.privilegeGroups.flatMap((group) => + group.privileges.filter((privilege) => featurePrivileges.includes(privilege.id)) + ); + + // If the definition includes any disabled sub-feature privileges, return an error. + const disabledSubFeaturePrivileges = subFeaturePrivileges.filter( + (privilege) => privilege.disabled + ); + if (disabledSubFeaturePrivileges.length > 0) { + errors.push( + `Feature [${featureId}] does not support specified sub-feature privileges [${disabledSubFeaturePrivileges + .map((privilege) => privilege.id) + .join(', ')}].` + ); + } else if ( subFeature.requireAllSpaces && !forAllSpaces && - subFeature.privilegeGroups.some((group) => - group.privileges.some((privilege) => feature.includes(privilege.id)) - ) + subFeaturePrivileges.length > 0 ) { errors.push( `Sub-feature privilege [${kibanaFeature.name} - ${ diff --git a/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authorization.ts b/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authorization.ts index 76d6580e8bbb8..d6ec69803b8f5 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authorization.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/platform_security/authorization.ts @@ -6,11 +6,25 @@ */ import expect from 'expect'; +import { KibanaFeatureConfig, SubFeaturePrivilegeConfig } from '@kbn/features-plugin/common'; import { FtrProviderContext } from '../../../ftr_provider_context'; +function collectSubFeaturesPrivileges(feature: KibanaFeatureConfig) { + return new Map( + feature.subFeatures?.flatMap((subFeature) => + subFeature.privilegeGroups.flatMap(({ privileges }) => + privileges.map( + (privilege) => [privilege.id, privilege] as [string, SubFeaturePrivilegeConfig] + ) + ) + ) ?? [] + ); +} + export default function ({ getService }: FtrProviderContext) { const svlCommonApi = getService('svlCommonApi'); const supertest = getService('supertest'); + const log = getService('log'); describe('security/authorization', function () { describe('route access', () => { @@ -76,5 +90,39 @@ export default function ({ getService }: FtrProviderContext) { }); }); }); + + describe('available features', () => { + const svlUserManager = getService('svlUserManager'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + let adminCredentials: { Cookie: string }; + + before(async () => { + // get auth header for Viewer role + adminCredentials = await svlUserManager.getApiCredentialsForRole('admin'); + }); + + it('all Dashboard and Discover sub-feature privileges are disabled', async () => { + const { body } = await supertestWithoutAuth + .get('/api/features') + .set(svlCommonApi.getInternalRequestHeader()) + .set(adminCredentials) + .expect(200); + + // We should make sure that neither Discover nor Dashboard displays any sub-feature privileges in Serverless. + // If any of these features adds a new sub-feature privilege we should make an explicit decision whether it + // should be displayed in Serverless. + const features = body as KibanaFeatureConfig[]; + for (const featureId of ['discover', 'dashboard']) { + const feature = features.find((f) => f.id === featureId)!; + const subFeaturesPrivileges = collectSubFeaturesPrivileges(feature); + for (const privilege of subFeaturesPrivileges.values()) { + log.debug( + `Verifying that ${privilege.id} sub-feature privilege of ${featureId} feature is disabled.` + ); + expect(privilege.disabled).toBe(true); + } + } + }); + }); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts index c6257df072d85..dfd398fc360d0 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts @@ -11,6 +11,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('Serverless observability API - feature flags', function () { loadTestFile(require.resolve('./custom_threshold_rule')); loadTestFile(require.resolve('./infra')); + loadTestFile(require.resolve('./platform_security')); loadTestFile(require.resolve('../common/platform_security/roles_routes_feature_flag.ts')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts new file mode 100644 index 0000000000000..25bdff734e379 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts @@ -0,0 +1,9585 @@ +/* + * 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 ({ getService }: FtrProviderContext) { + const svlCommonApi = getService('svlCommonApi'); + + describe('security/authorization', function () { + describe('available features', () => { + const svlUserManager = getService('svlUserManager'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + let adminCredentials: { Cookie: string }; + + before(async () => { + // get auth header for Viewer role + adminCredentials = await svlUserManager.getApiCredentialsForRole('admin'); + }); + + it('composite features', async () => { + const { body } = await supertestWithoutAuth + .get('/api/security/privileges?includeActions=true') + .set(svlCommonApi.getInternalRequestHeader()) + .set(adminCredentials) + .expect(200); + + // The following features are composed of other features in a way that is + // specific to the observability solution. + const compositeFeatureIds = [ + 'apm', + 'dashboard', + 'discover', + 'fleetv2', + 'infrastructure', + 'reporting', + 'slo', + 'uptime', + ]; + + const features = Object.fromEntries( + Object.entries(body.features).filter(([key]) => compositeFeatureIds.includes(key)) + ); + expectSnapshot(features).toMatchInline(` + Object { + "apm": Object { + "all": Array [ + "login:", + "api:apm", + "api:apm_write", + "api:rac", + "app:apm", + "app:ux", + "app:kibana", + "ui:catalogue/apm", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/apm", + "ui:navLinks/ux", + "ui:navLinks/kibana", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:apm-indices/bulk_get", + "saved_object:apm-indices/get", + "saved_object:apm-indices/find", + "saved_object:apm-indices/open_point_in_time", + "saved_object:apm-indices/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:apm/show", + "ui:apm/save", + "ui:apm/alerting:show", + "ui:apm/alerting:save", + "alerting:apm.error_rate/apm/rule/get", + "alerting:apm.error_rate/apm/rule/getRuleState", + "alerting:apm.error_rate/apm/rule/getAlertSummary", + "alerting:apm.error_rate/apm/rule/getExecutionLog", + "alerting:apm.error_rate/apm/rule/getActionErrorLog", + "alerting:apm.error_rate/apm/rule/find", + "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/apm/rule/getBackfill", + "alerting:apm.error_rate/apm/rule/findBackfill", + "alerting:apm.error_rate/apm/rule/create", + "alerting:apm.error_rate/apm/rule/delete", + "alerting:apm.error_rate/apm/rule/update", + "alerting:apm.error_rate/apm/rule/updateApiKey", + "alerting:apm.error_rate/apm/rule/enable", + "alerting:apm.error_rate/apm/rule/disable", + "alerting:apm.error_rate/apm/rule/muteAll", + "alerting:apm.error_rate/apm/rule/unmuteAll", + "alerting:apm.error_rate/apm/rule/muteAlert", + "alerting:apm.error_rate/apm/rule/unmuteAlert", + "alerting:apm.error_rate/apm/rule/snooze", + "alerting:apm.error_rate/apm/rule/bulkEdit", + "alerting:apm.error_rate/apm/rule/bulkDelete", + "alerting:apm.error_rate/apm/rule/bulkEnable", + "alerting:apm.error_rate/apm/rule/bulkDisable", + "alerting:apm.error_rate/apm/rule/unsnooze", + "alerting:apm.error_rate/apm/rule/runSoon", + "alerting:apm.error_rate/apm/rule/scheduleBackfill", + "alerting:apm.error_rate/apm/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/apm/rule/get", + "alerting:apm.transaction_error_rate/apm/rule/getRuleState", + "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/apm/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/apm/rule/find", + "alerting:apm.transaction_error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/apm/rule/getBackfill", + "alerting:apm.transaction_error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_error_rate/apm/rule/create", + "alerting:apm.transaction_error_rate/apm/rule/delete", + "alerting:apm.transaction_error_rate/apm/rule/update", + "alerting:apm.transaction_error_rate/apm/rule/updateApiKey", + "alerting:apm.transaction_error_rate/apm/rule/enable", + "alerting:apm.transaction_error_rate/apm/rule/disable", + "alerting:apm.transaction_error_rate/apm/rule/muteAll", + "alerting:apm.transaction_error_rate/apm/rule/unmuteAll", + "alerting:apm.transaction_error_rate/apm/rule/muteAlert", + "alerting:apm.transaction_error_rate/apm/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/apm/rule/snooze", + "alerting:apm.transaction_error_rate/apm/rule/bulkEdit", + "alerting:apm.transaction_error_rate/apm/rule/bulkDelete", + "alerting:apm.transaction_error_rate/apm/rule/bulkEnable", + "alerting:apm.transaction_error_rate/apm/rule/bulkDisable", + "alerting:apm.transaction_error_rate/apm/rule/unsnooze", + "alerting:apm.transaction_error_rate/apm/rule/runSoon", + "alerting:apm.transaction_error_rate/apm/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/apm/rule/deleteBackfill", + "alerting:apm.transaction_duration/apm/rule/get", + "alerting:apm.transaction_duration/apm/rule/getRuleState", + "alerting:apm.transaction_duration/apm/rule/getAlertSummary", + "alerting:apm.transaction_duration/apm/rule/getExecutionLog", + "alerting:apm.transaction_duration/apm/rule/getActionErrorLog", + "alerting:apm.transaction_duration/apm/rule/find", + "alerting:apm.transaction_duration/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/apm/rule/getBackfill", + "alerting:apm.transaction_duration/apm/rule/findBackfill", + "alerting:apm.transaction_duration/apm/rule/create", + "alerting:apm.transaction_duration/apm/rule/delete", + "alerting:apm.transaction_duration/apm/rule/update", + "alerting:apm.transaction_duration/apm/rule/updateApiKey", + "alerting:apm.transaction_duration/apm/rule/enable", + "alerting:apm.transaction_duration/apm/rule/disable", + "alerting:apm.transaction_duration/apm/rule/muteAll", + "alerting:apm.transaction_duration/apm/rule/unmuteAll", + "alerting:apm.transaction_duration/apm/rule/muteAlert", + "alerting:apm.transaction_duration/apm/rule/unmuteAlert", + "alerting:apm.transaction_duration/apm/rule/snooze", + "alerting:apm.transaction_duration/apm/rule/bulkEdit", + "alerting:apm.transaction_duration/apm/rule/bulkDelete", + "alerting:apm.transaction_duration/apm/rule/bulkEnable", + "alerting:apm.transaction_duration/apm/rule/bulkDisable", + "alerting:apm.transaction_duration/apm/rule/unsnooze", + "alerting:apm.transaction_duration/apm/rule/runSoon", + "alerting:apm.transaction_duration/apm/rule/scheduleBackfill", + "alerting:apm.transaction_duration/apm/rule/deleteBackfill", + "alerting:apm.anomaly/apm/rule/get", + "alerting:apm.anomaly/apm/rule/getRuleState", + "alerting:apm.anomaly/apm/rule/getAlertSummary", + "alerting:apm.anomaly/apm/rule/getExecutionLog", + "alerting:apm.anomaly/apm/rule/getActionErrorLog", + "alerting:apm.anomaly/apm/rule/find", + "alerting:apm.anomaly/apm/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/apm/rule/getBackfill", + "alerting:apm.anomaly/apm/rule/findBackfill", + "alerting:apm.anomaly/apm/rule/create", + "alerting:apm.anomaly/apm/rule/delete", + "alerting:apm.anomaly/apm/rule/update", + "alerting:apm.anomaly/apm/rule/updateApiKey", + "alerting:apm.anomaly/apm/rule/enable", + "alerting:apm.anomaly/apm/rule/disable", + "alerting:apm.anomaly/apm/rule/muteAll", + "alerting:apm.anomaly/apm/rule/unmuteAll", + "alerting:apm.anomaly/apm/rule/muteAlert", + "alerting:apm.anomaly/apm/rule/unmuteAlert", + "alerting:apm.anomaly/apm/rule/snooze", + "alerting:apm.anomaly/apm/rule/bulkEdit", + "alerting:apm.anomaly/apm/rule/bulkDelete", + "alerting:apm.anomaly/apm/rule/bulkEnable", + "alerting:apm.anomaly/apm/rule/bulkDisable", + "alerting:apm.anomaly/apm/rule/unsnooze", + "alerting:apm.anomaly/apm/rule/runSoon", + "alerting:apm.anomaly/apm/rule/scheduleBackfill", + "alerting:apm.anomaly/apm/rule/deleteBackfill", + "alerting:apm.error_rate/apm/alert/get", + "alerting:apm.error_rate/apm/alert/find", + "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/apm/alert/getAlertSummary", + "alerting:apm.error_rate/apm/alert/update", + "alerting:apm.transaction_error_rate/apm/alert/get", + "alerting:apm.transaction_error_rate/apm/alert/find", + "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/alert/update", + "alerting:apm.transaction_duration/apm/alert/get", + "alerting:apm.transaction_duration/apm/alert/find", + "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/apm/alert/getAlertSummary", + "alerting:apm.transaction_duration/apm/alert/update", + "alerting:apm.anomaly/apm/alert/get", + "alerting:apm.anomaly/apm/alert/find", + "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/apm/alert/getAlertSummary", + "alerting:apm.anomaly/apm/alert/update", + "api:infra", + "app:infra", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/infra", + "ui:navLinks/logs", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-ui-source/create", + "saved_object:infrastructure-ui-source/bulk_create", + "saved_object:infrastructure-ui-source/update", + "saved_object:infrastructure-ui-source/bulk_update", + "saved_object:infrastructure-ui-source/delete", + "saved_object:infrastructure-ui-source/bulk_delete", + "saved_object:infrastructure-ui-source/share_to_space", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/create", + "saved_object:infrastructure-monitoring-log-view/bulk_create", + "saved_object:infrastructure-monitoring-log-view/update", + "saved_object:infrastructure-monitoring-log-view/bulk_update", + "saved_object:infrastructure-monitoring-log-view/delete", + "saved_object:infrastructure-monitoring-log-view/bulk_delete", + "saved_object:infrastructure-monitoring-log-view/share_to_space", + "ui:logs/show", + "ui:logs/configureSource", + "ui:logs/save", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/rule/create", + "alerting:logs.alert.document.count/logs/rule/delete", + "alerting:logs.alert.document.count/logs/rule/update", + "alerting:logs.alert.document.count/logs/rule/updateApiKey", + "alerting:logs.alert.document.count/logs/rule/enable", + "alerting:logs.alert.document.count/logs/rule/disable", + "alerting:logs.alert.document.count/logs/rule/muteAll", + "alerting:logs.alert.document.count/logs/rule/unmuteAll", + "alerting:logs.alert.document.count/logs/rule/muteAlert", + "alerting:logs.alert.document.count/logs/rule/unmuteAlert", + "alerting:logs.alert.document.count/logs/rule/snooze", + "alerting:logs.alert.document.count/logs/rule/bulkEdit", + "alerting:logs.alert.document.count/logs/rule/bulkDelete", + "alerting:logs.alert.document.count/logs/rule/bulkEnable", + "alerting:logs.alert.document.count/logs/rule/bulkDisable", + "alerting:logs.alert.document.count/logs/rule/unsnooze", + "alerting:logs.alert.document.count/logs/rule/runSoon", + "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", + "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/create", + "alerting:.es-query/logs/rule/delete", + "alerting:.es-query/logs/rule/update", + "alerting:.es-query/logs/rule/updateApiKey", + "alerting:.es-query/logs/rule/enable", + "alerting:.es-query/logs/rule/disable", + "alerting:.es-query/logs/rule/muteAll", + "alerting:.es-query/logs/rule/unmuteAll", + "alerting:.es-query/logs/rule/muteAlert", + "alerting:.es-query/logs/rule/unmuteAlert", + "alerting:.es-query/logs/rule/snooze", + "alerting:.es-query/logs/rule/bulkEdit", + "alerting:.es-query/logs/rule/bulkDelete", + "alerting:.es-query/logs/rule/bulkEnable", + "alerting:.es-query/logs/rule/bulkDisable", + "alerting:.es-query/logs/rule/unsnooze", + "alerting:.es-query/logs/rule/runSoon", + "alerting:.es-query/logs/rule/scheduleBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_all": Array [ + "login:", + "api:apm", + "api:apm_write", + "api:rac", + "app:apm", + "app:ux", + "app:kibana", + "ui:catalogue/apm", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/apm", + "ui:navLinks/ux", + "ui:navLinks/kibana", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:apm-indices/bulk_get", + "saved_object:apm-indices/get", + "saved_object:apm-indices/find", + "saved_object:apm-indices/open_point_in_time", + "saved_object:apm-indices/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:apm/show", + "ui:apm/save", + "ui:apm/alerting:show", + "ui:apm/alerting:save", + "alerting:apm.error_rate/apm/rule/get", + "alerting:apm.error_rate/apm/rule/getRuleState", + "alerting:apm.error_rate/apm/rule/getAlertSummary", + "alerting:apm.error_rate/apm/rule/getExecutionLog", + "alerting:apm.error_rate/apm/rule/getActionErrorLog", + "alerting:apm.error_rate/apm/rule/find", + "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/apm/rule/getBackfill", + "alerting:apm.error_rate/apm/rule/findBackfill", + "alerting:apm.error_rate/apm/rule/create", + "alerting:apm.error_rate/apm/rule/delete", + "alerting:apm.error_rate/apm/rule/update", + "alerting:apm.error_rate/apm/rule/updateApiKey", + "alerting:apm.error_rate/apm/rule/enable", + "alerting:apm.error_rate/apm/rule/disable", + "alerting:apm.error_rate/apm/rule/muteAll", + "alerting:apm.error_rate/apm/rule/unmuteAll", + "alerting:apm.error_rate/apm/rule/muteAlert", + "alerting:apm.error_rate/apm/rule/unmuteAlert", + "alerting:apm.error_rate/apm/rule/snooze", + "alerting:apm.error_rate/apm/rule/bulkEdit", + "alerting:apm.error_rate/apm/rule/bulkDelete", + "alerting:apm.error_rate/apm/rule/bulkEnable", + "alerting:apm.error_rate/apm/rule/bulkDisable", + "alerting:apm.error_rate/apm/rule/unsnooze", + "alerting:apm.error_rate/apm/rule/runSoon", + "alerting:apm.error_rate/apm/rule/scheduleBackfill", + "alerting:apm.error_rate/apm/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/apm/rule/get", + "alerting:apm.transaction_error_rate/apm/rule/getRuleState", + "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/apm/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/apm/rule/find", + "alerting:apm.transaction_error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/apm/rule/getBackfill", + "alerting:apm.transaction_error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_error_rate/apm/rule/create", + "alerting:apm.transaction_error_rate/apm/rule/delete", + "alerting:apm.transaction_error_rate/apm/rule/update", + "alerting:apm.transaction_error_rate/apm/rule/updateApiKey", + "alerting:apm.transaction_error_rate/apm/rule/enable", + "alerting:apm.transaction_error_rate/apm/rule/disable", + "alerting:apm.transaction_error_rate/apm/rule/muteAll", + "alerting:apm.transaction_error_rate/apm/rule/unmuteAll", + "alerting:apm.transaction_error_rate/apm/rule/muteAlert", + "alerting:apm.transaction_error_rate/apm/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/apm/rule/snooze", + "alerting:apm.transaction_error_rate/apm/rule/bulkEdit", + "alerting:apm.transaction_error_rate/apm/rule/bulkDelete", + "alerting:apm.transaction_error_rate/apm/rule/bulkEnable", + "alerting:apm.transaction_error_rate/apm/rule/bulkDisable", + "alerting:apm.transaction_error_rate/apm/rule/unsnooze", + "alerting:apm.transaction_error_rate/apm/rule/runSoon", + "alerting:apm.transaction_error_rate/apm/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/apm/rule/deleteBackfill", + "alerting:apm.transaction_duration/apm/rule/get", + "alerting:apm.transaction_duration/apm/rule/getRuleState", + "alerting:apm.transaction_duration/apm/rule/getAlertSummary", + "alerting:apm.transaction_duration/apm/rule/getExecutionLog", + "alerting:apm.transaction_duration/apm/rule/getActionErrorLog", + "alerting:apm.transaction_duration/apm/rule/find", + "alerting:apm.transaction_duration/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/apm/rule/getBackfill", + "alerting:apm.transaction_duration/apm/rule/findBackfill", + "alerting:apm.transaction_duration/apm/rule/create", + "alerting:apm.transaction_duration/apm/rule/delete", + "alerting:apm.transaction_duration/apm/rule/update", + "alerting:apm.transaction_duration/apm/rule/updateApiKey", + "alerting:apm.transaction_duration/apm/rule/enable", + "alerting:apm.transaction_duration/apm/rule/disable", + "alerting:apm.transaction_duration/apm/rule/muteAll", + "alerting:apm.transaction_duration/apm/rule/unmuteAll", + "alerting:apm.transaction_duration/apm/rule/muteAlert", + "alerting:apm.transaction_duration/apm/rule/unmuteAlert", + "alerting:apm.transaction_duration/apm/rule/snooze", + "alerting:apm.transaction_duration/apm/rule/bulkEdit", + "alerting:apm.transaction_duration/apm/rule/bulkDelete", + "alerting:apm.transaction_duration/apm/rule/bulkEnable", + "alerting:apm.transaction_duration/apm/rule/bulkDisable", + "alerting:apm.transaction_duration/apm/rule/unsnooze", + "alerting:apm.transaction_duration/apm/rule/runSoon", + "alerting:apm.transaction_duration/apm/rule/scheduleBackfill", + "alerting:apm.transaction_duration/apm/rule/deleteBackfill", + "alerting:apm.anomaly/apm/rule/get", + "alerting:apm.anomaly/apm/rule/getRuleState", + "alerting:apm.anomaly/apm/rule/getAlertSummary", + "alerting:apm.anomaly/apm/rule/getExecutionLog", + "alerting:apm.anomaly/apm/rule/getActionErrorLog", + "alerting:apm.anomaly/apm/rule/find", + "alerting:apm.anomaly/apm/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/apm/rule/getBackfill", + "alerting:apm.anomaly/apm/rule/findBackfill", + "alerting:apm.anomaly/apm/rule/create", + "alerting:apm.anomaly/apm/rule/delete", + "alerting:apm.anomaly/apm/rule/update", + "alerting:apm.anomaly/apm/rule/updateApiKey", + "alerting:apm.anomaly/apm/rule/enable", + "alerting:apm.anomaly/apm/rule/disable", + "alerting:apm.anomaly/apm/rule/muteAll", + "alerting:apm.anomaly/apm/rule/unmuteAll", + "alerting:apm.anomaly/apm/rule/muteAlert", + "alerting:apm.anomaly/apm/rule/unmuteAlert", + "alerting:apm.anomaly/apm/rule/snooze", + "alerting:apm.anomaly/apm/rule/bulkEdit", + "alerting:apm.anomaly/apm/rule/bulkDelete", + "alerting:apm.anomaly/apm/rule/bulkEnable", + "alerting:apm.anomaly/apm/rule/bulkDisable", + "alerting:apm.anomaly/apm/rule/unsnooze", + "alerting:apm.anomaly/apm/rule/runSoon", + "alerting:apm.anomaly/apm/rule/scheduleBackfill", + "alerting:apm.anomaly/apm/rule/deleteBackfill", + "alerting:apm.error_rate/apm/alert/get", + "alerting:apm.error_rate/apm/alert/find", + "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/apm/alert/getAlertSummary", + "alerting:apm.error_rate/apm/alert/update", + "alerting:apm.transaction_error_rate/apm/alert/get", + "alerting:apm.transaction_error_rate/apm/alert/find", + "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/alert/update", + "alerting:apm.transaction_duration/apm/alert/get", + "alerting:apm.transaction_duration/apm/alert/find", + "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/apm/alert/getAlertSummary", + "alerting:apm.transaction_duration/apm/alert/update", + "alerting:apm.anomaly/apm/alert/get", + "alerting:apm.anomaly/apm/alert/find", + "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/apm/alert/getAlertSummary", + "alerting:apm.anomaly/apm/alert/update", + "api:infra", + "app:infra", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/infra", + "ui:navLinks/logs", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-ui-source/create", + "saved_object:infrastructure-ui-source/bulk_create", + "saved_object:infrastructure-ui-source/update", + "saved_object:infrastructure-ui-source/bulk_update", + "saved_object:infrastructure-ui-source/delete", + "saved_object:infrastructure-ui-source/bulk_delete", + "saved_object:infrastructure-ui-source/share_to_space", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/create", + "saved_object:infrastructure-monitoring-log-view/bulk_create", + "saved_object:infrastructure-monitoring-log-view/update", + "saved_object:infrastructure-monitoring-log-view/bulk_update", + "saved_object:infrastructure-monitoring-log-view/delete", + "saved_object:infrastructure-monitoring-log-view/bulk_delete", + "saved_object:infrastructure-monitoring-log-view/share_to_space", + "ui:logs/show", + "ui:logs/configureSource", + "ui:logs/save", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/rule/create", + "alerting:logs.alert.document.count/logs/rule/delete", + "alerting:logs.alert.document.count/logs/rule/update", + "alerting:logs.alert.document.count/logs/rule/updateApiKey", + "alerting:logs.alert.document.count/logs/rule/enable", + "alerting:logs.alert.document.count/logs/rule/disable", + "alerting:logs.alert.document.count/logs/rule/muteAll", + "alerting:logs.alert.document.count/logs/rule/unmuteAll", + "alerting:logs.alert.document.count/logs/rule/muteAlert", + "alerting:logs.alert.document.count/logs/rule/unmuteAlert", + "alerting:logs.alert.document.count/logs/rule/snooze", + "alerting:logs.alert.document.count/logs/rule/bulkEdit", + "alerting:logs.alert.document.count/logs/rule/bulkDelete", + "alerting:logs.alert.document.count/logs/rule/bulkEnable", + "alerting:logs.alert.document.count/logs/rule/bulkDisable", + "alerting:logs.alert.document.count/logs/rule/unsnooze", + "alerting:logs.alert.document.count/logs/rule/runSoon", + "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", + "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/create", + "alerting:.es-query/logs/rule/delete", + "alerting:.es-query/logs/rule/update", + "alerting:.es-query/logs/rule/updateApiKey", + "alerting:.es-query/logs/rule/enable", + "alerting:.es-query/logs/rule/disable", + "alerting:.es-query/logs/rule/muteAll", + "alerting:.es-query/logs/rule/unmuteAll", + "alerting:.es-query/logs/rule/muteAlert", + "alerting:.es-query/logs/rule/unmuteAlert", + "alerting:.es-query/logs/rule/snooze", + "alerting:.es-query/logs/rule/bulkEdit", + "alerting:.es-query/logs/rule/bulkDelete", + "alerting:.es-query/logs/rule/bulkEnable", + "alerting:.es-query/logs/rule/bulkDisable", + "alerting:.es-query/logs/rule/unsnooze", + "alerting:.es-query/logs/rule/runSoon", + "alerting:.es-query/logs/rule/scheduleBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_read": Array [ + "login:", + "api:apm", + "api:rac", + "app:apm", + "app:ux", + "app:kibana", + "ui:catalogue/apm", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/apm", + "ui:navLinks/ux", + "ui:navLinks/kibana", + "saved_object:apm-indices/bulk_get", + "saved_object:apm-indices/get", + "saved_object:apm-indices/find", + "saved_object:apm-indices/open_point_in_time", + "saved_object:apm-indices/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:apm/show", + "ui:apm/alerting:show", + "alerting:apm.error_rate/apm/rule/get", + "alerting:apm.error_rate/apm/rule/getRuleState", + "alerting:apm.error_rate/apm/rule/getAlertSummary", + "alerting:apm.error_rate/apm/rule/getExecutionLog", + "alerting:apm.error_rate/apm/rule/getActionErrorLog", + "alerting:apm.error_rate/apm/rule/find", + "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/apm/rule/getBackfill", + "alerting:apm.error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_error_rate/apm/rule/get", + "alerting:apm.transaction_error_rate/apm/rule/getRuleState", + "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/apm/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/apm/rule/find", + "alerting:apm.transaction_error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/apm/rule/getBackfill", + "alerting:apm.transaction_error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_duration/apm/rule/get", + "alerting:apm.transaction_duration/apm/rule/getRuleState", + "alerting:apm.transaction_duration/apm/rule/getAlertSummary", + "alerting:apm.transaction_duration/apm/rule/getExecutionLog", + "alerting:apm.transaction_duration/apm/rule/getActionErrorLog", + "alerting:apm.transaction_duration/apm/rule/find", + "alerting:apm.transaction_duration/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/apm/rule/getBackfill", + "alerting:apm.transaction_duration/apm/rule/findBackfill", + "alerting:apm.anomaly/apm/rule/get", + "alerting:apm.anomaly/apm/rule/getRuleState", + "alerting:apm.anomaly/apm/rule/getAlertSummary", + "alerting:apm.anomaly/apm/rule/getExecutionLog", + "alerting:apm.anomaly/apm/rule/getActionErrorLog", + "alerting:apm.anomaly/apm/rule/find", + "alerting:apm.anomaly/apm/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/apm/rule/getBackfill", + "alerting:apm.anomaly/apm/rule/findBackfill", + "alerting:apm.error_rate/apm/alert/get", + "alerting:apm.error_rate/apm/alert/find", + "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/alert/get", + "alerting:apm.transaction_error_rate/apm/alert/find", + "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_duration/apm/alert/get", + "alerting:apm.transaction_duration/apm/alert/find", + "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/apm/alert/getAlertSummary", + "alerting:apm.anomaly/apm/alert/get", + "alerting:apm.anomaly/apm/alert/find", + "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/apm/alert/getAlertSummary", + "api:infra", + "app:infra", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/infra", + "ui:navLinks/logs", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "ui:logs/show", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + "read": Array [ + "login:", + "api:apm", + "api:rac", + "app:apm", + "app:ux", + "app:kibana", + "ui:catalogue/apm", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/apm", + "ui:navLinks/ux", + "ui:navLinks/kibana", + "saved_object:apm-indices/bulk_get", + "saved_object:apm-indices/get", + "saved_object:apm-indices/find", + "saved_object:apm-indices/open_point_in_time", + "saved_object:apm-indices/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:apm/show", + "ui:apm/alerting:show", + "alerting:apm.error_rate/apm/rule/get", + "alerting:apm.error_rate/apm/rule/getRuleState", + "alerting:apm.error_rate/apm/rule/getAlertSummary", + "alerting:apm.error_rate/apm/rule/getExecutionLog", + "alerting:apm.error_rate/apm/rule/getActionErrorLog", + "alerting:apm.error_rate/apm/rule/find", + "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/apm/rule/getBackfill", + "alerting:apm.error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_error_rate/apm/rule/get", + "alerting:apm.transaction_error_rate/apm/rule/getRuleState", + "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/apm/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/apm/rule/find", + "alerting:apm.transaction_error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/apm/rule/getBackfill", + "alerting:apm.transaction_error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_duration/apm/rule/get", + "alerting:apm.transaction_duration/apm/rule/getRuleState", + "alerting:apm.transaction_duration/apm/rule/getAlertSummary", + "alerting:apm.transaction_duration/apm/rule/getExecutionLog", + "alerting:apm.transaction_duration/apm/rule/getActionErrorLog", + "alerting:apm.transaction_duration/apm/rule/find", + "alerting:apm.transaction_duration/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/apm/rule/getBackfill", + "alerting:apm.transaction_duration/apm/rule/findBackfill", + "alerting:apm.anomaly/apm/rule/get", + "alerting:apm.anomaly/apm/rule/getRuleState", + "alerting:apm.anomaly/apm/rule/getAlertSummary", + "alerting:apm.anomaly/apm/rule/getExecutionLog", + "alerting:apm.anomaly/apm/rule/getActionErrorLog", + "alerting:apm.anomaly/apm/rule/find", + "alerting:apm.anomaly/apm/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/apm/rule/getBackfill", + "alerting:apm.anomaly/apm/rule/findBackfill", + "alerting:apm.error_rate/apm/alert/get", + "alerting:apm.error_rate/apm/alert/find", + "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/alert/get", + "alerting:apm.transaction_error_rate/apm/alert/find", + "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_duration/apm/alert/get", + "alerting:apm.transaction_duration/apm/alert/find", + "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/apm/alert/getAlertSummary", + "alerting:apm.anomaly/apm/alert/get", + "alerting:apm.anomaly/apm/alert/find", + "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/apm/alert/getAlertSummary", + "api:infra", + "app:infra", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/infra", + "ui:navLinks/logs", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "ui:logs/show", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + }, + "dashboard": Object { + "all": Array [ + "login:", + "api:bulkGetUserProfiles", + "api:store_search_session", + "api:generateReport", + "api:downloadCsv", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "ui:dashboard/createNew", + "ui:dashboard/show", + "ui:dashboard/showWriteControls", + "ui:dashboard/saveQuery", + "ui:dashboard/createShortUrl", + "ui:dashboard/storeSearchSession", + "ui:dashboard/generateScreenshot", + "ui:dashboard/downloadCsv", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps/save", + "ui:maps/show", + "ui:maps/saveQuery", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "ui:visualize/show", + "ui:visualize/delete", + "ui:visualize/save", + "ui:visualize/saveQuery", + "ui:visualize/createShortUrl", + "ui:visualize/generateScreenshot", + ], + "download_csv_report": Array [ + "login:", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + ], + "generate_report": Array [ + "login:", + "api:generateReport", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/generateScreenshot", + ], + "minimal_all": Array [ + "login:", + "api:bulkGetUserProfiles", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:dashboard/createNew", + "ui:dashboard/show", + "ui:dashboard/showWriteControls", + "ui:dashboard/saveQuery", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps/save", + "ui:maps/show", + "ui:maps/saveQuery", + "api:generateReport", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:visualize/show", + "ui:visualize/delete", + "ui:visualize/save", + "ui:visualize/saveQuery", + "ui:visualize/createShortUrl", + "ui:visualize/generateScreenshot", + ], + "minimal_read": Array [ + "login:", + "api:bulkGetUserProfiles", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:dashboard/show", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:visualize/show", + "ui:visualize/createShortUrl", + ], + "read": Array [ + "login:", + "api:bulkGetUserProfiles", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "ui:dashboard/show", + "ui:dashboard/createShortUrl", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "ui:visualize/show", + "ui:visualize/createShortUrl", + ], + "store_search_session": Array [ + "login:", + "api:store_search_session", + "ui:management/kibana/search_sessions", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "ui:dashboard/storeSearchSession", + ], + "url_create": Array [ + "login:", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:dashboard/createShortUrl", + ], + }, + "discover": Object { + "all": Array [ + "login:", + "api:fileUpload:analyzeFile", + "api:store_search_session", + "api:generateReport", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + "ui:discover/createShortUrl", + "ui:discover/storeSearchSession", + "ui:discover/generateCsv", + "api:rac", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "generate_report": Array [ + "login:", + "api:generateReport", + "ui:management/insightsAndAlerting/reporting", + "ui:discover/generateCsv", + ], + "minimal_all": Array [ + "login:", + "api:fileUpload:analyzeFile", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + "api:rac", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_read": Array [ + "login:", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:discover/show", + "api:rac", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + "read": Array [ + "login:", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "ui:discover/show", + "ui:discover/createShortUrl", + "api:rac", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + "store_search_session": Array [ + "login:", + "api:store_search_session", + "ui:management/kibana/search_sessions", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "ui:discover/storeSearchSession", + ], + "url_create": Array [ + "login:", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:discover/createShortUrl", + ], + }, + "fleetv2": Object { + "all": Array [ + "login:", + "api:fleet-read", + "api:fleet-all", + "app:fleet", + "ui:catalogue/fleet", + "ui:navLinks/fleet", + "saved_object:ingest-outputs/bulk_get", + "saved_object:ingest-outputs/get", + "saved_object:ingest-outputs/find", + "saved_object:ingest-outputs/open_point_in_time", + "saved_object:ingest-outputs/close_point_in_time", + "saved_object:ingest-outputs/create", + "saved_object:ingest-outputs/bulk_create", + "saved_object:ingest-outputs/update", + "saved_object:ingest-outputs/bulk_update", + "saved_object:ingest-outputs/delete", + "saved_object:ingest-outputs/bulk_delete", + "saved_object:ingest-outputs/share_to_space", + "saved_object:ingest-agent-policies/bulk_get", + "saved_object:ingest-agent-policies/get", + "saved_object:ingest-agent-policies/find", + "saved_object:ingest-agent-policies/open_point_in_time", + "saved_object:ingest-agent-policies/close_point_in_time", + "saved_object:ingest-agent-policies/create", + "saved_object:ingest-agent-policies/bulk_create", + "saved_object:ingest-agent-policies/update", + "saved_object:ingest-agent-policies/bulk_update", + "saved_object:ingest-agent-policies/delete", + "saved_object:ingest-agent-policies/bulk_delete", + "saved_object:ingest-agent-policies/share_to_space", + "saved_object:ingest-package-policies/bulk_get", + "saved_object:ingest-package-policies/get", + "saved_object:ingest-package-policies/find", + "saved_object:ingest-package-policies/open_point_in_time", + "saved_object:ingest-package-policies/close_point_in_time", + "saved_object:ingest-package-policies/create", + "saved_object:ingest-package-policies/bulk_create", + "saved_object:ingest-package-policies/update", + "saved_object:ingest-package-policies/bulk_update", + "saved_object:ingest-package-policies/delete", + "saved_object:ingest-package-policies/bulk_delete", + "saved_object:ingest-package-policies/share_to_space", + "saved_object:epm-packages/bulk_get", + "saved_object:epm-packages/get", + "saved_object:epm-packages/find", + "saved_object:epm-packages/open_point_in_time", + "saved_object:epm-packages/close_point_in_time", + "saved_object:epm-packages/create", + "saved_object:epm-packages/bulk_create", + "saved_object:epm-packages/update", + "saved_object:epm-packages/bulk_update", + "saved_object:epm-packages/delete", + "saved_object:epm-packages/bulk_delete", + "saved_object:epm-packages/share_to_space", + "saved_object:epm-packages-assets/bulk_get", + "saved_object:epm-packages-assets/get", + "saved_object:epm-packages-assets/find", + "saved_object:epm-packages-assets/open_point_in_time", + "saved_object:epm-packages-assets/close_point_in_time", + "saved_object:epm-packages-assets/create", + "saved_object:epm-packages-assets/bulk_create", + "saved_object:epm-packages-assets/update", + "saved_object:epm-packages-assets/bulk_update", + "saved_object:epm-packages-assets/delete", + "saved_object:epm-packages-assets/bulk_delete", + "saved_object:epm-packages-assets/share_to_space", + "saved_object:fleet-preconfiguration-deletion-record/bulk_get", + "saved_object:fleet-preconfiguration-deletion-record/get", + "saved_object:fleet-preconfiguration-deletion-record/find", + "saved_object:fleet-preconfiguration-deletion-record/open_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/close_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/create", + "saved_object:fleet-preconfiguration-deletion-record/bulk_create", + "saved_object:fleet-preconfiguration-deletion-record/update", + "saved_object:fleet-preconfiguration-deletion-record/bulk_update", + "saved_object:fleet-preconfiguration-deletion-record/delete", + "saved_object:fleet-preconfiguration-deletion-record/bulk_delete", + "saved_object:fleet-preconfiguration-deletion-record/share_to_space", + "saved_object:ingest-download-sources/bulk_get", + "saved_object:ingest-download-sources/get", + "saved_object:ingest-download-sources/find", + "saved_object:ingest-download-sources/open_point_in_time", + "saved_object:ingest-download-sources/close_point_in_time", + "saved_object:ingest-download-sources/create", + "saved_object:ingest-download-sources/bulk_create", + "saved_object:ingest-download-sources/update", + "saved_object:ingest-download-sources/bulk_update", + "saved_object:ingest-download-sources/delete", + "saved_object:ingest-download-sources/bulk_delete", + "saved_object:ingest-download-sources/share_to_space", + "saved_object:fleet-fleet-server-host/bulk_get", + "saved_object:fleet-fleet-server-host/get", + "saved_object:fleet-fleet-server-host/find", + "saved_object:fleet-fleet-server-host/open_point_in_time", + "saved_object:fleet-fleet-server-host/close_point_in_time", + "saved_object:fleet-fleet-server-host/create", + "saved_object:fleet-fleet-server-host/bulk_create", + "saved_object:fleet-fleet-server-host/update", + "saved_object:fleet-fleet-server-host/bulk_update", + "saved_object:fleet-fleet-server-host/delete", + "saved_object:fleet-fleet-server-host/bulk_delete", + "saved_object:fleet-fleet-server-host/share_to_space", + "saved_object:fleet-proxy/bulk_get", + "saved_object:fleet-proxy/get", + "saved_object:fleet-proxy/find", + "saved_object:fleet-proxy/open_point_in_time", + "saved_object:fleet-proxy/close_point_in_time", + "saved_object:fleet-proxy/create", + "saved_object:fleet-proxy/bulk_create", + "saved_object:fleet-proxy/update", + "saved_object:fleet-proxy/bulk_update", + "saved_object:fleet-proxy/delete", + "saved_object:fleet-proxy/bulk_delete", + "saved_object:fleet-proxy/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:fleetv2/read", + "ui:fleetv2/all", + "api:infra", + "api:rac", + "app:infra", + "app:logs", + "app:kibana", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/logs", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-ui-source/create", + "saved_object:infrastructure-ui-source/bulk_create", + "saved_object:infrastructure-ui-source/update", + "saved_object:infrastructure-ui-source/bulk_update", + "saved_object:infrastructure-ui-source/delete", + "saved_object:infrastructure-ui-source/bulk_delete", + "saved_object:infrastructure-ui-source/share_to_space", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/create", + "saved_object:infrastructure-monitoring-log-view/bulk_create", + "saved_object:infrastructure-monitoring-log-view/update", + "saved_object:infrastructure-monitoring-log-view/bulk_update", + "saved_object:infrastructure-monitoring-log-view/delete", + "saved_object:infrastructure-monitoring-log-view/bulk_delete", + "saved_object:infrastructure-monitoring-log-view/share_to_space", + "ui:logs/show", + "ui:logs/configureSource", + "ui:logs/save", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/rule/create", + "alerting:logs.alert.document.count/logs/rule/delete", + "alerting:logs.alert.document.count/logs/rule/update", + "alerting:logs.alert.document.count/logs/rule/updateApiKey", + "alerting:logs.alert.document.count/logs/rule/enable", + "alerting:logs.alert.document.count/logs/rule/disable", + "alerting:logs.alert.document.count/logs/rule/muteAll", + "alerting:logs.alert.document.count/logs/rule/unmuteAll", + "alerting:logs.alert.document.count/logs/rule/muteAlert", + "alerting:logs.alert.document.count/logs/rule/unmuteAlert", + "alerting:logs.alert.document.count/logs/rule/snooze", + "alerting:logs.alert.document.count/logs/rule/bulkEdit", + "alerting:logs.alert.document.count/logs/rule/bulkDelete", + "alerting:logs.alert.document.count/logs/rule/bulkEnable", + "alerting:logs.alert.document.count/logs/rule/bulkDisable", + "alerting:logs.alert.document.count/logs/rule/unsnooze", + "alerting:logs.alert.document.count/logs/rule/runSoon", + "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", + "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/create", + "alerting:.es-query/logs/rule/delete", + "alerting:.es-query/logs/rule/update", + "alerting:.es-query/logs/rule/updateApiKey", + "alerting:.es-query/logs/rule/enable", + "alerting:.es-query/logs/rule/disable", + "alerting:.es-query/logs/rule/muteAll", + "alerting:.es-query/logs/rule/unmuteAll", + "alerting:.es-query/logs/rule/muteAlert", + "alerting:.es-query/logs/rule/unmuteAlert", + "alerting:.es-query/logs/rule/snooze", + "alerting:.es-query/logs/rule/bulkEdit", + "alerting:.es-query/logs/rule/bulkDelete", + "alerting:.es-query/logs/rule/bulkEnable", + "alerting:.es-query/logs/rule/bulkDisable", + "alerting:.es-query/logs/rule/unsnooze", + "alerting:.es-query/logs/rule/runSoon", + "alerting:.es-query/logs/rule/scheduleBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + ], + "minimal_all": Array [ + "login:", + "api:fleet-read", + "api:fleet-all", + "app:fleet", + "ui:catalogue/fleet", + "ui:navLinks/fleet", + "saved_object:ingest-outputs/bulk_get", + "saved_object:ingest-outputs/get", + "saved_object:ingest-outputs/find", + "saved_object:ingest-outputs/open_point_in_time", + "saved_object:ingest-outputs/close_point_in_time", + "saved_object:ingest-outputs/create", + "saved_object:ingest-outputs/bulk_create", + "saved_object:ingest-outputs/update", + "saved_object:ingest-outputs/bulk_update", + "saved_object:ingest-outputs/delete", + "saved_object:ingest-outputs/bulk_delete", + "saved_object:ingest-outputs/share_to_space", + "saved_object:ingest-agent-policies/bulk_get", + "saved_object:ingest-agent-policies/get", + "saved_object:ingest-agent-policies/find", + "saved_object:ingest-agent-policies/open_point_in_time", + "saved_object:ingest-agent-policies/close_point_in_time", + "saved_object:ingest-agent-policies/create", + "saved_object:ingest-agent-policies/bulk_create", + "saved_object:ingest-agent-policies/update", + "saved_object:ingest-agent-policies/bulk_update", + "saved_object:ingest-agent-policies/delete", + "saved_object:ingest-agent-policies/bulk_delete", + "saved_object:ingest-agent-policies/share_to_space", + "saved_object:ingest-package-policies/bulk_get", + "saved_object:ingest-package-policies/get", + "saved_object:ingest-package-policies/find", + "saved_object:ingest-package-policies/open_point_in_time", + "saved_object:ingest-package-policies/close_point_in_time", + "saved_object:ingest-package-policies/create", + "saved_object:ingest-package-policies/bulk_create", + "saved_object:ingest-package-policies/update", + "saved_object:ingest-package-policies/bulk_update", + "saved_object:ingest-package-policies/delete", + "saved_object:ingest-package-policies/bulk_delete", + "saved_object:ingest-package-policies/share_to_space", + "saved_object:epm-packages/bulk_get", + "saved_object:epm-packages/get", + "saved_object:epm-packages/find", + "saved_object:epm-packages/open_point_in_time", + "saved_object:epm-packages/close_point_in_time", + "saved_object:epm-packages/create", + "saved_object:epm-packages/bulk_create", + "saved_object:epm-packages/update", + "saved_object:epm-packages/bulk_update", + "saved_object:epm-packages/delete", + "saved_object:epm-packages/bulk_delete", + "saved_object:epm-packages/share_to_space", + "saved_object:epm-packages-assets/bulk_get", + "saved_object:epm-packages-assets/get", + "saved_object:epm-packages-assets/find", + "saved_object:epm-packages-assets/open_point_in_time", + "saved_object:epm-packages-assets/close_point_in_time", + "saved_object:epm-packages-assets/create", + "saved_object:epm-packages-assets/bulk_create", + "saved_object:epm-packages-assets/update", + "saved_object:epm-packages-assets/bulk_update", + "saved_object:epm-packages-assets/delete", + "saved_object:epm-packages-assets/bulk_delete", + "saved_object:epm-packages-assets/share_to_space", + "saved_object:fleet-preconfiguration-deletion-record/bulk_get", + "saved_object:fleet-preconfiguration-deletion-record/get", + "saved_object:fleet-preconfiguration-deletion-record/find", + "saved_object:fleet-preconfiguration-deletion-record/open_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/close_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/create", + "saved_object:fleet-preconfiguration-deletion-record/bulk_create", + "saved_object:fleet-preconfiguration-deletion-record/update", + "saved_object:fleet-preconfiguration-deletion-record/bulk_update", + "saved_object:fleet-preconfiguration-deletion-record/delete", + "saved_object:fleet-preconfiguration-deletion-record/bulk_delete", + "saved_object:fleet-preconfiguration-deletion-record/share_to_space", + "saved_object:ingest-download-sources/bulk_get", + "saved_object:ingest-download-sources/get", + "saved_object:ingest-download-sources/find", + "saved_object:ingest-download-sources/open_point_in_time", + "saved_object:ingest-download-sources/close_point_in_time", + "saved_object:ingest-download-sources/create", + "saved_object:ingest-download-sources/bulk_create", + "saved_object:ingest-download-sources/update", + "saved_object:ingest-download-sources/bulk_update", + "saved_object:ingest-download-sources/delete", + "saved_object:ingest-download-sources/bulk_delete", + "saved_object:ingest-download-sources/share_to_space", + "saved_object:fleet-fleet-server-host/bulk_get", + "saved_object:fleet-fleet-server-host/get", + "saved_object:fleet-fleet-server-host/find", + "saved_object:fleet-fleet-server-host/open_point_in_time", + "saved_object:fleet-fleet-server-host/close_point_in_time", + "saved_object:fleet-fleet-server-host/create", + "saved_object:fleet-fleet-server-host/bulk_create", + "saved_object:fleet-fleet-server-host/update", + "saved_object:fleet-fleet-server-host/bulk_update", + "saved_object:fleet-fleet-server-host/delete", + "saved_object:fleet-fleet-server-host/bulk_delete", + "saved_object:fleet-fleet-server-host/share_to_space", + "saved_object:fleet-proxy/bulk_get", + "saved_object:fleet-proxy/get", + "saved_object:fleet-proxy/find", + "saved_object:fleet-proxy/open_point_in_time", + "saved_object:fleet-proxy/close_point_in_time", + "saved_object:fleet-proxy/create", + "saved_object:fleet-proxy/bulk_create", + "saved_object:fleet-proxy/update", + "saved_object:fleet-proxy/bulk_update", + "saved_object:fleet-proxy/delete", + "saved_object:fleet-proxy/bulk_delete", + "saved_object:fleet-proxy/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:fleetv2/read", + "ui:fleetv2/all", + "api:infra", + "api:rac", + "app:infra", + "app:logs", + "app:kibana", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/logs", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-ui-source/create", + "saved_object:infrastructure-ui-source/bulk_create", + "saved_object:infrastructure-ui-source/update", + "saved_object:infrastructure-ui-source/bulk_update", + "saved_object:infrastructure-ui-source/delete", + "saved_object:infrastructure-ui-source/bulk_delete", + "saved_object:infrastructure-ui-source/share_to_space", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/create", + "saved_object:infrastructure-monitoring-log-view/bulk_create", + "saved_object:infrastructure-monitoring-log-view/update", + "saved_object:infrastructure-monitoring-log-view/bulk_update", + "saved_object:infrastructure-monitoring-log-view/delete", + "saved_object:infrastructure-monitoring-log-view/bulk_delete", + "saved_object:infrastructure-monitoring-log-view/share_to_space", + "ui:logs/show", + "ui:logs/configureSource", + "ui:logs/save", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/rule/create", + "alerting:logs.alert.document.count/logs/rule/delete", + "alerting:logs.alert.document.count/logs/rule/update", + "alerting:logs.alert.document.count/logs/rule/updateApiKey", + "alerting:logs.alert.document.count/logs/rule/enable", + "alerting:logs.alert.document.count/logs/rule/disable", + "alerting:logs.alert.document.count/logs/rule/muteAll", + "alerting:logs.alert.document.count/logs/rule/unmuteAll", + "alerting:logs.alert.document.count/logs/rule/muteAlert", + "alerting:logs.alert.document.count/logs/rule/unmuteAlert", + "alerting:logs.alert.document.count/logs/rule/snooze", + "alerting:logs.alert.document.count/logs/rule/bulkEdit", + "alerting:logs.alert.document.count/logs/rule/bulkDelete", + "alerting:logs.alert.document.count/logs/rule/bulkEnable", + "alerting:logs.alert.document.count/logs/rule/bulkDisable", + "alerting:logs.alert.document.count/logs/rule/unsnooze", + "alerting:logs.alert.document.count/logs/rule/runSoon", + "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", + "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/create", + "alerting:.es-query/logs/rule/delete", + "alerting:.es-query/logs/rule/update", + "alerting:.es-query/logs/rule/updateApiKey", + "alerting:.es-query/logs/rule/enable", + "alerting:.es-query/logs/rule/disable", + "alerting:.es-query/logs/rule/muteAll", + "alerting:.es-query/logs/rule/unmuteAll", + "alerting:.es-query/logs/rule/muteAlert", + "alerting:.es-query/logs/rule/unmuteAlert", + "alerting:.es-query/logs/rule/snooze", + "alerting:.es-query/logs/rule/bulkEdit", + "alerting:.es-query/logs/rule/bulkDelete", + "alerting:.es-query/logs/rule/bulkEnable", + "alerting:.es-query/logs/rule/bulkDisable", + "alerting:.es-query/logs/rule/unsnooze", + "alerting:.es-query/logs/rule/runSoon", + "alerting:.es-query/logs/rule/scheduleBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + ], + "minimal_read": Array [ + "login:", + "api:fleet-read", + "app:fleet", + "ui:catalogue/fleet", + "ui:navLinks/fleet", + "saved_object:ingest-outputs/bulk_get", + "saved_object:ingest-outputs/get", + "saved_object:ingest-outputs/find", + "saved_object:ingest-outputs/open_point_in_time", + "saved_object:ingest-outputs/close_point_in_time", + "saved_object:ingest-agent-policies/bulk_get", + "saved_object:ingest-agent-policies/get", + "saved_object:ingest-agent-policies/find", + "saved_object:ingest-agent-policies/open_point_in_time", + "saved_object:ingest-agent-policies/close_point_in_time", + "saved_object:ingest-package-policies/bulk_get", + "saved_object:ingest-package-policies/get", + "saved_object:ingest-package-policies/find", + "saved_object:ingest-package-policies/open_point_in_time", + "saved_object:ingest-package-policies/close_point_in_time", + "saved_object:epm-packages/bulk_get", + "saved_object:epm-packages/get", + "saved_object:epm-packages/find", + "saved_object:epm-packages/open_point_in_time", + "saved_object:epm-packages/close_point_in_time", + "saved_object:epm-packages-assets/bulk_get", + "saved_object:epm-packages-assets/get", + "saved_object:epm-packages-assets/find", + "saved_object:epm-packages-assets/open_point_in_time", + "saved_object:epm-packages-assets/close_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/bulk_get", + "saved_object:fleet-preconfiguration-deletion-record/get", + "saved_object:fleet-preconfiguration-deletion-record/find", + "saved_object:fleet-preconfiguration-deletion-record/open_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/close_point_in_time", + "saved_object:ingest-download-sources/bulk_get", + "saved_object:ingest-download-sources/get", + "saved_object:ingest-download-sources/find", + "saved_object:ingest-download-sources/open_point_in_time", + "saved_object:ingest-download-sources/close_point_in_time", + "saved_object:fleet-fleet-server-host/bulk_get", + "saved_object:fleet-fleet-server-host/get", + "saved_object:fleet-fleet-server-host/find", + "saved_object:fleet-fleet-server-host/open_point_in_time", + "saved_object:fleet-fleet-server-host/close_point_in_time", + "saved_object:fleet-proxy/bulk_get", + "saved_object:fleet-proxy/get", + "saved_object:fleet-proxy/find", + "saved_object:fleet-proxy/open_point_in_time", + "saved_object:fleet-proxy/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:fleetv2/read", + "api:infra", + "api:rac", + "app:infra", + "app:logs", + "app:kibana", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/logs", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "ui:logs/show", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + ], + "read": Array [ + "login:", + "api:fleet-read", + "app:fleet", + "ui:catalogue/fleet", + "ui:navLinks/fleet", + "saved_object:ingest-outputs/bulk_get", + "saved_object:ingest-outputs/get", + "saved_object:ingest-outputs/find", + "saved_object:ingest-outputs/open_point_in_time", + "saved_object:ingest-outputs/close_point_in_time", + "saved_object:ingest-agent-policies/bulk_get", + "saved_object:ingest-agent-policies/get", + "saved_object:ingest-agent-policies/find", + "saved_object:ingest-agent-policies/open_point_in_time", + "saved_object:ingest-agent-policies/close_point_in_time", + "saved_object:ingest-package-policies/bulk_get", + "saved_object:ingest-package-policies/get", + "saved_object:ingest-package-policies/find", + "saved_object:ingest-package-policies/open_point_in_time", + "saved_object:ingest-package-policies/close_point_in_time", + "saved_object:epm-packages/bulk_get", + "saved_object:epm-packages/get", + "saved_object:epm-packages/find", + "saved_object:epm-packages/open_point_in_time", + "saved_object:epm-packages/close_point_in_time", + "saved_object:epm-packages-assets/bulk_get", + "saved_object:epm-packages-assets/get", + "saved_object:epm-packages-assets/find", + "saved_object:epm-packages-assets/open_point_in_time", + "saved_object:epm-packages-assets/close_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/bulk_get", + "saved_object:fleet-preconfiguration-deletion-record/get", + "saved_object:fleet-preconfiguration-deletion-record/find", + "saved_object:fleet-preconfiguration-deletion-record/open_point_in_time", + "saved_object:fleet-preconfiguration-deletion-record/close_point_in_time", + "saved_object:ingest-download-sources/bulk_get", + "saved_object:ingest-download-sources/get", + "saved_object:ingest-download-sources/find", + "saved_object:ingest-download-sources/open_point_in_time", + "saved_object:ingest-download-sources/close_point_in_time", + "saved_object:fleet-fleet-server-host/bulk_get", + "saved_object:fleet-fleet-server-host/get", + "saved_object:fleet-fleet-server-host/find", + "saved_object:fleet-fleet-server-host/open_point_in_time", + "saved_object:fleet-fleet-server-host/close_point_in_time", + "saved_object:fleet-proxy/bulk_get", + "saved_object:fleet-proxy/get", + "saved_object:fleet-proxy/find", + "saved_object:fleet-proxy/open_point_in_time", + "saved_object:fleet-proxy/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:fleetv2/read", + "api:infra", + "api:rac", + "app:infra", + "app:logs", + "app:kibana", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/logs", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "ui:logs/show", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + ], + }, + "infrastructure": Object { + "all": Array [ + "login:", + "api:infra", + "api:rac", + "app:infra", + "app:metrics", + "app:kibana", + "ui:catalogue/infraops", + "ui:catalogue/metrics", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/metrics", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-ui-source/create", + "saved_object:infrastructure-ui-source/bulk_create", + "saved_object:infrastructure-ui-source/update", + "saved_object:infrastructure-ui-source/bulk_update", + "saved_object:infrastructure-ui-source/delete", + "saved_object:infrastructure-ui-source/bulk_delete", + "saved_object:infrastructure-ui-source/share_to_space", + "saved_object:metrics-data-source/bulk_get", + "saved_object:metrics-data-source/get", + "saved_object:metrics-data-source/find", + "saved_object:metrics-data-source/open_point_in_time", + "saved_object:metrics-data-source/close_point_in_time", + "saved_object:metrics-data-source/create", + "saved_object:metrics-data-source/bulk_create", + "saved_object:metrics-data-source/update", + "saved_object:metrics-data-source/bulk_update", + "saved_object:metrics-data-source/delete", + "saved_object:metrics-data-source/bulk_delete", + "saved_object:metrics-data-source/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:infrastructure/show", + "ui:infrastructure/configureSource", + "ui:infrastructure/save", + "alerting:metrics.alert.threshold/infrastructure/rule/get", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/infrastructure/rule/find", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/create", + "alerting:metrics.alert.threshold/infrastructure/rule/delete", + "alerting:metrics.alert.threshold/infrastructure/rule/update", + "alerting:metrics.alert.threshold/infrastructure/rule/updateApiKey", + "alerting:metrics.alert.threshold/infrastructure/rule/enable", + "alerting:metrics.alert.threshold/infrastructure/rule/disable", + "alerting:metrics.alert.threshold/infrastructure/rule/muteAll", + "alerting:metrics.alert.threshold/infrastructure/rule/unmuteAll", + "alerting:metrics.alert.threshold/infrastructure/rule/muteAlert", + "alerting:metrics.alert.threshold/infrastructure/rule/unmuteAlert", + "alerting:metrics.alert.threshold/infrastructure/rule/snooze", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkEdit", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkDelete", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkEnable", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkDisable", + "alerting:metrics.alert.threshold/infrastructure/rule/unsnooze", + "alerting:metrics.alert.threshold/infrastructure/rule/runSoon", + "alerting:metrics.alert.threshold/infrastructure/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/create", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/delete", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/update", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/enable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/disable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/snooze", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/deleteBackfill", + "alerting:.es-query/infrastructure/rule/get", + "alerting:.es-query/infrastructure/rule/getRuleState", + "alerting:.es-query/infrastructure/rule/getAlertSummary", + "alerting:.es-query/infrastructure/rule/getExecutionLog", + "alerting:.es-query/infrastructure/rule/getActionErrorLog", + "alerting:.es-query/infrastructure/rule/find", + "alerting:.es-query/infrastructure/rule/getRuleExecutionKPI", + "alerting:.es-query/infrastructure/rule/getBackfill", + "alerting:.es-query/infrastructure/rule/findBackfill", + "alerting:.es-query/infrastructure/rule/create", + "alerting:.es-query/infrastructure/rule/delete", + "alerting:.es-query/infrastructure/rule/update", + "alerting:.es-query/infrastructure/rule/updateApiKey", + "alerting:.es-query/infrastructure/rule/enable", + "alerting:.es-query/infrastructure/rule/disable", + "alerting:.es-query/infrastructure/rule/muteAll", + "alerting:.es-query/infrastructure/rule/unmuteAll", + "alerting:.es-query/infrastructure/rule/muteAlert", + "alerting:.es-query/infrastructure/rule/unmuteAlert", + "alerting:.es-query/infrastructure/rule/snooze", + "alerting:.es-query/infrastructure/rule/bulkEdit", + "alerting:.es-query/infrastructure/rule/bulkDelete", + "alerting:.es-query/infrastructure/rule/bulkEnable", + "alerting:.es-query/infrastructure/rule/bulkDisable", + "alerting:.es-query/infrastructure/rule/unsnooze", + "alerting:.es-query/infrastructure/rule/runSoon", + "alerting:.es-query/infrastructure/rule/scheduleBackfill", + "alerting:.es-query/infrastructure/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/get", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/find", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/findBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/create", + "alerting:observability.rules.custom_threshold/infrastructure/rule/delete", + "alerting:observability.rules.custom_threshold/infrastructure/rule/update", + "alerting:observability.rules.custom_threshold/infrastructure/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/infrastructure/rule/enable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/disable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/muteAll", + "alerting:observability.rules.custom_threshold/infrastructure/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/infrastructure/rule/muteAlert", + "alerting:observability.rules.custom_threshold/infrastructure/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/infrastructure/rule/snooze", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/unsnooze", + "alerting:observability.rules.custom_threshold/infrastructure/rule/runSoon", + "alerting:observability.rules.custom_threshold/infrastructure/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.threshold/infrastructure/alert/get", + "alerting:metrics.alert.threshold/infrastructure/alert/find", + "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.threshold/infrastructure/alert/update", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/update", + "alerting:.es-query/infrastructure/alert/get", + "alerting:.es-query/infrastructure/alert/find", + "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/infrastructure/alert/getAlertSummary", + "alerting:.es-query/infrastructure/alert/update", + "alerting:observability.rules.custom_threshold/infrastructure/alert/get", + "alerting:observability.rules.custom_threshold/infrastructure/alert/find", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/update", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/logs", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/create", + "saved_object:infrastructure-monitoring-log-view/bulk_create", + "saved_object:infrastructure-monitoring-log-view/update", + "saved_object:infrastructure-monitoring-log-view/bulk_update", + "saved_object:infrastructure-monitoring-log-view/delete", + "saved_object:infrastructure-monitoring-log-view/bulk_delete", + "saved_object:infrastructure-monitoring-log-view/share_to_space", + "ui:logs/show", + "ui:logs/configureSource", + "ui:logs/save", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/rule/create", + "alerting:logs.alert.document.count/logs/rule/delete", + "alerting:logs.alert.document.count/logs/rule/update", + "alerting:logs.alert.document.count/logs/rule/updateApiKey", + "alerting:logs.alert.document.count/logs/rule/enable", + "alerting:logs.alert.document.count/logs/rule/disable", + "alerting:logs.alert.document.count/logs/rule/muteAll", + "alerting:logs.alert.document.count/logs/rule/unmuteAll", + "alerting:logs.alert.document.count/logs/rule/muteAlert", + "alerting:logs.alert.document.count/logs/rule/unmuteAlert", + "alerting:logs.alert.document.count/logs/rule/snooze", + "alerting:logs.alert.document.count/logs/rule/bulkEdit", + "alerting:logs.alert.document.count/logs/rule/bulkDelete", + "alerting:logs.alert.document.count/logs/rule/bulkEnable", + "alerting:logs.alert.document.count/logs/rule/bulkDisable", + "alerting:logs.alert.document.count/logs/rule/unsnooze", + "alerting:logs.alert.document.count/logs/rule/runSoon", + "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", + "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/create", + "alerting:.es-query/logs/rule/delete", + "alerting:.es-query/logs/rule/update", + "alerting:.es-query/logs/rule/updateApiKey", + "alerting:.es-query/logs/rule/enable", + "alerting:.es-query/logs/rule/disable", + "alerting:.es-query/logs/rule/muteAll", + "alerting:.es-query/logs/rule/unmuteAll", + "alerting:.es-query/logs/rule/muteAlert", + "alerting:.es-query/logs/rule/unmuteAlert", + "alerting:.es-query/logs/rule/snooze", + "alerting:.es-query/logs/rule/bulkEdit", + "alerting:.es-query/logs/rule/bulkDelete", + "alerting:.es-query/logs/rule/bulkEnable", + "alerting:.es-query/logs/rule/bulkDisable", + "alerting:.es-query/logs/rule/unsnooze", + "alerting:.es-query/logs/rule/runSoon", + "alerting:.es-query/logs/rule/scheduleBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_all": Array [ + "login:", + "api:infra", + "api:rac", + "app:infra", + "app:metrics", + "app:kibana", + "ui:catalogue/infraops", + "ui:catalogue/metrics", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/metrics", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:infrastructure-ui-source/create", + "saved_object:infrastructure-ui-source/bulk_create", + "saved_object:infrastructure-ui-source/update", + "saved_object:infrastructure-ui-source/bulk_update", + "saved_object:infrastructure-ui-source/delete", + "saved_object:infrastructure-ui-source/bulk_delete", + "saved_object:infrastructure-ui-source/share_to_space", + "saved_object:metrics-data-source/bulk_get", + "saved_object:metrics-data-source/get", + "saved_object:metrics-data-source/find", + "saved_object:metrics-data-source/open_point_in_time", + "saved_object:metrics-data-source/close_point_in_time", + "saved_object:metrics-data-source/create", + "saved_object:metrics-data-source/bulk_create", + "saved_object:metrics-data-source/update", + "saved_object:metrics-data-source/bulk_update", + "saved_object:metrics-data-source/delete", + "saved_object:metrics-data-source/bulk_delete", + "saved_object:metrics-data-source/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:infrastructure/show", + "ui:infrastructure/configureSource", + "ui:infrastructure/save", + "alerting:metrics.alert.threshold/infrastructure/rule/get", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/infrastructure/rule/find", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/create", + "alerting:metrics.alert.threshold/infrastructure/rule/delete", + "alerting:metrics.alert.threshold/infrastructure/rule/update", + "alerting:metrics.alert.threshold/infrastructure/rule/updateApiKey", + "alerting:metrics.alert.threshold/infrastructure/rule/enable", + "alerting:metrics.alert.threshold/infrastructure/rule/disable", + "alerting:metrics.alert.threshold/infrastructure/rule/muteAll", + "alerting:metrics.alert.threshold/infrastructure/rule/unmuteAll", + "alerting:metrics.alert.threshold/infrastructure/rule/muteAlert", + "alerting:metrics.alert.threshold/infrastructure/rule/unmuteAlert", + "alerting:metrics.alert.threshold/infrastructure/rule/snooze", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkEdit", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkDelete", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkEnable", + "alerting:metrics.alert.threshold/infrastructure/rule/bulkDisable", + "alerting:metrics.alert.threshold/infrastructure/rule/unsnooze", + "alerting:metrics.alert.threshold/infrastructure/rule/runSoon", + "alerting:metrics.alert.threshold/infrastructure/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/create", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/delete", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/update", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/enable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/disable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/snooze", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/deleteBackfill", + "alerting:.es-query/infrastructure/rule/get", + "alerting:.es-query/infrastructure/rule/getRuleState", + "alerting:.es-query/infrastructure/rule/getAlertSummary", + "alerting:.es-query/infrastructure/rule/getExecutionLog", + "alerting:.es-query/infrastructure/rule/getActionErrorLog", + "alerting:.es-query/infrastructure/rule/find", + "alerting:.es-query/infrastructure/rule/getRuleExecutionKPI", + "alerting:.es-query/infrastructure/rule/getBackfill", + "alerting:.es-query/infrastructure/rule/findBackfill", + "alerting:.es-query/infrastructure/rule/create", + "alerting:.es-query/infrastructure/rule/delete", + "alerting:.es-query/infrastructure/rule/update", + "alerting:.es-query/infrastructure/rule/updateApiKey", + "alerting:.es-query/infrastructure/rule/enable", + "alerting:.es-query/infrastructure/rule/disable", + "alerting:.es-query/infrastructure/rule/muteAll", + "alerting:.es-query/infrastructure/rule/unmuteAll", + "alerting:.es-query/infrastructure/rule/muteAlert", + "alerting:.es-query/infrastructure/rule/unmuteAlert", + "alerting:.es-query/infrastructure/rule/snooze", + "alerting:.es-query/infrastructure/rule/bulkEdit", + "alerting:.es-query/infrastructure/rule/bulkDelete", + "alerting:.es-query/infrastructure/rule/bulkEnable", + "alerting:.es-query/infrastructure/rule/bulkDisable", + "alerting:.es-query/infrastructure/rule/unsnooze", + "alerting:.es-query/infrastructure/rule/runSoon", + "alerting:.es-query/infrastructure/rule/scheduleBackfill", + "alerting:.es-query/infrastructure/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/get", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/find", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/findBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/create", + "alerting:observability.rules.custom_threshold/infrastructure/rule/delete", + "alerting:observability.rules.custom_threshold/infrastructure/rule/update", + "alerting:observability.rules.custom_threshold/infrastructure/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/infrastructure/rule/enable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/disable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/muteAll", + "alerting:observability.rules.custom_threshold/infrastructure/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/infrastructure/rule/muteAlert", + "alerting:observability.rules.custom_threshold/infrastructure/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/infrastructure/rule/snooze", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/infrastructure/rule/unsnooze", + "alerting:observability.rules.custom_threshold/infrastructure/rule/runSoon", + "alerting:observability.rules.custom_threshold/infrastructure/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.threshold/infrastructure/alert/get", + "alerting:metrics.alert.threshold/infrastructure/alert/find", + "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.threshold/infrastructure/alert/update", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/update", + "alerting:.es-query/infrastructure/alert/get", + "alerting:.es-query/infrastructure/alert/find", + "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/infrastructure/alert/getAlertSummary", + "alerting:.es-query/infrastructure/alert/update", + "alerting:observability.rules.custom_threshold/infrastructure/alert/get", + "alerting:observability.rules.custom_threshold/infrastructure/alert/find", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/update", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/logs", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "saved_object:infrastructure-monitoring-log-view/create", + "saved_object:infrastructure-monitoring-log-view/bulk_create", + "saved_object:infrastructure-monitoring-log-view/update", + "saved_object:infrastructure-monitoring-log-view/bulk_update", + "saved_object:infrastructure-monitoring-log-view/delete", + "saved_object:infrastructure-monitoring-log-view/bulk_delete", + "saved_object:infrastructure-monitoring-log-view/share_to_space", + "ui:logs/show", + "ui:logs/configureSource", + "ui:logs/save", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/rule/create", + "alerting:logs.alert.document.count/logs/rule/delete", + "alerting:logs.alert.document.count/logs/rule/update", + "alerting:logs.alert.document.count/logs/rule/updateApiKey", + "alerting:logs.alert.document.count/logs/rule/enable", + "alerting:logs.alert.document.count/logs/rule/disable", + "alerting:logs.alert.document.count/logs/rule/muteAll", + "alerting:logs.alert.document.count/logs/rule/unmuteAll", + "alerting:logs.alert.document.count/logs/rule/muteAlert", + "alerting:logs.alert.document.count/logs/rule/unmuteAlert", + "alerting:logs.alert.document.count/logs/rule/snooze", + "alerting:logs.alert.document.count/logs/rule/bulkEdit", + "alerting:logs.alert.document.count/logs/rule/bulkDelete", + "alerting:logs.alert.document.count/logs/rule/bulkEnable", + "alerting:logs.alert.document.count/logs/rule/bulkDisable", + "alerting:logs.alert.document.count/logs/rule/unsnooze", + "alerting:logs.alert.document.count/logs/rule/runSoon", + "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", + "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/create", + "alerting:.es-query/logs/rule/delete", + "alerting:.es-query/logs/rule/update", + "alerting:.es-query/logs/rule/updateApiKey", + "alerting:.es-query/logs/rule/enable", + "alerting:.es-query/logs/rule/disable", + "alerting:.es-query/logs/rule/muteAll", + "alerting:.es-query/logs/rule/unmuteAll", + "alerting:.es-query/logs/rule/muteAlert", + "alerting:.es-query/logs/rule/unmuteAlert", + "alerting:.es-query/logs/rule/snooze", + "alerting:.es-query/logs/rule/bulkEdit", + "alerting:.es-query/logs/rule/bulkDelete", + "alerting:.es-query/logs/rule/bulkEnable", + "alerting:.es-query/logs/rule/bulkDisable", + "alerting:.es-query/logs/rule/unsnooze", + "alerting:.es-query/logs/rule/runSoon", + "alerting:.es-query/logs/rule/scheduleBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_read": Array [ + "login:", + "api:infra", + "api:rac", + "app:infra", + "app:metrics", + "app:kibana", + "ui:catalogue/infraops", + "ui:catalogue/metrics", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/metrics", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:metrics-data-source/bulk_get", + "saved_object:metrics-data-source/get", + "saved_object:metrics-data-source/find", + "saved_object:metrics-data-source/open_point_in_time", + "saved_object:metrics-data-source/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:infrastructure/show", + "alerting:metrics.alert.threshold/infrastructure/rule/get", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/infrastructure/rule/find", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/findBackfill", + "alerting:.es-query/infrastructure/rule/get", + "alerting:.es-query/infrastructure/rule/getRuleState", + "alerting:.es-query/infrastructure/rule/getAlertSummary", + "alerting:.es-query/infrastructure/rule/getExecutionLog", + "alerting:.es-query/infrastructure/rule/getActionErrorLog", + "alerting:.es-query/infrastructure/rule/find", + "alerting:.es-query/infrastructure/rule/getRuleExecutionKPI", + "alerting:.es-query/infrastructure/rule/getBackfill", + "alerting:.es-query/infrastructure/rule/findBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/get", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/find", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/findBackfill", + "alerting:metrics.alert.threshold/infrastructure/alert/get", + "alerting:metrics.alert.threshold/infrastructure/alert/find", + "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", + "alerting:.es-query/infrastructure/alert/get", + "alerting:.es-query/infrastructure/alert/find", + "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/infrastructure/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/alert/get", + "alerting:observability.rules.custom_threshold/infrastructure/alert/find", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/logs", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "ui:logs/show", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + "read": Array [ + "login:", + "api:infra", + "api:rac", + "app:infra", + "app:metrics", + "app:kibana", + "ui:catalogue/infraops", + "ui:catalogue/metrics", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/infra", + "ui:navLinks/metrics", + "ui:navLinks/kibana", + "saved_object:infrastructure-ui-source/bulk_get", + "saved_object:infrastructure-ui-source/get", + "saved_object:infrastructure-ui-source/find", + "saved_object:infrastructure-ui-source/open_point_in_time", + "saved_object:infrastructure-ui-source/close_point_in_time", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:metrics-data-source/bulk_get", + "saved_object:metrics-data-source/get", + "saved_object:metrics-data-source/find", + "saved_object:metrics-data-source/open_point_in_time", + "saved_object:metrics-data-source/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:infrastructure/show", + "alerting:metrics.alert.threshold/infrastructure/rule/get", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/infrastructure/rule/find", + "alerting:metrics.alert.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/infrastructure/rule/findBackfill", + "alerting:.es-query/infrastructure/rule/get", + "alerting:.es-query/infrastructure/rule/getRuleState", + "alerting:.es-query/infrastructure/rule/getAlertSummary", + "alerting:.es-query/infrastructure/rule/getExecutionLog", + "alerting:.es-query/infrastructure/rule/getActionErrorLog", + "alerting:.es-query/infrastructure/rule/find", + "alerting:.es-query/infrastructure/rule/getRuleExecutionKPI", + "alerting:.es-query/infrastructure/rule/getBackfill", + "alerting:.es-query/infrastructure/rule/findBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/get", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/infrastructure/rule/find", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/infrastructure/rule/getBackfill", + "alerting:observability.rules.custom_threshold/infrastructure/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/findBackfill", + "alerting:metrics.alert.threshold/infrastructure/alert/get", + "alerting:metrics.alert.threshold/infrastructure/alert/find", + "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", + "alerting:.es-query/infrastructure/alert/get", + "alerting:.es-query/infrastructure/alert/find", + "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/infrastructure/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/infrastructure/alert/get", + "alerting:observability.rules.custom_threshold/infrastructure/alert/find", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", + "app:logs", + "ui:catalogue/infralogging", + "ui:catalogue/logs", + "ui:navLinks/logs", + "saved_object:infrastructure-monitoring-log-view/bulk_get", + "saved_object:infrastructure-monitoring-log-view/get", + "saved_object:infrastructure-monitoring-log-view/find", + "saved_object:infrastructure-monitoring-log-view/open_point_in_time", + "saved_object:infrastructure-monitoring-log-view/close_point_in_time", + "ui:logs/show", + "alerting:logs.alert.document.count/logs/rule/get", + "alerting:logs.alert.document.count/logs/rule/getRuleState", + "alerting:logs.alert.document.count/logs/rule/getAlertSummary", + "alerting:logs.alert.document.count/logs/rule/getExecutionLog", + "alerting:logs.alert.document.count/logs/rule/getActionErrorLog", + "alerting:logs.alert.document.count/logs/rule/find", + "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/logs/rule/getBackfill", + "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:.es-query/logs/rule/get", + "alerting:.es-query/logs/rule/getRuleState", + "alerting:.es-query/logs/rule/getAlertSummary", + "alerting:.es-query/logs/rule/getExecutionLog", + "alerting:.es-query/logs/rule/getActionErrorLog", + "alerting:.es-query/logs/rule/find", + "alerting:.es-query/logs/rule/getRuleExecutionKPI", + "alerting:.es-query/logs/rule/getBackfill", + "alerting:.es-query/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + }, + "reporting": Object { + "all": Array [ + "login:", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + "api:generateReport", + "ui:discover/generateCsv", + ], + "minimal_all": Array [ + "login:", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + "api:generateReport", + "ui:discover/generateCsv", + ], + "minimal_read": Array [ + "login:", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + ], + "read": Array [ + "login:", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + ], + }, + "slo": Object { + "all": Array [ + "login:", + "api:slo_write", + "api:slo_read", + "api:rac", + "app:slo", + "app:kibana", + "ui:catalogue/slo", + "ui:catalogue/observability", + "ui:navLinks/slo", + "ui:navLinks/kibana", + "saved_object:slo/bulk_get", + "saved_object:slo/get", + "saved_object:slo/find", + "saved_object:slo/open_point_in_time", + "saved_object:slo/close_point_in_time", + "saved_object:slo/create", + "saved_object:slo/bulk_create", + "saved_object:slo/update", + "saved_object:slo/bulk_update", + "saved_object:slo/delete", + "saved_object:slo/bulk_delete", + "saved_object:slo/share_to_space", + "saved_object:slo-settings/bulk_get", + "saved_object:slo-settings/get", + "saved_object:slo-settings/find", + "saved_object:slo-settings/open_point_in_time", + "saved_object:slo-settings/close_point_in_time", + "saved_object:slo-settings/create", + "saved_object:slo-settings/bulk_create", + "saved_object:slo-settings/update", + "saved_object:slo-settings/bulk_update", + "saved_object:slo-settings/delete", + "saved_object:slo-settings/bulk_delete", + "saved_object:slo-settings/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:slo/read", + "ui:slo/write", + "alerting:slo.rules.burnRate/slo/rule/get", + "alerting:slo.rules.burnRate/slo/rule/getRuleState", + "alerting:slo.rules.burnRate/slo/rule/getAlertSummary", + "alerting:slo.rules.burnRate/slo/rule/getExecutionLog", + "alerting:slo.rules.burnRate/slo/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/slo/rule/find", + "alerting:slo.rules.burnRate/slo/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/slo/rule/getBackfill", + "alerting:slo.rules.burnRate/slo/rule/findBackfill", + "alerting:slo.rules.burnRate/slo/rule/create", + "alerting:slo.rules.burnRate/slo/rule/delete", + "alerting:slo.rules.burnRate/slo/rule/update", + "alerting:slo.rules.burnRate/slo/rule/updateApiKey", + "alerting:slo.rules.burnRate/slo/rule/enable", + "alerting:slo.rules.burnRate/slo/rule/disable", + "alerting:slo.rules.burnRate/slo/rule/muteAll", + "alerting:slo.rules.burnRate/slo/rule/unmuteAll", + "alerting:slo.rules.burnRate/slo/rule/muteAlert", + "alerting:slo.rules.burnRate/slo/rule/unmuteAlert", + "alerting:slo.rules.burnRate/slo/rule/snooze", + "alerting:slo.rules.burnRate/slo/rule/bulkEdit", + "alerting:slo.rules.burnRate/slo/rule/bulkDelete", + "alerting:slo.rules.burnRate/slo/rule/bulkEnable", + "alerting:slo.rules.burnRate/slo/rule/bulkDisable", + "alerting:slo.rules.burnRate/slo/rule/unsnooze", + "alerting:slo.rules.burnRate/slo/rule/runSoon", + "alerting:slo.rules.burnRate/slo/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/slo/rule/deleteBackfill", + "alerting:slo.rules.burnRate/slo/alert/get", + "alerting:slo.rules.burnRate/slo/alert/find", + "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", + "alerting:slo.rules.burnRate/slo/alert/update", + "app:observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_all": Array [ + "login:", + "api:slo_write", + "api:slo_read", + "api:rac", + "app:slo", + "app:kibana", + "ui:catalogue/slo", + "ui:catalogue/observability", + "ui:navLinks/slo", + "ui:navLinks/kibana", + "saved_object:slo/bulk_get", + "saved_object:slo/get", + "saved_object:slo/find", + "saved_object:slo/open_point_in_time", + "saved_object:slo/close_point_in_time", + "saved_object:slo/create", + "saved_object:slo/bulk_create", + "saved_object:slo/update", + "saved_object:slo/bulk_update", + "saved_object:slo/delete", + "saved_object:slo/bulk_delete", + "saved_object:slo/share_to_space", + "saved_object:slo-settings/bulk_get", + "saved_object:slo-settings/get", + "saved_object:slo-settings/find", + "saved_object:slo-settings/open_point_in_time", + "saved_object:slo-settings/close_point_in_time", + "saved_object:slo-settings/create", + "saved_object:slo-settings/bulk_create", + "saved_object:slo-settings/update", + "saved_object:slo-settings/bulk_update", + "saved_object:slo-settings/delete", + "saved_object:slo-settings/bulk_delete", + "saved_object:slo-settings/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:slo/read", + "ui:slo/write", + "alerting:slo.rules.burnRate/slo/rule/get", + "alerting:slo.rules.burnRate/slo/rule/getRuleState", + "alerting:slo.rules.burnRate/slo/rule/getAlertSummary", + "alerting:slo.rules.burnRate/slo/rule/getExecutionLog", + "alerting:slo.rules.burnRate/slo/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/slo/rule/find", + "alerting:slo.rules.burnRate/slo/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/slo/rule/getBackfill", + "alerting:slo.rules.burnRate/slo/rule/findBackfill", + "alerting:slo.rules.burnRate/slo/rule/create", + "alerting:slo.rules.burnRate/slo/rule/delete", + "alerting:slo.rules.burnRate/slo/rule/update", + "alerting:slo.rules.burnRate/slo/rule/updateApiKey", + "alerting:slo.rules.burnRate/slo/rule/enable", + "alerting:slo.rules.burnRate/slo/rule/disable", + "alerting:slo.rules.burnRate/slo/rule/muteAll", + "alerting:slo.rules.burnRate/slo/rule/unmuteAll", + "alerting:slo.rules.burnRate/slo/rule/muteAlert", + "alerting:slo.rules.burnRate/slo/rule/unmuteAlert", + "alerting:slo.rules.burnRate/slo/rule/snooze", + "alerting:slo.rules.burnRate/slo/rule/bulkEdit", + "alerting:slo.rules.burnRate/slo/rule/bulkDelete", + "alerting:slo.rules.burnRate/slo/rule/bulkEnable", + "alerting:slo.rules.burnRate/slo/rule/bulkDisable", + "alerting:slo.rules.burnRate/slo/rule/unsnooze", + "alerting:slo.rules.burnRate/slo/rule/runSoon", + "alerting:slo.rules.burnRate/slo/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/slo/rule/deleteBackfill", + "alerting:slo.rules.burnRate/slo/alert/get", + "alerting:slo.rules.burnRate/slo/alert/find", + "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", + "alerting:slo.rules.burnRate/slo/alert/update", + "app:observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_read": Array [ + "login:", + "api:slo_read", + "api:rac", + "app:slo", + "app:kibana", + "ui:catalogue/slo", + "ui:catalogue/observability", + "ui:navLinks/slo", + "ui:navLinks/kibana", + "saved_object:slo/bulk_get", + "saved_object:slo/get", + "saved_object:slo/find", + "saved_object:slo/open_point_in_time", + "saved_object:slo/close_point_in_time", + "saved_object:slo-settings/bulk_get", + "saved_object:slo-settings/get", + "saved_object:slo-settings/find", + "saved_object:slo-settings/open_point_in_time", + "saved_object:slo-settings/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:slo/read", + "alerting:slo.rules.burnRate/slo/rule/get", + "alerting:slo.rules.burnRate/slo/rule/getRuleState", + "alerting:slo.rules.burnRate/slo/rule/getAlertSummary", + "alerting:slo.rules.burnRate/slo/rule/getExecutionLog", + "alerting:slo.rules.burnRate/slo/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/slo/rule/find", + "alerting:slo.rules.burnRate/slo/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/slo/rule/getBackfill", + "alerting:slo.rules.burnRate/slo/rule/findBackfill", + "alerting:slo.rules.burnRate/slo/alert/get", + "alerting:slo.rules.burnRate/slo/alert/find", + "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", + "app:observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + "read": Array [ + "login:", + "api:slo_read", + "api:rac", + "app:slo", + "app:kibana", + "ui:catalogue/slo", + "ui:catalogue/observability", + "ui:navLinks/slo", + "ui:navLinks/kibana", + "saved_object:slo/bulk_get", + "saved_object:slo/get", + "saved_object:slo/find", + "saved_object:slo/open_point_in_time", + "saved_object:slo/close_point_in_time", + "saved_object:slo-settings/bulk_get", + "saved_object:slo-settings/get", + "saved_object:slo-settings/find", + "saved_object:slo-settings/open_point_in_time", + "saved_object:slo-settings/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:slo/read", + "alerting:slo.rules.burnRate/slo/rule/get", + "alerting:slo.rules.burnRate/slo/rule/getRuleState", + "alerting:slo.rules.burnRate/slo/rule/getAlertSummary", + "alerting:slo.rules.burnRate/slo/rule/getExecutionLog", + "alerting:slo.rules.burnRate/slo/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/slo/rule/find", + "alerting:slo.rules.burnRate/slo/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/slo/rule/getBackfill", + "alerting:slo.rules.burnRate/slo/rule/findBackfill", + "alerting:slo.rules.burnRate/slo/alert/get", + "alerting:slo.rules.burnRate/slo/alert/find", + "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", + "app:observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + }, + "uptime": Object { + "all": Array [ + "login:", + "api:uptime-read", + "api:uptime-write", + "api:lists-all", + "api:rac", + "app:uptime", + "app:kibana", + "app:synthetics", + "ui:catalogue/uptime", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/uptime", + "ui:navLinks/kibana", + "ui:navLinks/synthetics", + "saved_object:synthetics-dynamic-settings/bulk_get", + "saved_object:synthetics-dynamic-settings/get", + "saved_object:synthetics-dynamic-settings/find", + "saved_object:synthetics-dynamic-settings/open_point_in_time", + "saved_object:synthetics-dynamic-settings/close_point_in_time", + "saved_object:synthetics-dynamic-settings/create", + "saved_object:synthetics-dynamic-settings/bulk_create", + "saved_object:synthetics-dynamic-settings/update", + "saved_object:synthetics-dynamic-settings/bulk_update", + "saved_object:synthetics-dynamic-settings/delete", + "saved_object:synthetics-dynamic-settings/bulk_delete", + "saved_object:synthetics-dynamic-settings/share_to_space", + "saved_object:synthetics-monitor/bulk_get", + "saved_object:synthetics-monitor/get", + "saved_object:synthetics-monitor/find", + "saved_object:synthetics-monitor/open_point_in_time", + "saved_object:synthetics-monitor/close_point_in_time", + "saved_object:synthetics-monitor/create", + "saved_object:synthetics-monitor/bulk_create", + "saved_object:synthetics-monitor/update", + "saved_object:synthetics-monitor/bulk_update", + "saved_object:synthetics-monitor/delete", + "saved_object:synthetics-monitor/bulk_delete", + "saved_object:synthetics-monitor/share_to_space", + "saved_object:uptime-synthetics-api-key/bulk_get", + "saved_object:uptime-synthetics-api-key/get", + "saved_object:uptime-synthetics-api-key/find", + "saved_object:uptime-synthetics-api-key/open_point_in_time", + "saved_object:uptime-synthetics-api-key/close_point_in_time", + "saved_object:uptime-synthetics-api-key/create", + "saved_object:uptime-synthetics-api-key/bulk_create", + "saved_object:uptime-synthetics-api-key/update", + "saved_object:uptime-synthetics-api-key/bulk_update", + "saved_object:uptime-synthetics-api-key/delete", + "saved_object:uptime-synthetics-api-key/bulk_delete", + "saved_object:uptime-synthetics-api-key/share_to_space", + "saved_object:synthetics-privates-locations/bulk_get", + "saved_object:synthetics-privates-locations/get", + "saved_object:synthetics-privates-locations/find", + "saved_object:synthetics-privates-locations/open_point_in_time", + "saved_object:synthetics-privates-locations/close_point_in_time", + "saved_object:synthetics-privates-locations/create", + "saved_object:synthetics-privates-locations/bulk_create", + "saved_object:synthetics-privates-locations/update", + "saved_object:synthetics-privates-locations/bulk_update", + "saved_object:synthetics-privates-locations/delete", + "saved_object:synthetics-privates-locations/bulk_delete", + "saved_object:synthetics-privates-locations/share_to_space", + "saved_object:synthetics-param/bulk_get", + "saved_object:synthetics-param/get", + "saved_object:synthetics-param/find", + "saved_object:synthetics-param/open_point_in_time", + "saved_object:synthetics-param/close_point_in_time", + "saved_object:synthetics-param/create", + "saved_object:synthetics-param/bulk_create", + "saved_object:synthetics-param/update", + "saved_object:synthetics-param/bulk_update", + "saved_object:synthetics-param/delete", + "saved_object:synthetics-param/bulk_delete", + "saved_object:synthetics-param/share_to_space", + "saved_object:uptime-dynamic-settings/bulk_get", + "saved_object:uptime-dynamic-settings/get", + "saved_object:uptime-dynamic-settings/find", + "saved_object:uptime-dynamic-settings/open_point_in_time", + "saved_object:uptime-dynamic-settings/close_point_in_time", + "saved_object:uptime-dynamic-settings/create", + "saved_object:uptime-dynamic-settings/bulk_create", + "saved_object:uptime-dynamic-settings/update", + "saved_object:uptime-dynamic-settings/bulk_update", + "saved_object:uptime-dynamic-settings/delete", + "saved_object:uptime-dynamic-settings/bulk_delete", + "saved_object:uptime-dynamic-settings/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:uptime/save", + "ui:uptime/configureSettings", + "ui:uptime/show", + "ui:uptime/alerting:save", + "ui:uptime/elasticManagedLocationsEnabled", + "alerting:xpack.uptime.alerts.tls/uptime/rule/get", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/find", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/create", + "alerting:xpack.uptime.alerts.tls/uptime/rule/delete", + "alerting:xpack.uptime.alerts.tls/uptime/rule/update", + "alerting:xpack.uptime.alerts.tls/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/uptime/rule/enable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/disable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/create", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/delete", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/update", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/enable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/disable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/alert/get", + "alerting:xpack.uptime.alerts.tls/uptime/alert/find", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/uptime/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "elastic_managed_locations_enabled": Array [ + "login:", + "ui:uptime/elasticManagedLocationsEnabled", + ], + "minimal_all": Array [ + "login:", + "api:uptime-read", + "api:uptime-write", + "api:lists-all", + "api:rac", + "app:uptime", + "app:kibana", + "app:synthetics", + "ui:catalogue/uptime", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/uptime", + "ui:navLinks/kibana", + "ui:navLinks/synthetics", + "saved_object:synthetics-dynamic-settings/bulk_get", + "saved_object:synthetics-dynamic-settings/get", + "saved_object:synthetics-dynamic-settings/find", + "saved_object:synthetics-dynamic-settings/open_point_in_time", + "saved_object:synthetics-dynamic-settings/close_point_in_time", + "saved_object:synthetics-dynamic-settings/create", + "saved_object:synthetics-dynamic-settings/bulk_create", + "saved_object:synthetics-dynamic-settings/update", + "saved_object:synthetics-dynamic-settings/bulk_update", + "saved_object:synthetics-dynamic-settings/delete", + "saved_object:synthetics-dynamic-settings/bulk_delete", + "saved_object:synthetics-dynamic-settings/share_to_space", + "saved_object:synthetics-monitor/bulk_get", + "saved_object:synthetics-monitor/get", + "saved_object:synthetics-monitor/find", + "saved_object:synthetics-monitor/open_point_in_time", + "saved_object:synthetics-monitor/close_point_in_time", + "saved_object:synthetics-monitor/create", + "saved_object:synthetics-monitor/bulk_create", + "saved_object:synthetics-monitor/update", + "saved_object:synthetics-monitor/bulk_update", + "saved_object:synthetics-monitor/delete", + "saved_object:synthetics-monitor/bulk_delete", + "saved_object:synthetics-monitor/share_to_space", + "saved_object:uptime-synthetics-api-key/bulk_get", + "saved_object:uptime-synthetics-api-key/get", + "saved_object:uptime-synthetics-api-key/find", + "saved_object:uptime-synthetics-api-key/open_point_in_time", + "saved_object:uptime-synthetics-api-key/close_point_in_time", + "saved_object:uptime-synthetics-api-key/create", + "saved_object:uptime-synthetics-api-key/bulk_create", + "saved_object:uptime-synthetics-api-key/update", + "saved_object:uptime-synthetics-api-key/bulk_update", + "saved_object:uptime-synthetics-api-key/delete", + "saved_object:uptime-synthetics-api-key/bulk_delete", + "saved_object:uptime-synthetics-api-key/share_to_space", + "saved_object:synthetics-privates-locations/bulk_get", + "saved_object:synthetics-privates-locations/get", + "saved_object:synthetics-privates-locations/find", + "saved_object:synthetics-privates-locations/open_point_in_time", + "saved_object:synthetics-privates-locations/close_point_in_time", + "saved_object:synthetics-privates-locations/create", + "saved_object:synthetics-privates-locations/bulk_create", + "saved_object:synthetics-privates-locations/update", + "saved_object:synthetics-privates-locations/bulk_update", + "saved_object:synthetics-privates-locations/delete", + "saved_object:synthetics-privates-locations/bulk_delete", + "saved_object:synthetics-privates-locations/share_to_space", + "saved_object:synthetics-param/bulk_get", + "saved_object:synthetics-param/get", + "saved_object:synthetics-param/find", + "saved_object:synthetics-param/open_point_in_time", + "saved_object:synthetics-param/close_point_in_time", + "saved_object:synthetics-param/create", + "saved_object:synthetics-param/bulk_create", + "saved_object:synthetics-param/update", + "saved_object:synthetics-param/bulk_update", + "saved_object:synthetics-param/delete", + "saved_object:synthetics-param/bulk_delete", + "saved_object:synthetics-param/share_to_space", + "saved_object:uptime-dynamic-settings/bulk_get", + "saved_object:uptime-dynamic-settings/get", + "saved_object:uptime-dynamic-settings/find", + "saved_object:uptime-dynamic-settings/open_point_in_time", + "saved_object:uptime-dynamic-settings/close_point_in_time", + "saved_object:uptime-dynamic-settings/create", + "saved_object:uptime-dynamic-settings/bulk_create", + "saved_object:uptime-dynamic-settings/update", + "saved_object:uptime-dynamic-settings/bulk_update", + "saved_object:uptime-dynamic-settings/delete", + "saved_object:uptime-dynamic-settings/bulk_delete", + "saved_object:uptime-dynamic-settings/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:uptime/save", + "ui:uptime/configureSettings", + "ui:uptime/show", + "ui:uptime/alerting:save", + "alerting:xpack.uptime.alerts.tls/uptime/rule/get", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/find", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/create", + "alerting:xpack.uptime.alerts.tls/uptime/rule/delete", + "alerting:xpack.uptime.alerts.tls/uptime/rule/update", + "alerting:xpack.uptime.alerts.tls/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/uptime/rule/enable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/disable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/create", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/delete", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/update", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/enable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/disable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/alert/get", + "alerting:xpack.uptime.alerts.tls/uptime/alert/find", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/uptime/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/create", + "alerting:apm.error_rate/observability/rule/delete", + "alerting:apm.error_rate/observability/rule/update", + "alerting:apm.error_rate/observability/rule/updateApiKey", + "alerting:apm.error_rate/observability/rule/enable", + "alerting:apm.error_rate/observability/rule/disable", + "alerting:apm.error_rate/observability/rule/muteAll", + "alerting:apm.error_rate/observability/rule/unmuteAll", + "alerting:apm.error_rate/observability/rule/muteAlert", + "alerting:apm.error_rate/observability/rule/unmuteAlert", + "alerting:apm.error_rate/observability/rule/snooze", + "alerting:apm.error_rate/observability/rule/bulkEdit", + "alerting:apm.error_rate/observability/rule/bulkDelete", + "alerting:apm.error_rate/observability/rule/bulkEnable", + "alerting:apm.error_rate/observability/rule/bulkDisable", + "alerting:apm.error_rate/observability/rule/unsnooze", + "alerting:apm.error_rate/observability/rule/runSoon", + "alerting:apm.error_rate/observability/rule/scheduleBackfill", + "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/create", + "alerting:apm.transaction_error_rate/observability/rule/delete", + "alerting:apm.transaction_error_rate/observability/rule/update", + "alerting:apm.transaction_error_rate/observability/rule/updateApiKey", + "alerting:apm.transaction_error_rate/observability/rule/enable", + "alerting:apm.transaction_error_rate/observability/rule/disable", + "alerting:apm.transaction_error_rate/observability/rule/muteAll", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAll", + "alerting:apm.transaction_error_rate/observability/rule/muteAlert", + "alerting:apm.transaction_error_rate/observability/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/observability/rule/snooze", + "alerting:apm.transaction_error_rate/observability/rule/bulkEdit", + "alerting:apm.transaction_error_rate/observability/rule/bulkDelete", + "alerting:apm.transaction_error_rate/observability/rule/bulkEnable", + "alerting:apm.transaction_error_rate/observability/rule/bulkDisable", + "alerting:apm.transaction_error_rate/observability/rule/unsnooze", + "alerting:apm.transaction_error_rate/observability/rule/runSoon", + "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/create", + "alerting:apm.transaction_duration/observability/rule/delete", + "alerting:apm.transaction_duration/observability/rule/update", + "alerting:apm.transaction_duration/observability/rule/updateApiKey", + "alerting:apm.transaction_duration/observability/rule/enable", + "alerting:apm.transaction_duration/observability/rule/disable", + "alerting:apm.transaction_duration/observability/rule/muteAll", + "alerting:apm.transaction_duration/observability/rule/unmuteAll", + "alerting:apm.transaction_duration/observability/rule/muteAlert", + "alerting:apm.transaction_duration/observability/rule/unmuteAlert", + "alerting:apm.transaction_duration/observability/rule/snooze", + "alerting:apm.transaction_duration/observability/rule/bulkEdit", + "alerting:apm.transaction_duration/observability/rule/bulkDelete", + "alerting:apm.transaction_duration/observability/rule/bulkEnable", + "alerting:apm.transaction_duration/observability/rule/bulkDisable", + "alerting:apm.transaction_duration/observability/rule/unsnooze", + "alerting:apm.transaction_duration/observability/rule/runSoon", + "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", + "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/create", + "alerting:apm.anomaly/observability/rule/delete", + "alerting:apm.anomaly/observability/rule/update", + "alerting:apm.anomaly/observability/rule/updateApiKey", + "alerting:apm.anomaly/observability/rule/enable", + "alerting:apm.anomaly/observability/rule/disable", + "alerting:apm.anomaly/observability/rule/muteAll", + "alerting:apm.anomaly/observability/rule/unmuteAll", + "alerting:apm.anomaly/observability/rule/muteAlert", + "alerting:apm.anomaly/observability/rule/unmuteAlert", + "alerting:apm.anomaly/observability/rule/snooze", + "alerting:apm.anomaly/observability/rule/bulkEdit", + "alerting:apm.anomaly/observability/rule/bulkDelete", + "alerting:apm.anomaly/observability/rule/bulkEnable", + "alerting:apm.anomaly/observability/rule/bulkDisable", + "alerting:apm.anomaly/observability/rule/unsnooze", + "alerting:apm.anomaly/observability/rule/runSoon", + "alerting:apm.anomaly/observability/rule/scheduleBackfill", + "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + ], + "minimal_read": Array [ + "login:", + "api:uptime-read", + "api:lists-read", + "api:rac", + "app:uptime", + "app:kibana", + "app:synthetics", + "ui:catalogue/uptime", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/uptime", + "ui:navLinks/kibana", + "ui:navLinks/synthetics", + "saved_object:synthetics-param/bulk_get", + "saved_object:synthetics-param/get", + "saved_object:synthetics-param/find", + "saved_object:synthetics-param/open_point_in_time", + "saved_object:synthetics-param/close_point_in_time", + "saved_object:synthetics-dynamic-settings/bulk_get", + "saved_object:synthetics-dynamic-settings/get", + "saved_object:synthetics-dynamic-settings/find", + "saved_object:synthetics-dynamic-settings/open_point_in_time", + "saved_object:synthetics-dynamic-settings/close_point_in_time", + "saved_object:synthetics-monitor/bulk_get", + "saved_object:synthetics-monitor/get", + "saved_object:synthetics-monitor/find", + "saved_object:synthetics-monitor/open_point_in_time", + "saved_object:synthetics-monitor/close_point_in_time", + "saved_object:uptime-synthetics-api-key/bulk_get", + "saved_object:uptime-synthetics-api-key/get", + "saved_object:uptime-synthetics-api-key/find", + "saved_object:uptime-synthetics-api-key/open_point_in_time", + "saved_object:uptime-synthetics-api-key/close_point_in_time", + "saved_object:synthetics-privates-locations/bulk_get", + "saved_object:synthetics-privates-locations/get", + "saved_object:synthetics-privates-locations/find", + "saved_object:synthetics-privates-locations/open_point_in_time", + "saved_object:synthetics-privates-locations/close_point_in_time", + "saved_object:uptime-dynamic-settings/bulk_get", + "saved_object:uptime-dynamic-settings/get", + "saved_object:uptime-dynamic-settings/find", + "saved_object:uptime-dynamic-settings/open_point_in_time", + "saved_object:uptime-dynamic-settings/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:uptime/show", + "ui:uptime/alerting:save", + "alerting:xpack.uptime.alerts.tls/uptime/rule/get", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/find", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/alert/get", + "alerting:xpack.uptime.alerts.tls/uptime/alert/find", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + "read": Array [ + "login:", + "api:uptime-read", + "api:lists-read", + "api:rac", + "app:uptime", + "app:kibana", + "app:synthetics", + "ui:catalogue/uptime", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/uptime", + "ui:navLinks/kibana", + "ui:navLinks/synthetics", + "saved_object:synthetics-param/bulk_get", + "saved_object:synthetics-param/get", + "saved_object:synthetics-param/find", + "saved_object:synthetics-param/open_point_in_time", + "saved_object:synthetics-param/close_point_in_time", + "saved_object:synthetics-dynamic-settings/bulk_get", + "saved_object:synthetics-dynamic-settings/get", + "saved_object:synthetics-dynamic-settings/find", + "saved_object:synthetics-dynamic-settings/open_point_in_time", + "saved_object:synthetics-dynamic-settings/close_point_in_time", + "saved_object:synthetics-monitor/bulk_get", + "saved_object:synthetics-monitor/get", + "saved_object:synthetics-monitor/find", + "saved_object:synthetics-monitor/open_point_in_time", + "saved_object:synthetics-monitor/close_point_in_time", + "saved_object:uptime-synthetics-api-key/bulk_get", + "saved_object:uptime-synthetics-api-key/get", + "saved_object:uptime-synthetics-api-key/find", + "saved_object:uptime-synthetics-api-key/open_point_in_time", + "saved_object:uptime-synthetics-api-key/close_point_in_time", + "saved_object:synthetics-privates-locations/bulk_get", + "saved_object:synthetics-privates-locations/get", + "saved_object:synthetics-privates-locations/find", + "saved_object:synthetics-privates-locations/open_point_in_time", + "saved_object:synthetics-privates-locations/close_point_in_time", + "saved_object:uptime-dynamic-settings/bulk_get", + "saved_object:uptime-dynamic-settings/get", + "saved_object:uptime-dynamic-settings/find", + "saved_object:uptime-dynamic-settings/open_point_in_time", + "saved_object:uptime-dynamic-settings/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:uptime/show", + "ui:uptime/alerting:save", + "alerting:xpack.uptime.alerts.tls/uptime/rule/get", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/uptime/rule/find", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/alert/get", + "alerting:xpack.uptime.alerts.tls/uptime/alert/find", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:apm.error_rate/observability/rule/get", + "alerting:apm.error_rate/observability/rule/getRuleState", + "alerting:apm.error_rate/observability/rule/getAlertSummary", + "alerting:apm.error_rate/observability/rule/getExecutionLog", + "alerting:apm.error_rate/observability/rule/getActionErrorLog", + "alerting:apm.error_rate/observability/rule/find", + "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/observability/rule/getBackfill", + "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/observability/rule/get", + "alerting:apm.transaction_error_rate/observability/rule/getRuleState", + "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/observability/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/observability/rule/find", + "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/observability/rule/getBackfill", + "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_duration/observability/rule/get", + "alerting:apm.transaction_duration/observability/rule/getRuleState", + "alerting:apm.transaction_duration/observability/rule/getAlertSummary", + "alerting:apm.transaction_duration/observability/rule/getExecutionLog", + "alerting:apm.transaction_duration/observability/rule/getActionErrorLog", + "alerting:apm.transaction_duration/observability/rule/find", + "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/observability/rule/getBackfill", + "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.anomaly/observability/rule/get", + "alerting:apm.anomaly/observability/rule/getRuleState", + "alerting:apm.anomaly/observability/rule/getAlertSummary", + "alerting:apm.anomaly/observability/rule/getExecutionLog", + "alerting:apm.anomaly/observability/rule/getActionErrorLog", + "alerting:apm.anomaly/observability/rule/find", + "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/observability/rule/getBackfill", + "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + ], + }, + } + `); + }); + }); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/index.ts b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/index.ts new file mode 100644 index 0000000000000..5271f15b683f1 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Platform security APIs', function () { + loadTestFile(require.resolve('./authorization')); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts index 90009b3b57ded..a757df76f10f3 100644 --- a/x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts +++ b/x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('Serverless search API - feature flags', function () { + loadTestFile(require.resolve('./platform_security')); loadTestFile(require.resolve('../common/platform_security/roles_routes_feature_flag.ts')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/search/platform_security/authorization.ts b/x-pack/test_serverless/api_integration/test_suites/search/platform_security/authorization.ts new file mode 100644 index 0000000000000..b05dd338c64ac --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/search/platform_security/authorization.ts @@ -0,0 +1,1029 @@ +/* + * 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 ({ getService }: FtrProviderContext) { + const svlCommonApi = getService('svlCommonApi'); + + describe('security/authorization', function () { + describe('available features', () => { + const svlUserManager = getService('svlUserManager'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + let adminCredentials: { Cookie: string }; + + before(async () => { + // get auth header for Viewer role + adminCredentials = await svlUserManager.getApiCredentialsForRole('admin'); + }); + + it('composite features', async () => { + const { body } = await supertestWithoutAuth + .get('/api/security/privileges?includeActions=true') + .set(svlCommonApi.getInternalRequestHeader()) + .set(adminCredentials) + .expect(200); + + // The following features are composed of other features in a way that is + // specific to the search solution. + const compositeFeatureIds = ['dashboard', 'discover', 'reporting']; + + const features = Object.fromEntries( + Object.entries(body.features).filter(([key]) => compositeFeatureIds.includes(key)) + ); + expectSnapshot(features).toMatchInline(` + Object { + "dashboard": Object { + "all": Array [ + "login:", + "api:bulkGetUserProfiles", + "api:store_search_session", + "api:generateReport", + "api:downloadCsv", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "ui:dashboard/createNew", + "ui:dashboard/show", + "ui:dashboard/showWriteControls", + "ui:dashboard/saveQuery", + "ui:dashboard/createShortUrl", + "ui:dashboard/storeSearchSession", + "ui:dashboard/generateScreenshot", + "ui:dashboard/downloadCsv", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps/save", + "ui:maps/show", + "ui:maps/saveQuery", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "ui:visualize/show", + "ui:visualize/delete", + "ui:visualize/save", + "ui:visualize/saveQuery", + "ui:visualize/createShortUrl", + "ui:visualize/generateScreenshot", + ], + "download_csv_report": Array [ + "login:", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + ], + "generate_report": Array [ + "login:", + "api:generateReport", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/generateScreenshot", + ], + "minimal_all": Array [ + "login:", + "api:bulkGetUserProfiles", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:dashboard/createNew", + "ui:dashboard/show", + "ui:dashboard/showWriteControls", + "ui:dashboard/saveQuery", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps/save", + "ui:maps/show", + "ui:maps/saveQuery", + "api:generateReport", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:visualize/show", + "ui:visualize/delete", + "ui:visualize/save", + "ui:visualize/saveQuery", + "ui:visualize/createShortUrl", + "ui:visualize/generateScreenshot", + ], + "minimal_read": Array [ + "login:", + "api:bulkGetUserProfiles", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:dashboard/show", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:visualize/show", + "ui:visualize/createShortUrl", + ], + "read": Array [ + "login:", + "api:bulkGetUserProfiles", + "app:dashboards", + "app:kibana", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "ui:navLinks/kibana", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "ui:dashboard/show", + "ui:dashboard/createShortUrl", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "ui:visualize/show", + "ui:visualize/createShortUrl", + ], + "store_search_session": Array [ + "login:", + "api:store_search_session", + "ui:management/kibana/search_sessions", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "ui:dashboard/storeSearchSession", + ], + "url_create": Array [ + "login:", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:dashboard/createShortUrl", + ], + }, + "discover": Object { + "all": Array [ + "login:", + "api:fileUpload:analyzeFile", + "api:store_search_session", + "api:generateReport", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + "ui:discover/createShortUrl", + "ui:discover/storeSearchSession", + "ui:discover/generateCsv", + ], + "generate_report": Array [ + "login:", + "api:generateReport", + "ui:management/insightsAndAlerting/reporting", + "ui:discover/generateCsv", + ], + "minimal_all": Array [ + "login:", + "api:fileUpload:analyzeFile", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + ], + "minimal_read": Array [ + "login:", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:discover/show", + ], + "read": Array [ + "login:", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "ui:discover/show", + "ui:discover/createShortUrl", + ], + "store_search_session": Array [ + "login:", + "api:store_search_session", + "ui:management/kibana/search_sessions", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "ui:discover/storeSearchSession", + ], + "url_create": Array [ + "login:", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "ui:discover/createShortUrl", + ], + }, + "reporting": Object { + "all": Array [ + "login:", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + "api:generateReport", + "ui:discover/generateCsv", + ], + "minimal_all": Array [ + "login:", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + "api:generateReport", + "ui:discover/generateCsv", + ], + "minimal_read": Array [ + "login:", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + ], + "read": Array [ + "login:", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + ], + }, + } + `); + }); + }); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/search/platform_security/index.ts b/x-pack/test_serverless/api_integration/test_suites/search/platform_security/index.ts new file mode 100644 index 0000000000000..5271f15b683f1 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/search/platform_security/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Platform security APIs', function () { + loadTestFile(require.resolve('./authorization')); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts index e3f61f3dde03c..f929d3e64c6bc 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('Serverless security API - feature flags', function () { + loadTestFile(require.resolve('./platform_security')); loadTestFile(require.resolve('../common/platform_security/roles_routes_feature_flag.ts')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts b/x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts new file mode 100644 index 0000000000000..54e9f5c1cbdf5 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts @@ -0,0 +1,2412 @@ +/* + * 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 ({ getService }: FtrProviderContext) { + const svlCommonApi = getService('svlCommonApi'); + + describe('security/authorization', function () { + describe('available features', () => { + const svlUserManager = getService('svlUserManager'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + let adminCredentials: { Cookie: string }; + + before(async () => { + // get auth header for Viewer role + adminCredentials = await svlUserManager.getApiCredentialsForRole('admin'); + }); + + it('composite features', async () => { + const { body } = await supertestWithoutAuth + .get('/api/security/privileges?includeActions=true') + .set(svlCommonApi.getInternalRequestHeader()) + .set(adminCredentials) + .expect(200); + + // The following features are composed of other features in a way that is + // specific to the security solution. + const compositeFeatureIds = ['dashboard', 'discover', 'reporting', 'siem']; + + const features = Object.fromEntries( + Object.entries(body.features).filter(([key]) => compositeFeatureIds.includes(key)) + ); + expectSnapshot(features).toMatchInline(` + Object { + "reporting": Object { + "all": Array [ + "login:", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + "api:generateReport", + "ui:discover/generateCsv", + ], + "minimal_all": Array [ + "login:", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "api:downloadCsv", + "ui:management/insightsAndAlerting/reporting", + "ui:dashboard/downloadCsv", + "api:generateReport", + "ui:discover/generateCsv", + ], + "minimal_read": Array [ + "login:", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + ], + "read": Array [ + "login:", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + ], + }, + "siem": Object { + "actions_log_management_all": Array [ + "login:", + "api:securitySolution-writeActionsLogManagement", + "api:securitySolution-readActionsLogManagement", + "ui:siem/writeActionsLogManagement", + "ui:siem/readActionsLogManagement", + ], + "actions_log_management_read": Array [ + "login:", + "api:securitySolution-readActionsLogManagement", + "ui:siem/readActionsLogManagement", + ], + "all": Array [ + "login:", + "api:securitySolution", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:rac", + "api:cloud-security-posture-all", + "api:cloud-security-posture-read", + "api:cloud-defend-all", + "api:cloud-defend-read", + "api:securitySolution-entity-analytics", + "api:securitySolution-threat-intelligence", + "api:securitySolution-showEndpointExceptions", + "api:securitySolution-crudEndpointExceptions", + "app:securitySolution", + "app:csp", + "app:cloudDefend", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/cloudDefend", + "ui:navLinks/kibana", + "saved_object:alert/bulk_get", + "saved_object:alert/get", + "saved_object:alert/find", + "saved_object:alert/open_point_in_time", + "saved_object:alert/close_point_in_time", + "saved_object:alert/create", + "saved_object:alert/bulk_create", + "saved_object:alert/update", + "saved_object:alert/bulk_update", + "saved_object:alert/delete", + "saved_object:alert/bulk_delete", + "saved_object:alert/share_to_space", + "saved_object:exception-list/bulk_get", + "saved_object:exception-list/get", + "saved_object:exception-list/find", + "saved_object:exception-list/open_point_in_time", + "saved_object:exception-list/close_point_in_time", + "saved_object:exception-list/create", + "saved_object:exception-list/bulk_create", + "saved_object:exception-list/update", + "saved_object:exception-list/bulk_update", + "saved_object:exception-list/delete", + "saved_object:exception-list/bulk_delete", + "saved_object:exception-list/share_to_space", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:index-pattern/create", + "saved_object:index-pattern/bulk_create", + "saved_object:index-pattern/update", + "saved_object:index-pattern/bulk_update", + "saved_object:index-pattern/delete", + "saved_object:index-pattern/bulk_delete", + "saved_object:index-pattern/share_to_space", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-note/create", + "saved_object:siem-ui-timeline-note/bulk_create", + "saved_object:siem-ui-timeline-note/update", + "saved_object:siem-ui-timeline-note/bulk_update", + "saved_object:siem-ui-timeline-note/delete", + "saved_object:siem-ui-timeline-note/bulk_delete", + "saved_object:siem-ui-timeline-note/share_to_space", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/create", + "saved_object:siem-ui-timeline-pinned-event/bulk_create", + "saved_object:siem-ui-timeline-pinned-event/update", + "saved_object:siem-ui-timeline-pinned-event/bulk_update", + "saved_object:siem-ui-timeline-pinned-event/delete", + "saved_object:siem-ui-timeline-pinned-event/bulk_delete", + "saved_object:siem-ui-timeline-pinned-event/share_to_space", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/create", + "saved_object:siem-detection-engine-rule-actions/bulk_create", + "saved_object:siem-detection-engine-rule-actions/update", + "saved_object:siem-detection-engine-rule-actions/bulk_update", + "saved_object:siem-detection-engine-rule-actions/delete", + "saved_object:siem-detection-engine-rule-actions/bulk_delete", + "saved_object:siem-detection-engine-rule-actions/share_to_space", + "saved_object:security-rule/bulk_get", + "saved_object:security-rule/get", + "saved_object:security-rule/find", + "saved_object:security-rule/open_point_in_time", + "saved_object:security-rule/close_point_in_time", + "saved_object:security-rule/create", + "saved_object:security-rule/bulk_create", + "saved_object:security-rule/update", + "saved_object:security-rule/bulk_update", + "saved_object:security-rule/delete", + "saved_object:security-rule/bulk_delete", + "saved_object:security-rule/share_to_space", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", + "saved_object:siem-ui-timeline/create", + "saved_object:siem-ui-timeline/bulk_create", + "saved_object:siem-ui-timeline/update", + "saved_object:siem-ui-timeline/bulk_update", + "saved_object:siem-ui-timeline/delete", + "saved_object:siem-ui-timeline/bulk_delete", + "saved_object:siem-ui-timeline/share_to_space", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/create", + "saved_object:endpoint:user-artifact-manifest/bulk_create", + "saved_object:endpoint:user-artifact-manifest/update", + "saved_object:endpoint:user-artifact-manifest/bulk_update", + "saved_object:endpoint:user-artifact-manifest/delete", + "saved_object:endpoint:user-artifact-manifest/bulk_delete", + "saved_object:endpoint:user-artifact-manifest/share_to_space", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/create", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_create", + "saved_object:endpoint:unified-user-artifact-manifest/update", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_update", + "saved_object:endpoint:unified-user-artifact-manifest/delete", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_delete", + "saved_object:endpoint:unified-user-artifact-manifest/share_to_space", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:security-solution-signals-migration/create", + "saved_object:security-solution-signals-migration/bulk_create", + "saved_object:security-solution-signals-migration/update", + "saved_object:security-solution-signals-migration/bulk_update", + "saved_object:security-solution-signals-migration/delete", + "saved_object:security-solution-signals-migration/bulk_delete", + "saved_object:security-solution-signals-migration/share_to_space", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:risk-engine-configuration/create", + "saved_object:risk-engine-configuration/bulk_create", + "saved_object:risk-engine-configuration/update", + "saved_object:risk-engine-configuration/bulk_update", + "saved_object:risk-engine-configuration/delete", + "saved_object:risk-engine-configuration/bulk_delete", + "saved_object:risk-engine-configuration/share_to_space", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/create", + "saved_object:policy-settings-protection-updates-note/bulk_create", + "saved_object:policy-settings-protection-updates-note/update", + "saved_object:policy-settings-protection-updates-note/bulk_update", + "saved_object:policy-settings-protection-updates-note/delete", + "saved_object:policy-settings-protection-updates-note/bulk_delete", + "saved_object:policy-settings-protection-updates-note/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:siem/show", + "ui:siem/crud", + "ui:siem/entity-analytics", + "ui:siem/investigation-guide", + "ui:siem/investigation-guide-interactions", + "ui:siem/threat-intelligence", + "ui:siem/showEndpointExceptions", + "ui:siem/crudEndpointExceptions", + "alerting:siem.notifications/siem/rule/get", + "alerting:siem.notifications/siem/rule/getRuleState", + "alerting:siem.notifications/siem/rule/getAlertSummary", + "alerting:siem.notifications/siem/rule/getExecutionLog", + "alerting:siem.notifications/siem/rule/getActionErrorLog", + "alerting:siem.notifications/siem/rule/find", + "alerting:siem.notifications/siem/rule/getRuleExecutionKPI", + "alerting:siem.notifications/siem/rule/getBackfill", + "alerting:siem.notifications/siem/rule/findBackfill", + "alerting:siem.notifications/siem/rule/create", + "alerting:siem.notifications/siem/rule/delete", + "alerting:siem.notifications/siem/rule/update", + "alerting:siem.notifications/siem/rule/updateApiKey", + "alerting:siem.notifications/siem/rule/enable", + "alerting:siem.notifications/siem/rule/disable", + "alerting:siem.notifications/siem/rule/muteAll", + "alerting:siem.notifications/siem/rule/unmuteAll", + "alerting:siem.notifications/siem/rule/muteAlert", + "alerting:siem.notifications/siem/rule/unmuteAlert", + "alerting:siem.notifications/siem/rule/snooze", + "alerting:siem.notifications/siem/rule/bulkEdit", + "alerting:siem.notifications/siem/rule/bulkDelete", + "alerting:siem.notifications/siem/rule/bulkEnable", + "alerting:siem.notifications/siem/rule/bulkDisable", + "alerting:siem.notifications/siem/rule/unsnooze", + "alerting:siem.notifications/siem/rule/runSoon", + "alerting:siem.notifications/siem/rule/scheduleBackfill", + "alerting:siem.notifications/siem/rule/deleteBackfill", + "alerting:siem.esqlRule/siem/rule/get", + "alerting:siem.esqlRule/siem/rule/getRuleState", + "alerting:siem.esqlRule/siem/rule/getAlertSummary", + "alerting:siem.esqlRule/siem/rule/getExecutionLog", + "alerting:siem.esqlRule/siem/rule/getActionErrorLog", + "alerting:siem.esqlRule/siem/rule/find", + "alerting:siem.esqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.esqlRule/siem/rule/getBackfill", + "alerting:siem.esqlRule/siem/rule/findBackfill", + "alerting:siem.esqlRule/siem/rule/create", + "alerting:siem.esqlRule/siem/rule/delete", + "alerting:siem.esqlRule/siem/rule/update", + "alerting:siem.esqlRule/siem/rule/updateApiKey", + "alerting:siem.esqlRule/siem/rule/enable", + "alerting:siem.esqlRule/siem/rule/disable", + "alerting:siem.esqlRule/siem/rule/muteAll", + "alerting:siem.esqlRule/siem/rule/unmuteAll", + "alerting:siem.esqlRule/siem/rule/muteAlert", + "alerting:siem.esqlRule/siem/rule/unmuteAlert", + "alerting:siem.esqlRule/siem/rule/snooze", + "alerting:siem.esqlRule/siem/rule/bulkEdit", + "alerting:siem.esqlRule/siem/rule/bulkDelete", + "alerting:siem.esqlRule/siem/rule/bulkEnable", + "alerting:siem.esqlRule/siem/rule/bulkDisable", + "alerting:siem.esqlRule/siem/rule/unsnooze", + "alerting:siem.esqlRule/siem/rule/runSoon", + "alerting:siem.esqlRule/siem/rule/scheduleBackfill", + "alerting:siem.esqlRule/siem/rule/deleteBackfill", + "alerting:siem.eqlRule/siem/rule/get", + "alerting:siem.eqlRule/siem/rule/getRuleState", + "alerting:siem.eqlRule/siem/rule/getAlertSummary", + "alerting:siem.eqlRule/siem/rule/getExecutionLog", + "alerting:siem.eqlRule/siem/rule/getActionErrorLog", + "alerting:siem.eqlRule/siem/rule/find", + "alerting:siem.eqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.eqlRule/siem/rule/getBackfill", + "alerting:siem.eqlRule/siem/rule/findBackfill", + "alerting:siem.eqlRule/siem/rule/create", + "alerting:siem.eqlRule/siem/rule/delete", + "alerting:siem.eqlRule/siem/rule/update", + "alerting:siem.eqlRule/siem/rule/updateApiKey", + "alerting:siem.eqlRule/siem/rule/enable", + "alerting:siem.eqlRule/siem/rule/disable", + "alerting:siem.eqlRule/siem/rule/muteAll", + "alerting:siem.eqlRule/siem/rule/unmuteAll", + "alerting:siem.eqlRule/siem/rule/muteAlert", + "alerting:siem.eqlRule/siem/rule/unmuteAlert", + "alerting:siem.eqlRule/siem/rule/snooze", + "alerting:siem.eqlRule/siem/rule/bulkEdit", + "alerting:siem.eqlRule/siem/rule/bulkDelete", + "alerting:siem.eqlRule/siem/rule/bulkEnable", + "alerting:siem.eqlRule/siem/rule/bulkDisable", + "alerting:siem.eqlRule/siem/rule/unsnooze", + "alerting:siem.eqlRule/siem/rule/runSoon", + "alerting:siem.eqlRule/siem/rule/scheduleBackfill", + "alerting:siem.eqlRule/siem/rule/deleteBackfill", + "alerting:siem.indicatorRule/siem/rule/get", + "alerting:siem.indicatorRule/siem/rule/getRuleState", + "alerting:siem.indicatorRule/siem/rule/getAlertSummary", + "alerting:siem.indicatorRule/siem/rule/getExecutionLog", + "alerting:siem.indicatorRule/siem/rule/getActionErrorLog", + "alerting:siem.indicatorRule/siem/rule/find", + "alerting:siem.indicatorRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.indicatorRule/siem/rule/getBackfill", + "alerting:siem.indicatorRule/siem/rule/findBackfill", + "alerting:siem.indicatorRule/siem/rule/create", + "alerting:siem.indicatorRule/siem/rule/delete", + "alerting:siem.indicatorRule/siem/rule/update", + "alerting:siem.indicatorRule/siem/rule/updateApiKey", + "alerting:siem.indicatorRule/siem/rule/enable", + "alerting:siem.indicatorRule/siem/rule/disable", + "alerting:siem.indicatorRule/siem/rule/muteAll", + "alerting:siem.indicatorRule/siem/rule/unmuteAll", + "alerting:siem.indicatorRule/siem/rule/muteAlert", + "alerting:siem.indicatorRule/siem/rule/unmuteAlert", + "alerting:siem.indicatorRule/siem/rule/snooze", + "alerting:siem.indicatorRule/siem/rule/bulkEdit", + "alerting:siem.indicatorRule/siem/rule/bulkDelete", + "alerting:siem.indicatorRule/siem/rule/bulkEnable", + "alerting:siem.indicatorRule/siem/rule/bulkDisable", + "alerting:siem.indicatorRule/siem/rule/unsnooze", + "alerting:siem.indicatorRule/siem/rule/runSoon", + "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", + "alerting:siem.indicatorRule/siem/rule/deleteBackfill", + "alerting:siem.mlRule/siem/rule/get", + "alerting:siem.mlRule/siem/rule/getRuleState", + "alerting:siem.mlRule/siem/rule/getAlertSummary", + "alerting:siem.mlRule/siem/rule/getExecutionLog", + "alerting:siem.mlRule/siem/rule/getActionErrorLog", + "alerting:siem.mlRule/siem/rule/find", + "alerting:siem.mlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.mlRule/siem/rule/getBackfill", + "alerting:siem.mlRule/siem/rule/findBackfill", + "alerting:siem.mlRule/siem/rule/create", + "alerting:siem.mlRule/siem/rule/delete", + "alerting:siem.mlRule/siem/rule/update", + "alerting:siem.mlRule/siem/rule/updateApiKey", + "alerting:siem.mlRule/siem/rule/enable", + "alerting:siem.mlRule/siem/rule/disable", + "alerting:siem.mlRule/siem/rule/muteAll", + "alerting:siem.mlRule/siem/rule/unmuteAll", + "alerting:siem.mlRule/siem/rule/muteAlert", + "alerting:siem.mlRule/siem/rule/unmuteAlert", + "alerting:siem.mlRule/siem/rule/snooze", + "alerting:siem.mlRule/siem/rule/bulkEdit", + "alerting:siem.mlRule/siem/rule/bulkDelete", + "alerting:siem.mlRule/siem/rule/bulkEnable", + "alerting:siem.mlRule/siem/rule/bulkDisable", + "alerting:siem.mlRule/siem/rule/unsnooze", + "alerting:siem.mlRule/siem/rule/runSoon", + "alerting:siem.mlRule/siem/rule/scheduleBackfill", + "alerting:siem.mlRule/siem/rule/deleteBackfill", + "alerting:siem.queryRule/siem/rule/get", + "alerting:siem.queryRule/siem/rule/getRuleState", + "alerting:siem.queryRule/siem/rule/getAlertSummary", + "alerting:siem.queryRule/siem/rule/getExecutionLog", + "alerting:siem.queryRule/siem/rule/getActionErrorLog", + "alerting:siem.queryRule/siem/rule/find", + "alerting:siem.queryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.queryRule/siem/rule/getBackfill", + "alerting:siem.queryRule/siem/rule/findBackfill", + "alerting:siem.queryRule/siem/rule/create", + "alerting:siem.queryRule/siem/rule/delete", + "alerting:siem.queryRule/siem/rule/update", + "alerting:siem.queryRule/siem/rule/updateApiKey", + "alerting:siem.queryRule/siem/rule/enable", + "alerting:siem.queryRule/siem/rule/disable", + "alerting:siem.queryRule/siem/rule/muteAll", + "alerting:siem.queryRule/siem/rule/unmuteAll", + "alerting:siem.queryRule/siem/rule/muteAlert", + "alerting:siem.queryRule/siem/rule/unmuteAlert", + "alerting:siem.queryRule/siem/rule/snooze", + "alerting:siem.queryRule/siem/rule/bulkEdit", + "alerting:siem.queryRule/siem/rule/bulkDelete", + "alerting:siem.queryRule/siem/rule/bulkEnable", + "alerting:siem.queryRule/siem/rule/bulkDisable", + "alerting:siem.queryRule/siem/rule/unsnooze", + "alerting:siem.queryRule/siem/rule/runSoon", + "alerting:siem.queryRule/siem/rule/scheduleBackfill", + "alerting:siem.queryRule/siem/rule/deleteBackfill", + "alerting:siem.savedQueryRule/siem/rule/get", + "alerting:siem.savedQueryRule/siem/rule/getRuleState", + "alerting:siem.savedQueryRule/siem/rule/getAlertSummary", + "alerting:siem.savedQueryRule/siem/rule/getExecutionLog", + "alerting:siem.savedQueryRule/siem/rule/getActionErrorLog", + "alerting:siem.savedQueryRule/siem/rule/find", + "alerting:siem.savedQueryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.savedQueryRule/siem/rule/getBackfill", + "alerting:siem.savedQueryRule/siem/rule/findBackfill", + "alerting:siem.savedQueryRule/siem/rule/create", + "alerting:siem.savedQueryRule/siem/rule/delete", + "alerting:siem.savedQueryRule/siem/rule/update", + "alerting:siem.savedQueryRule/siem/rule/updateApiKey", + "alerting:siem.savedQueryRule/siem/rule/enable", + "alerting:siem.savedQueryRule/siem/rule/disable", + "alerting:siem.savedQueryRule/siem/rule/muteAll", + "alerting:siem.savedQueryRule/siem/rule/unmuteAll", + "alerting:siem.savedQueryRule/siem/rule/muteAlert", + "alerting:siem.savedQueryRule/siem/rule/unmuteAlert", + "alerting:siem.savedQueryRule/siem/rule/snooze", + "alerting:siem.savedQueryRule/siem/rule/bulkEdit", + "alerting:siem.savedQueryRule/siem/rule/bulkDelete", + "alerting:siem.savedQueryRule/siem/rule/bulkEnable", + "alerting:siem.savedQueryRule/siem/rule/bulkDisable", + "alerting:siem.savedQueryRule/siem/rule/unsnooze", + "alerting:siem.savedQueryRule/siem/rule/runSoon", + "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", + "alerting:siem.savedQueryRule/siem/rule/deleteBackfill", + "alerting:siem.thresholdRule/siem/rule/get", + "alerting:siem.thresholdRule/siem/rule/getRuleState", + "alerting:siem.thresholdRule/siem/rule/getAlertSummary", + "alerting:siem.thresholdRule/siem/rule/getExecutionLog", + "alerting:siem.thresholdRule/siem/rule/getActionErrorLog", + "alerting:siem.thresholdRule/siem/rule/find", + "alerting:siem.thresholdRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.thresholdRule/siem/rule/getBackfill", + "alerting:siem.thresholdRule/siem/rule/findBackfill", + "alerting:siem.thresholdRule/siem/rule/create", + "alerting:siem.thresholdRule/siem/rule/delete", + "alerting:siem.thresholdRule/siem/rule/update", + "alerting:siem.thresholdRule/siem/rule/updateApiKey", + "alerting:siem.thresholdRule/siem/rule/enable", + "alerting:siem.thresholdRule/siem/rule/disable", + "alerting:siem.thresholdRule/siem/rule/muteAll", + "alerting:siem.thresholdRule/siem/rule/unmuteAll", + "alerting:siem.thresholdRule/siem/rule/muteAlert", + "alerting:siem.thresholdRule/siem/rule/unmuteAlert", + "alerting:siem.thresholdRule/siem/rule/snooze", + "alerting:siem.thresholdRule/siem/rule/bulkEdit", + "alerting:siem.thresholdRule/siem/rule/bulkDelete", + "alerting:siem.thresholdRule/siem/rule/bulkEnable", + "alerting:siem.thresholdRule/siem/rule/bulkDisable", + "alerting:siem.thresholdRule/siem/rule/unsnooze", + "alerting:siem.thresholdRule/siem/rule/runSoon", + "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", + "alerting:siem.thresholdRule/siem/rule/deleteBackfill", + "alerting:siem.newTermsRule/siem/rule/get", + "alerting:siem.newTermsRule/siem/rule/getRuleState", + "alerting:siem.newTermsRule/siem/rule/getAlertSummary", + "alerting:siem.newTermsRule/siem/rule/getExecutionLog", + "alerting:siem.newTermsRule/siem/rule/getActionErrorLog", + "alerting:siem.newTermsRule/siem/rule/find", + "alerting:siem.newTermsRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.newTermsRule/siem/rule/getBackfill", + "alerting:siem.newTermsRule/siem/rule/findBackfill", + "alerting:siem.newTermsRule/siem/rule/create", + "alerting:siem.newTermsRule/siem/rule/delete", + "alerting:siem.newTermsRule/siem/rule/update", + "alerting:siem.newTermsRule/siem/rule/updateApiKey", + "alerting:siem.newTermsRule/siem/rule/enable", + "alerting:siem.newTermsRule/siem/rule/disable", + "alerting:siem.newTermsRule/siem/rule/muteAll", + "alerting:siem.newTermsRule/siem/rule/unmuteAll", + "alerting:siem.newTermsRule/siem/rule/muteAlert", + "alerting:siem.newTermsRule/siem/rule/unmuteAlert", + "alerting:siem.newTermsRule/siem/rule/snooze", + "alerting:siem.newTermsRule/siem/rule/bulkEdit", + "alerting:siem.newTermsRule/siem/rule/bulkDelete", + "alerting:siem.newTermsRule/siem/rule/bulkEnable", + "alerting:siem.newTermsRule/siem/rule/bulkDisable", + "alerting:siem.newTermsRule/siem/rule/unsnooze", + "alerting:siem.newTermsRule/siem/rule/runSoon", + "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", + "alerting:siem.newTermsRule/siem/rule/deleteBackfill", + "alerting:siem.notifications/siem/alert/get", + "alerting:siem.notifications/siem/alert/find", + "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.notifications/siem/alert/getAlertSummary", + "alerting:siem.notifications/siem/alert/update", + "alerting:siem.esqlRule/siem/alert/get", + "alerting:siem.esqlRule/siem/alert/find", + "alerting:siem.esqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.esqlRule/siem/alert/getAlertSummary", + "alerting:siem.esqlRule/siem/alert/update", + "alerting:siem.eqlRule/siem/alert/get", + "alerting:siem.eqlRule/siem/alert/find", + "alerting:siem.eqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.eqlRule/siem/alert/getAlertSummary", + "alerting:siem.eqlRule/siem/alert/update", + "alerting:siem.indicatorRule/siem/alert/get", + "alerting:siem.indicatorRule/siem/alert/find", + "alerting:siem.indicatorRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.indicatorRule/siem/alert/getAlertSummary", + "alerting:siem.indicatorRule/siem/alert/update", + "alerting:siem.mlRule/siem/alert/get", + "alerting:siem.mlRule/siem/alert/find", + "alerting:siem.mlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.mlRule/siem/alert/getAlertSummary", + "alerting:siem.mlRule/siem/alert/update", + "alerting:siem.queryRule/siem/alert/get", + "alerting:siem.queryRule/siem/alert/find", + "alerting:siem.queryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.queryRule/siem/alert/getAlertSummary", + "alerting:siem.queryRule/siem/alert/update", + "alerting:siem.savedQueryRule/siem/alert/get", + "alerting:siem.savedQueryRule/siem/alert/find", + "alerting:siem.savedQueryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.savedQueryRule/siem/alert/getAlertSummary", + "alerting:siem.savedQueryRule/siem/alert/update", + "alerting:siem.thresholdRule/siem/alert/get", + "alerting:siem.thresholdRule/siem/alert/find", + "alerting:siem.thresholdRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.thresholdRule/siem/alert/getAlertSummary", + "alerting:siem.thresholdRule/siem/alert/update", + "alerting:siem.newTermsRule/siem/alert/get", + "alerting:siem.newTermsRule/siem/alert/find", + "alerting:siem.newTermsRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.newTermsRule/siem/alert/getAlertSummary", + "alerting:siem.newTermsRule/siem/alert/update", + "api:fileUpload:analyzeFile", + "api:store_search_session", + "api:generateReport", + "app:discover", + "ui:catalogue/discover", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/discover", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + "ui:discover/createShortUrl", + "ui:discover/storeSearchSession", + "ui:discover/generateCsv", + "api:bulkGetUserProfiles", + "api:downloadCsv", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "ui:dashboard/createNew", + "ui:dashboard/show", + "ui:dashboard/showWriteControls", + "ui:dashboard/saveQuery", + "ui:dashboard/createShortUrl", + "ui:dashboard/storeSearchSession", + "ui:dashboard/generateScreenshot", + "ui:dashboard/downloadCsv", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "ui:visualize/show", + "ui:visualize/delete", + "ui:visualize/save", + "ui:visualize/saveQuery", + "ui:visualize/createShortUrl", + "ui:visualize/generateScreenshot", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps/save", + "ui:maps/show", + "ui:maps/saveQuery", + ], + "blocklist_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-writeBlocklist", + "api:securitySolution-readBlocklist", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siem/writeBlocklist", + "ui:siem/readBlocklist", + ], + "blocklist_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readBlocklist", + "ui:siem/readBlocklist", + ], + "endpoint_exceptions_all": Array [ + "login:", + "api:securitySolution-showEndpointExceptions", + "api:securitySolution-crudEndpointExceptions", + "ui:siem/showEndpointExceptions", + "ui:siem/crudEndpointExceptions", + ], + "endpoint_exceptions_read": Array [ + "login:", + "api:securitySolution-showEndpointExceptions", + "ui:siem/showEndpointExceptions", + ], + "endpoint_list_all": Array [ + "login:", + "api:securitySolution-writeEndpointList", + "api:securitySolution-readEndpointList", + "ui:siem/writeEndpointList", + "ui:siem/readEndpointList", + ], + "endpoint_list_read": Array [ + "login:", + "api:securitySolution-readEndpointList", + "ui:siem/readEndpointList", + ], + "event_filters_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-writeEventFilters", + "api:securitySolution-readEventFilters", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siem/writeEventFilters", + "ui:siem/readEventFilters", + ], + "event_filters_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readEventFilters", + "ui:siem/readEventFilters", + ], + "execute_operations_all": Array [ + "login:", + "api:securitySolution-writeExecuteOperations", + "ui:siem/writeExecuteOperations", + ], + "file_operations_all": Array [ + "login:", + "api:securitySolution-writeFileOperations", + "ui:siem/writeFileOperations", + ], + "host_isolation_all": Array [ + "login:", + "api:securitySolution-writeHostIsolationRelease", + "api:securitySolution-writeHostIsolation", + "ui:siem/writeHostIsolationRelease", + "ui:siem/writeHostIsolation", + ], + "host_isolation_exceptions_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-deleteHostIsolationExceptions", + "api:securitySolution-readHostIsolationExceptions", + "api:securitySolution-accessHostIsolationExceptions", + "api:securitySolution-writeHostIsolationExceptions", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siem/readHostIsolationExceptions", + "ui:siem/deleteHostIsolationExceptions", + "ui:siem/accessHostIsolationExceptions", + "ui:siem/writeHostIsolationExceptions", + ], + "host_isolation_exceptions_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readHostIsolationExceptions", + "api:securitySolution-accessHostIsolationExceptions", + "ui:siem/readHostIsolationExceptions", + "ui:siem/accessHostIsolationExceptions", + ], + "minimal_all": Array [ + "login:", + "api:securitySolution", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:rac", + "api:cloud-security-posture-all", + "api:cloud-security-posture-read", + "api:cloud-defend-all", + "api:cloud-defend-read", + "api:securitySolution-entity-analytics", + "api:securitySolution-threat-intelligence", + "app:securitySolution", + "app:csp", + "app:cloudDefend", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/cloudDefend", + "ui:navLinks/kibana", + "saved_object:alert/bulk_get", + "saved_object:alert/get", + "saved_object:alert/find", + "saved_object:alert/open_point_in_time", + "saved_object:alert/close_point_in_time", + "saved_object:alert/create", + "saved_object:alert/bulk_create", + "saved_object:alert/update", + "saved_object:alert/bulk_update", + "saved_object:alert/delete", + "saved_object:alert/bulk_delete", + "saved_object:alert/share_to_space", + "saved_object:exception-list/bulk_get", + "saved_object:exception-list/get", + "saved_object:exception-list/find", + "saved_object:exception-list/open_point_in_time", + "saved_object:exception-list/close_point_in_time", + "saved_object:exception-list/create", + "saved_object:exception-list/bulk_create", + "saved_object:exception-list/update", + "saved_object:exception-list/bulk_update", + "saved_object:exception-list/delete", + "saved_object:exception-list/bulk_delete", + "saved_object:exception-list/share_to_space", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:index-pattern/create", + "saved_object:index-pattern/bulk_create", + "saved_object:index-pattern/update", + "saved_object:index-pattern/bulk_update", + "saved_object:index-pattern/delete", + "saved_object:index-pattern/bulk_delete", + "saved_object:index-pattern/share_to_space", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-note/create", + "saved_object:siem-ui-timeline-note/bulk_create", + "saved_object:siem-ui-timeline-note/update", + "saved_object:siem-ui-timeline-note/bulk_update", + "saved_object:siem-ui-timeline-note/delete", + "saved_object:siem-ui-timeline-note/bulk_delete", + "saved_object:siem-ui-timeline-note/share_to_space", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/create", + "saved_object:siem-ui-timeline-pinned-event/bulk_create", + "saved_object:siem-ui-timeline-pinned-event/update", + "saved_object:siem-ui-timeline-pinned-event/bulk_update", + "saved_object:siem-ui-timeline-pinned-event/delete", + "saved_object:siem-ui-timeline-pinned-event/bulk_delete", + "saved_object:siem-ui-timeline-pinned-event/share_to_space", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/create", + "saved_object:siem-detection-engine-rule-actions/bulk_create", + "saved_object:siem-detection-engine-rule-actions/update", + "saved_object:siem-detection-engine-rule-actions/bulk_update", + "saved_object:siem-detection-engine-rule-actions/delete", + "saved_object:siem-detection-engine-rule-actions/bulk_delete", + "saved_object:siem-detection-engine-rule-actions/share_to_space", + "saved_object:security-rule/bulk_get", + "saved_object:security-rule/get", + "saved_object:security-rule/find", + "saved_object:security-rule/open_point_in_time", + "saved_object:security-rule/close_point_in_time", + "saved_object:security-rule/create", + "saved_object:security-rule/bulk_create", + "saved_object:security-rule/update", + "saved_object:security-rule/bulk_update", + "saved_object:security-rule/delete", + "saved_object:security-rule/bulk_delete", + "saved_object:security-rule/share_to_space", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", + "saved_object:siem-ui-timeline/create", + "saved_object:siem-ui-timeline/bulk_create", + "saved_object:siem-ui-timeline/update", + "saved_object:siem-ui-timeline/bulk_update", + "saved_object:siem-ui-timeline/delete", + "saved_object:siem-ui-timeline/bulk_delete", + "saved_object:siem-ui-timeline/share_to_space", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/create", + "saved_object:endpoint:user-artifact-manifest/bulk_create", + "saved_object:endpoint:user-artifact-manifest/update", + "saved_object:endpoint:user-artifact-manifest/bulk_update", + "saved_object:endpoint:user-artifact-manifest/delete", + "saved_object:endpoint:user-artifact-manifest/bulk_delete", + "saved_object:endpoint:user-artifact-manifest/share_to_space", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/create", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_create", + "saved_object:endpoint:unified-user-artifact-manifest/update", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_update", + "saved_object:endpoint:unified-user-artifact-manifest/delete", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_delete", + "saved_object:endpoint:unified-user-artifact-manifest/share_to_space", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:security-solution-signals-migration/create", + "saved_object:security-solution-signals-migration/bulk_create", + "saved_object:security-solution-signals-migration/update", + "saved_object:security-solution-signals-migration/bulk_update", + "saved_object:security-solution-signals-migration/delete", + "saved_object:security-solution-signals-migration/bulk_delete", + "saved_object:security-solution-signals-migration/share_to_space", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:risk-engine-configuration/create", + "saved_object:risk-engine-configuration/bulk_create", + "saved_object:risk-engine-configuration/update", + "saved_object:risk-engine-configuration/bulk_update", + "saved_object:risk-engine-configuration/delete", + "saved_object:risk-engine-configuration/bulk_delete", + "saved_object:risk-engine-configuration/share_to_space", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/create", + "saved_object:policy-settings-protection-updates-note/bulk_create", + "saved_object:policy-settings-protection-updates-note/update", + "saved_object:policy-settings-protection-updates-note/bulk_update", + "saved_object:policy-settings-protection-updates-note/delete", + "saved_object:policy-settings-protection-updates-note/bulk_delete", + "saved_object:policy-settings-protection-updates-note/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:siem/show", + "ui:siem/crud", + "ui:siem/entity-analytics", + "ui:siem/investigation-guide", + "ui:siem/investigation-guide-interactions", + "ui:siem/threat-intelligence", + "alerting:siem.notifications/siem/rule/get", + "alerting:siem.notifications/siem/rule/getRuleState", + "alerting:siem.notifications/siem/rule/getAlertSummary", + "alerting:siem.notifications/siem/rule/getExecutionLog", + "alerting:siem.notifications/siem/rule/getActionErrorLog", + "alerting:siem.notifications/siem/rule/find", + "alerting:siem.notifications/siem/rule/getRuleExecutionKPI", + "alerting:siem.notifications/siem/rule/getBackfill", + "alerting:siem.notifications/siem/rule/findBackfill", + "alerting:siem.notifications/siem/rule/create", + "alerting:siem.notifications/siem/rule/delete", + "alerting:siem.notifications/siem/rule/update", + "alerting:siem.notifications/siem/rule/updateApiKey", + "alerting:siem.notifications/siem/rule/enable", + "alerting:siem.notifications/siem/rule/disable", + "alerting:siem.notifications/siem/rule/muteAll", + "alerting:siem.notifications/siem/rule/unmuteAll", + "alerting:siem.notifications/siem/rule/muteAlert", + "alerting:siem.notifications/siem/rule/unmuteAlert", + "alerting:siem.notifications/siem/rule/snooze", + "alerting:siem.notifications/siem/rule/bulkEdit", + "alerting:siem.notifications/siem/rule/bulkDelete", + "alerting:siem.notifications/siem/rule/bulkEnable", + "alerting:siem.notifications/siem/rule/bulkDisable", + "alerting:siem.notifications/siem/rule/unsnooze", + "alerting:siem.notifications/siem/rule/runSoon", + "alerting:siem.notifications/siem/rule/scheduleBackfill", + "alerting:siem.notifications/siem/rule/deleteBackfill", + "alerting:siem.esqlRule/siem/rule/get", + "alerting:siem.esqlRule/siem/rule/getRuleState", + "alerting:siem.esqlRule/siem/rule/getAlertSummary", + "alerting:siem.esqlRule/siem/rule/getExecutionLog", + "alerting:siem.esqlRule/siem/rule/getActionErrorLog", + "alerting:siem.esqlRule/siem/rule/find", + "alerting:siem.esqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.esqlRule/siem/rule/getBackfill", + "alerting:siem.esqlRule/siem/rule/findBackfill", + "alerting:siem.esqlRule/siem/rule/create", + "alerting:siem.esqlRule/siem/rule/delete", + "alerting:siem.esqlRule/siem/rule/update", + "alerting:siem.esqlRule/siem/rule/updateApiKey", + "alerting:siem.esqlRule/siem/rule/enable", + "alerting:siem.esqlRule/siem/rule/disable", + "alerting:siem.esqlRule/siem/rule/muteAll", + "alerting:siem.esqlRule/siem/rule/unmuteAll", + "alerting:siem.esqlRule/siem/rule/muteAlert", + "alerting:siem.esqlRule/siem/rule/unmuteAlert", + "alerting:siem.esqlRule/siem/rule/snooze", + "alerting:siem.esqlRule/siem/rule/bulkEdit", + "alerting:siem.esqlRule/siem/rule/bulkDelete", + "alerting:siem.esqlRule/siem/rule/bulkEnable", + "alerting:siem.esqlRule/siem/rule/bulkDisable", + "alerting:siem.esqlRule/siem/rule/unsnooze", + "alerting:siem.esqlRule/siem/rule/runSoon", + "alerting:siem.esqlRule/siem/rule/scheduleBackfill", + "alerting:siem.esqlRule/siem/rule/deleteBackfill", + "alerting:siem.eqlRule/siem/rule/get", + "alerting:siem.eqlRule/siem/rule/getRuleState", + "alerting:siem.eqlRule/siem/rule/getAlertSummary", + "alerting:siem.eqlRule/siem/rule/getExecutionLog", + "alerting:siem.eqlRule/siem/rule/getActionErrorLog", + "alerting:siem.eqlRule/siem/rule/find", + "alerting:siem.eqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.eqlRule/siem/rule/getBackfill", + "alerting:siem.eqlRule/siem/rule/findBackfill", + "alerting:siem.eqlRule/siem/rule/create", + "alerting:siem.eqlRule/siem/rule/delete", + "alerting:siem.eqlRule/siem/rule/update", + "alerting:siem.eqlRule/siem/rule/updateApiKey", + "alerting:siem.eqlRule/siem/rule/enable", + "alerting:siem.eqlRule/siem/rule/disable", + "alerting:siem.eqlRule/siem/rule/muteAll", + "alerting:siem.eqlRule/siem/rule/unmuteAll", + "alerting:siem.eqlRule/siem/rule/muteAlert", + "alerting:siem.eqlRule/siem/rule/unmuteAlert", + "alerting:siem.eqlRule/siem/rule/snooze", + "alerting:siem.eqlRule/siem/rule/bulkEdit", + "alerting:siem.eqlRule/siem/rule/bulkDelete", + "alerting:siem.eqlRule/siem/rule/bulkEnable", + "alerting:siem.eqlRule/siem/rule/bulkDisable", + "alerting:siem.eqlRule/siem/rule/unsnooze", + "alerting:siem.eqlRule/siem/rule/runSoon", + "alerting:siem.eqlRule/siem/rule/scheduleBackfill", + "alerting:siem.eqlRule/siem/rule/deleteBackfill", + "alerting:siem.indicatorRule/siem/rule/get", + "alerting:siem.indicatorRule/siem/rule/getRuleState", + "alerting:siem.indicatorRule/siem/rule/getAlertSummary", + "alerting:siem.indicatorRule/siem/rule/getExecutionLog", + "alerting:siem.indicatorRule/siem/rule/getActionErrorLog", + "alerting:siem.indicatorRule/siem/rule/find", + "alerting:siem.indicatorRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.indicatorRule/siem/rule/getBackfill", + "alerting:siem.indicatorRule/siem/rule/findBackfill", + "alerting:siem.indicatorRule/siem/rule/create", + "alerting:siem.indicatorRule/siem/rule/delete", + "alerting:siem.indicatorRule/siem/rule/update", + "alerting:siem.indicatorRule/siem/rule/updateApiKey", + "alerting:siem.indicatorRule/siem/rule/enable", + "alerting:siem.indicatorRule/siem/rule/disable", + "alerting:siem.indicatorRule/siem/rule/muteAll", + "alerting:siem.indicatorRule/siem/rule/unmuteAll", + "alerting:siem.indicatorRule/siem/rule/muteAlert", + "alerting:siem.indicatorRule/siem/rule/unmuteAlert", + "alerting:siem.indicatorRule/siem/rule/snooze", + "alerting:siem.indicatorRule/siem/rule/bulkEdit", + "alerting:siem.indicatorRule/siem/rule/bulkDelete", + "alerting:siem.indicatorRule/siem/rule/bulkEnable", + "alerting:siem.indicatorRule/siem/rule/bulkDisable", + "alerting:siem.indicatorRule/siem/rule/unsnooze", + "alerting:siem.indicatorRule/siem/rule/runSoon", + "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", + "alerting:siem.indicatorRule/siem/rule/deleteBackfill", + "alerting:siem.mlRule/siem/rule/get", + "alerting:siem.mlRule/siem/rule/getRuleState", + "alerting:siem.mlRule/siem/rule/getAlertSummary", + "alerting:siem.mlRule/siem/rule/getExecutionLog", + "alerting:siem.mlRule/siem/rule/getActionErrorLog", + "alerting:siem.mlRule/siem/rule/find", + "alerting:siem.mlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.mlRule/siem/rule/getBackfill", + "alerting:siem.mlRule/siem/rule/findBackfill", + "alerting:siem.mlRule/siem/rule/create", + "alerting:siem.mlRule/siem/rule/delete", + "alerting:siem.mlRule/siem/rule/update", + "alerting:siem.mlRule/siem/rule/updateApiKey", + "alerting:siem.mlRule/siem/rule/enable", + "alerting:siem.mlRule/siem/rule/disable", + "alerting:siem.mlRule/siem/rule/muteAll", + "alerting:siem.mlRule/siem/rule/unmuteAll", + "alerting:siem.mlRule/siem/rule/muteAlert", + "alerting:siem.mlRule/siem/rule/unmuteAlert", + "alerting:siem.mlRule/siem/rule/snooze", + "alerting:siem.mlRule/siem/rule/bulkEdit", + "alerting:siem.mlRule/siem/rule/bulkDelete", + "alerting:siem.mlRule/siem/rule/bulkEnable", + "alerting:siem.mlRule/siem/rule/bulkDisable", + "alerting:siem.mlRule/siem/rule/unsnooze", + "alerting:siem.mlRule/siem/rule/runSoon", + "alerting:siem.mlRule/siem/rule/scheduleBackfill", + "alerting:siem.mlRule/siem/rule/deleteBackfill", + "alerting:siem.queryRule/siem/rule/get", + "alerting:siem.queryRule/siem/rule/getRuleState", + "alerting:siem.queryRule/siem/rule/getAlertSummary", + "alerting:siem.queryRule/siem/rule/getExecutionLog", + "alerting:siem.queryRule/siem/rule/getActionErrorLog", + "alerting:siem.queryRule/siem/rule/find", + "alerting:siem.queryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.queryRule/siem/rule/getBackfill", + "alerting:siem.queryRule/siem/rule/findBackfill", + "alerting:siem.queryRule/siem/rule/create", + "alerting:siem.queryRule/siem/rule/delete", + "alerting:siem.queryRule/siem/rule/update", + "alerting:siem.queryRule/siem/rule/updateApiKey", + "alerting:siem.queryRule/siem/rule/enable", + "alerting:siem.queryRule/siem/rule/disable", + "alerting:siem.queryRule/siem/rule/muteAll", + "alerting:siem.queryRule/siem/rule/unmuteAll", + "alerting:siem.queryRule/siem/rule/muteAlert", + "alerting:siem.queryRule/siem/rule/unmuteAlert", + "alerting:siem.queryRule/siem/rule/snooze", + "alerting:siem.queryRule/siem/rule/bulkEdit", + "alerting:siem.queryRule/siem/rule/bulkDelete", + "alerting:siem.queryRule/siem/rule/bulkEnable", + "alerting:siem.queryRule/siem/rule/bulkDisable", + "alerting:siem.queryRule/siem/rule/unsnooze", + "alerting:siem.queryRule/siem/rule/runSoon", + "alerting:siem.queryRule/siem/rule/scheduleBackfill", + "alerting:siem.queryRule/siem/rule/deleteBackfill", + "alerting:siem.savedQueryRule/siem/rule/get", + "alerting:siem.savedQueryRule/siem/rule/getRuleState", + "alerting:siem.savedQueryRule/siem/rule/getAlertSummary", + "alerting:siem.savedQueryRule/siem/rule/getExecutionLog", + "alerting:siem.savedQueryRule/siem/rule/getActionErrorLog", + "alerting:siem.savedQueryRule/siem/rule/find", + "alerting:siem.savedQueryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.savedQueryRule/siem/rule/getBackfill", + "alerting:siem.savedQueryRule/siem/rule/findBackfill", + "alerting:siem.savedQueryRule/siem/rule/create", + "alerting:siem.savedQueryRule/siem/rule/delete", + "alerting:siem.savedQueryRule/siem/rule/update", + "alerting:siem.savedQueryRule/siem/rule/updateApiKey", + "alerting:siem.savedQueryRule/siem/rule/enable", + "alerting:siem.savedQueryRule/siem/rule/disable", + "alerting:siem.savedQueryRule/siem/rule/muteAll", + "alerting:siem.savedQueryRule/siem/rule/unmuteAll", + "alerting:siem.savedQueryRule/siem/rule/muteAlert", + "alerting:siem.savedQueryRule/siem/rule/unmuteAlert", + "alerting:siem.savedQueryRule/siem/rule/snooze", + "alerting:siem.savedQueryRule/siem/rule/bulkEdit", + "alerting:siem.savedQueryRule/siem/rule/bulkDelete", + "alerting:siem.savedQueryRule/siem/rule/bulkEnable", + "alerting:siem.savedQueryRule/siem/rule/bulkDisable", + "alerting:siem.savedQueryRule/siem/rule/unsnooze", + "alerting:siem.savedQueryRule/siem/rule/runSoon", + "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", + "alerting:siem.savedQueryRule/siem/rule/deleteBackfill", + "alerting:siem.thresholdRule/siem/rule/get", + "alerting:siem.thresholdRule/siem/rule/getRuleState", + "alerting:siem.thresholdRule/siem/rule/getAlertSummary", + "alerting:siem.thresholdRule/siem/rule/getExecutionLog", + "alerting:siem.thresholdRule/siem/rule/getActionErrorLog", + "alerting:siem.thresholdRule/siem/rule/find", + "alerting:siem.thresholdRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.thresholdRule/siem/rule/getBackfill", + "alerting:siem.thresholdRule/siem/rule/findBackfill", + "alerting:siem.thresholdRule/siem/rule/create", + "alerting:siem.thresholdRule/siem/rule/delete", + "alerting:siem.thresholdRule/siem/rule/update", + "alerting:siem.thresholdRule/siem/rule/updateApiKey", + "alerting:siem.thresholdRule/siem/rule/enable", + "alerting:siem.thresholdRule/siem/rule/disable", + "alerting:siem.thresholdRule/siem/rule/muteAll", + "alerting:siem.thresholdRule/siem/rule/unmuteAll", + "alerting:siem.thresholdRule/siem/rule/muteAlert", + "alerting:siem.thresholdRule/siem/rule/unmuteAlert", + "alerting:siem.thresholdRule/siem/rule/snooze", + "alerting:siem.thresholdRule/siem/rule/bulkEdit", + "alerting:siem.thresholdRule/siem/rule/bulkDelete", + "alerting:siem.thresholdRule/siem/rule/bulkEnable", + "alerting:siem.thresholdRule/siem/rule/bulkDisable", + "alerting:siem.thresholdRule/siem/rule/unsnooze", + "alerting:siem.thresholdRule/siem/rule/runSoon", + "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", + "alerting:siem.thresholdRule/siem/rule/deleteBackfill", + "alerting:siem.newTermsRule/siem/rule/get", + "alerting:siem.newTermsRule/siem/rule/getRuleState", + "alerting:siem.newTermsRule/siem/rule/getAlertSummary", + "alerting:siem.newTermsRule/siem/rule/getExecutionLog", + "alerting:siem.newTermsRule/siem/rule/getActionErrorLog", + "alerting:siem.newTermsRule/siem/rule/find", + "alerting:siem.newTermsRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.newTermsRule/siem/rule/getBackfill", + "alerting:siem.newTermsRule/siem/rule/findBackfill", + "alerting:siem.newTermsRule/siem/rule/create", + "alerting:siem.newTermsRule/siem/rule/delete", + "alerting:siem.newTermsRule/siem/rule/update", + "alerting:siem.newTermsRule/siem/rule/updateApiKey", + "alerting:siem.newTermsRule/siem/rule/enable", + "alerting:siem.newTermsRule/siem/rule/disable", + "alerting:siem.newTermsRule/siem/rule/muteAll", + "alerting:siem.newTermsRule/siem/rule/unmuteAll", + "alerting:siem.newTermsRule/siem/rule/muteAlert", + "alerting:siem.newTermsRule/siem/rule/unmuteAlert", + "alerting:siem.newTermsRule/siem/rule/snooze", + "alerting:siem.newTermsRule/siem/rule/bulkEdit", + "alerting:siem.newTermsRule/siem/rule/bulkDelete", + "alerting:siem.newTermsRule/siem/rule/bulkEnable", + "alerting:siem.newTermsRule/siem/rule/bulkDisable", + "alerting:siem.newTermsRule/siem/rule/unsnooze", + "alerting:siem.newTermsRule/siem/rule/runSoon", + "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", + "alerting:siem.newTermsRule/siem/rule/deleteBackfill", + "alerting:siem.notifications/siem/alert/get", + "alerting:siem.notifications/siem/alert/find", + "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.notifications/siem/alert/getAlertSummary", + "alerting:siem.notifications/siem/alert/update", + "alerting:siem.esqlRule/siem/alert/get", + "alerting:siem.esqlRule/siem/alert/find", + "alerting:siem.esqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.esqlRule/siem/alert/getAlertSummary", + "alerting:siem.esqlRule/siem/alert/update", + "alerting:siem.eqlRule/siem/alert/get", + "alerting:siem.eqlRule/siem/alert/find", + "alerting:siem.eqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.eqlRule/siem/alert/getAlertSummary", + "alerting:siem.eqlRule/siem/alert/update", + "alerting:siem.indicatorRule/siem/alert/get", + "alerting:siem.indicatorRule/siem/alert/find", + "alerting:siem.indicatorRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.indicatorRule/siem/alert/getAlertSummary", + "alerting:siem.indicatorRule/siem/alert/update", + "alerting:siem.mlRule/siem/alert/get", + "alerting:siem.mlRule/siem/alert/find", + "alerting:siem.mlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.mlRule/siem/alert/getAlertSummary", + "alerting:siem.mlRule/siem/alert/update", + "alerting:siem.queryRule/siem/alert/get", + "alerting:siem.queryRule/siem/alert/find", + "alerting:siem.queryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.queryRule/siem/alert/getAlertSummary", + "alerting:siem.queryRule/siem/alert/update", + "alerting:siem.savedQueryRule/siem/alert/get", + "alerting:siem.savedQueryRule/siem/alert/find", + "alerting:siem.savedQueryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.savedQueryRule/siem/alert/getAlertSummary", + "alerting:siem.savedQueryRule/siem/alert/update", + "alerting:siem.thresholdRule/siem/alert/get", + "alerting:siem.thresholdRule/siem/alert/find", + "alerting:siem.thresholdRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.thresholdRule/siem/alert/getAlertSummary", + "alerting:siem.thresholdRule/siem/alert/update", + "alerting:siem.newTermsRule/siem/alert/get", + "alerting:siem.newTermsRule/siem/alert/find", + "alerting:siem.newTermsRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.newTermsRule/siem/alert/getAlertSummary", + "alerting:siem.newTermsRule/siem/alert/update", + "api:fileUpload:analyzeFile", + "api:store_search_session", + "api:generateReport", + "app:discover", + "ui:catalogue/discover", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/discover", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + "ui:discover/createShortUrl", + "ui:discover/storeSearchSession", + "ui:discover/generateCsv", + "api:bulkGetUserProfiles", + "api:downloadCsv", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "ui:dashboard/createNew", + "ui:dashboard/show", + "ui:dashboard/showWriteControls", + "ui:dashboard/saveQuery", + "ui:dashboard/createShortUrl", + "ui:dashboard/storeSearchSession", + "ui:dashboard/generateScreenshot", + "ui:dashboard/downloadCsv", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "ui:visualize/show", + "ui:visualize/delete", + "ui:visualize/save", + "ui:visualize/saveQuery", + "ui:visualize/createShortUrl", + "ui:visualize/generateScreenshot", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps/save", + "ui:maps/show", + "ui:maps/saveQuery", + ], + "minimal_read": Array [ + "login:", + "api:securitySolution", + "api:lists-read", + "api:rac", + "api:cloud-security-posture-read", + "api:cloud-defend-read", + "api:securitySolution-entity-analytics", + "api:securitySolution-threat-intelligence", + "app:securitySolution", + "app:csp", + "app:cloudDefend", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/cloudDefend", + "ui:navLinks/kibana", + "saved_object:exception-list/bulk_get", + "saved_object:exception-list/get", + "saved_object:exception-list/find", + "saved_object:exception-list/open_point_in_time", + "saved_object:exception-list/close_point_in_time", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:security-rule/bulk_get", + "saved_object:security-rule/get", + "saved_object:security-rule/find", + "saved_object:security-rule/open_point_in_time", + "saved_object:security-rule/close_point_in_time", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:siem/show", + "ui:siem/entity-analytics", + "ui:siem/investigation-guide", + "ui:siem/investigation-guide-interactions", + "ui:siem/threat-intelligence", + "alerting:siem.notifications/siem/rule/get", + "alerting:siem.notifications/siem/rule/getRuleState", + "alerting:siem.notifications/siem/rule/getAlertSummary", + "alerting:siem.notifications/siem/rule/getExecutionLog", + "alerting:siem.notifications/siem/rule/getActionErrorLog", + "alerting:siem.notifications/siem/rule/find", + "alerting:siem.notifications/siem/rule/getRuleExecutionKPI", + "alerting:siem.notifications/siem/rule/getBackfill", + "alerting:siem.notifications/siem/rule/findBackfill", + "alerting:siem.esqlRule/siem/rule/get", + "alerting:siem.esqlRule/siem/rule/getRuleState", + "alerting:siem.esqlRule/siem/rule/getAlertSummary", + "alerting:siem.esqlRule/siem/rule/getExecutionLog", + "alerting:siem.esqlRule/siem/rule/getActionErrorLog", + "alerting:siem.esqlRule/siem/rule/find", + "alerting:siem.esqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.esqlRule/siem/rule/getBackfill", + "alerting:siem.esqlRule/siem/rule/findBackfill", + "alerting:siem.eqlRule/siem/rule/get", + "alerting:siem.eqlRule/siem/rule/getRuleState", + "alerting:siem.eqlRule/siem/rule/getAlertSummary", + "alerting:siem.eqlRule/siem/rule/getExecutionLog", + "alerting:siem.eqlRule/siem/rule/getActionErrorLog", + "alerting:siem.eqlRule/siem/rule/find", + "alerting:siem.eqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.eqlRule/siem/rule/getBackfill", + "alerting:siem.eqlRule/siem/rule/findBackfill", + "alerting:siem.indicatorRule/siem/rule/get", + "alerting:siem.indicatorRule/siem/rule/getRuleState", + "alerting:siem.indicatorRule/siem/rule/getAlertSummary", + "alerting:siem.indicatorRule/siem/rule/getExecutionLog", + "alerting:siem.indicatorRule/siem/rule/getActionErrorLog", + "alerting:siem.indicatorRule/siem/rule/find", + "alerting:siem.indicatorRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.indicatorRule/siem/rule/getBackfill", + "alerting:siem.indicatorRule/siem/rule/findBackfill", + "alerting:siem.mlRule/siem/rule/get", + "alerting:siem.mlRule/siem/rule/getRuleState", + "alerting:siem.mlRule/siem/rule/getAlertSummary", + "alerting:siem.mlRule/siem/rule/getExecutionLog", + "alerting:siem.mlRule/siem/rule/getActionErrorLog", + "alerting:siem.mlRule/siem/rule/find", + "alerting:siem.mlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.mlRule/siem/rule/getBackfill", + "alerting:siem.mlRule/siem/rule/findBackfill", + "alerting:siem.queryRule/siem/rule/get", + "alerting:siem.queryRule/siem/rule/getRuleState", + "alerting:siem.queryRule/siem/rule/getAlertSummary", + "alerting:siem.queryRule/siem/rule/getExecutionLog", + "alerting:siem.queryRule/siem/rule/getActionErrorLog", + "alerting:siem.queryRule/siem/rule/find", + "alerting:siem.queryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.queryRule/siem/rule/getBackfill", + "alerting:siem.queryRule/siem/rule/findBackfill", + "alerting:siem.savedQueryRule/siem/rule/get", + "alerting:siem.savedQueryRule/siem/rule/getRuleState", + "alerting:siem.savedQueryRule/siem/rule/getAlertSummary", + "alerting:siem.savedQueryRule/siem/rule/getExecutionLog", + "alerting:siem.savedQueryRule/siem/rule/getActionErrorLog", + "alerting:siem.savedQueryRule/siem/rule/find", + "alerting:siem.savedQueryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.savedQueryRule/siem/rule/getBackfill", + "alerting:siem.savedQueryRule/siem/rule/findBackfill", + "alerting:siem.thresholdRule/siem/rule/get", + "alerting:siem.thresholdRule/siem/rule/getRuleState", + "alerting:siem.thresholdRule/siem/rule/getAlertSummary", + "alerting:siem.thresholdRule/siem/rule/getExecutionLog", + "alerting:siem.thresholdRule/siem/rule/getActionErrorLog", + "alerting:siem.thresholdRule/siem/rule/find", + "alerting:siem.thresholdRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.thresholdRule/siem/rule/getBackfill", + "alerting:siem.thresholdRule/siem/rule/findBackfill", + "alerting:siem.newTermsRule/siem/rule/get", + "alerting:siem.newTermsRule/siem/rule/getRuleState", + "alerting:siem.newTermsRule/siem/rule/getAlertSummary", + "alerting:siem.newTermsRule/siem/rule/getExecutionLog", + "alerting:siem.newTermsRule/siem/rule/getActionErrorLog", + "alerting:siem.newTermsRule/siem/rule/find", + "alerting:siem.newTermsRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.newTermsRule/siem/rule/getBackfill", + "alerting:siem.newTermsRule/siem/rule/findBackfill", + "alerting:siem.notifications/siem/alert/get", + "alerting:siem.notifications/siem/alert/find", + "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.notifications/siem/alert/getAlertSummary", + "alerting:siem.notifications/siem/alert/update", + "alerting:siem.esqlRule/siem/alert/get", + "alerting:siem.esqlRule/siem/alert/find", + "alerting:siem.esqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.esqlRule/siem/alert/getAlertSummary", + "alerting:siem.esqlRule/siem/alert/update", + "alerting:siem.eqlRule/siem/alert/get", + "alerting:siem.eqlRule/siem/alert/find", + "alerting:siem.eqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.eqlRule/siem/alert/getAlertSummary", + "alerting:siem.eqlRule/siem/alert/update", + "alerting:siem.indicatorRule/siem/alert/get", + "alerting:siem.indicatorRule/siem/alert/find", + "alerting:siem.indicatorRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.indicatorRule/siem/alert/getAlertSummary", + "alerting:siem.indicatorRule/siem/alert/update", + "alerting:siem.mlRule/siem/alert/get", + "alerting:siem.mlRule/siem/alert/find", + "alerting:siem.mlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.mlRule/siem/alert/getAlertSummary", + "alerting:siem.mlRule/siem/alert/update", + "alerting:siem.queryRule/siem/alert/get", + "alerting:siem.queryRule/siem/alert/find", + "alerting:siem.queryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.queryRule/siem/alert/getAlertSummary", + "alerting:siem.queryRule/siem/alert/update", + "alerting:siem.savedQueryRule/siem/alert/get", + "alerting:siem.savedQueryRule/siem/alert/find", + "alerting:siem.savedQueryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.savedQueryRule/siem/alert/getAlertSummary", + "alerting:siem.savedQueryRule/siem/alert/update", + "alerting:siem.thresholdRule/siem/alert/get", + "alerting:siem.thresholdRule/siem/alert/find", + "alerting:siem.thresholdRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.thresholdRule/siem/alert/getAlertSummary", + "alerting:siem.thresholdRule/siem/alert/update", + "alerting:siem.newTermsRule/siem/alert/get", + "alerting:siem.newTermsRule/siem/alert/find", + "alerting:siem.newTermsRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.newTermsRule/siem/alert/getAlertSummary", + "alerting:siem.newTermsRule/siem/alert/update", + "app:discover", + "ui:catalogue/discover", + "ui:navLinks/discover", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "ui:discover/show", + "ui:discover/createShortUrl", + "api:bulkGetUserProfiles", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "ui:dashboard/show", + "ui:dashboard/createShortUrl", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "ui:visualize/show", + "ui:visualize/createShortUrl", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps/show", + ], + "policy_management_all": Array [ + "login:", + "api:securitySolution-writePolicyManagement", + "api:securitySolution-readPolicyManagement", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/create", + "saved_object:policy-settings-protection-updates-note/bulk_create", + "saved_object:policy-settings-protection-updates-note/update", + "saved_object:policy-settings-protection-updates-note/bulk_update", + "saved_object:policy-settings-protection-updates-note/delete", + "saved_object:policy-settings-protection-updates-note/bulk_delete", + "saved_object:policy-settings-protection-updates-note/share_to_space", + "ui:siem/writePolicyManagement", + "ui:siem/readPolicyManagement", + ], + "policy_management_read": Array [ + "login:", + "api:securitySolution-readPolicyManagement", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "ui:siem/readPolicyManagement", + ], + "process_operations_all": Array [ + "login:", + "api:securitySolution-writeProcessOperations", + "ui:siem/writeProcessOperations", + ], + "read": Array [ + "login:", + "api:securitySolution", + "api:lists-read", + "api:rac", + "api:cloud-security-posture-read", + "api:cloud-defend-read", + "api:securitySolution-entity-analytics", + "api:securitySolution-threat-intelligence", + "api:securitySolution-showEndpointExceptions", + "app:securitySolution", + "app:csp", + "app:cloudDefend", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/cloudDefend", + "ui:navLinks/kibana", + "saved_object:exception-list/bulk_get", + "saved_object:exception-list/get", + "saved_object:exception-list/find", + "saved_object:exception-list/open_point_in_time", + "saved_object:exception-list/close_point_in_time", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:security-rule/bulk_get", + "saved_object:security-rule/get", + "saved_object:security-rule/find", + "saved_object:security-rule/open_point_in_time", + "saved_object:security-rule/close_point_in_time", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:siem/show", + "ui:siem/entity-analytics", + "ui:siem/investigation-guide", + "ui:siem/investigation-guide-interactions", + "ui:siem/threat-intelligence", + "ui:siem/showEndpointExceptions", + "alerting:siem.notifications/siem/rule/get", + "alerting:siem.notifications/siem/rule/getRuleState", + "alerting:siem.notifications/siem/rule/getAlertSummary", + "alerting:siem.notifications/siem/rule/getExecutionLog", + "alerting:siem.notifications/siem/rule/getActionErrorLog", + "alerting:siem.notifications/siem/rule/find", + "alerting:siem.notifications/siem/rule/getRuleExecutionKPI", + "alerting:siem.notifications/siem/rule/getBackfill", + "alerting:siem.notifications/siem/rule/findBackfill", + "alerting:siem.esqlRule/siem/rule/get", + "alerting:siem.esqlRule/siem/rule/getRuleState", + "alerting:siem.esqlRule/siem/rule/getAlertSummary", + "alerting:siem.esqlRule/siem/rule/getExecutionLog", + "alerting:siem.esqlRule/siem/rule/getActionErrorLog", + "alerting:siem.esqlRule/siem/rule/find", + "alerting:siem.esqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.esqlRule/siem/rule/getBackfill", + "alerting:siem.esqlRule/siem/rule/findBackfill", + "alerting:siem.eqlRule/siem/rule/get", + "alerting:siem.eqlRule/siem/rule/getRuleState", + "alerting:siem.eqlRule/siem/rule/getAlertSummary", + "alerting:siem.eqlRule/siem/rule/getExecutionLog", + "alerting:siem.eqlRule/siem/rule/getActionErrorLog", + "alerting:siem.eqlRule/siem/rule/find", + "alerting:siem.eqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.eqlRule/siem/rule/getBackfill", + "alerting:siem.eqlRule/siem/rule/findBackfill", + "alerting:siem.indicatorRule/siem/rule/get", + "alerting:siem.indicatorRule/siem/rule/getRuleState", + "alerting:siem.indicatorRule/siem/rule/getAlertSummary", + "alerting:siem.indicatorRule/siem/rule/getExecutionLog", + "alerting:siem.indicatorRule/siem/rule/getActionErrorLog", + "alerting:siem.indicatorRule/siem/rule/find", + "alerting:siem.indicatorRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.indicatorRule/siem/rule/getBackfill", + "alerting:siem.indicatorRule/siem/rule/findBackfill", + "alerting:siem.mlRule/siem/rule/get", + "alerting:siem.mlRule/siem/rule/getRuleState", + "alerting:siem.mlRule/siem/rule/getAlertSummary", + "alerting:siem.mlRule/siem/rule/getExecutionLog", + "alerting:siem.mlRule/siem/rule/getActionErrorLog", + "alerting:siem.mlRule/siem/rule/find", + "alerting:siem.mlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.mlRule/siem/rule/getBackfill", + "alerting:siem.mlRule/siem/rule/findBackfill", + "alerting:siem.queryRule/siem/rule/get", + "alerting:siem.queryRule/siem/rule/getRuleState", + "alerting:siem.queryRule/siem/rule/getAlertSummary", + "alerting:siem.queryRule/siem/rule/getExecutionLog", + "alerting:siem.queryRule/siem/rule/getActionErrorLog", + "alerting:siem.queryRule/siem/rule/find", + "alerting:siem.queryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.queryRule/siem/rule/getBackfill", + "alerting:siem.queryRule/siem/rule/findBackfill", + "alerting:siem.savedQueryRule/siem/rule/get", + "alerting:siem.savedQueryRule/siem/rule/getRuleState", + "alerting:siem.savedQueryRule/siem/rule/getAlertSummary", + "alerting:siem.savedQueryRule/siem/rule/getExecutionLog", + "alerting:siem.savedQueryRule/siem/rule/getActionErrorLog", + "alerting:siem.savedQueryRule/siem/rule/find", + "alerting:siem.savedQueryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.savedQueryRule/siem/rule/getBackfill", + "alerting:siem.savedQueryRule/siem/rule/findBackfill", + "alerting:siem.thresholdRule/siem/rule/get", + "alerting:siem.thresholdRule/siem/rule/getRuleState", + "alerting:siem.thresholdRule/siem/rule/getAlertSummary", + "alerting:siem.thresholdRule/siem/rule/getExecutionLog", + "alerting:siem.thresholdRule/siem/rule/getActionErrorLog", + "alerting:siem.thresholdRule/siem/rule/find", + "alerting:siem.thresholdRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.thresholdRule/siem/rule/getBackfill", + "alerting:siem.thresholdRule/siem/rule/findBackfill", + "alerting:siem.newTermsRule/siem/rule/get", + "alerting:siem.newTermsRule/siem/rule/getRuleState", + "alerting:siem.newTermsRule/siem/rule/getAlertSummary", + "alerting:siem.newTermsRule/siem/rule/getExecutionLog", + "alerting:siem.newTermsRule/siem/rule/getActionErrorLog", + "alerting:siem.newTermsRule/siem/rule/find", + "alerting:siem.newTermsRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.newTermsRule/siem/rule/getBackfill", + "alerting:siem.newTermsRule/siem/rule/findBackfill", + "alerting:siem.notifications/siem/alert/get", + "alerting:siem.notifications/siem/alert/find", + "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.notifications/siem/alert/getAlertSummary", + "alerting:siem.notifications/siem/alert/update", + "alerting:siem.esqlRule/siem/alert/get", + "alerting:siem.esqlRule/siem/alert/find", + "alerting:siem.esqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.esqlRule/siem/alert/getAlertSummary", + "alerting:siem.esqlRule/siem/alert/update", + "alerting:siem.eqlRule/siem/alert/get", + "alerting:siem.eqlRule/siem/alert/find", + "alerting:siem.eqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.eqlRule/siem/alert/getAlertSummary", + "alerting:siem.eqlRule/siem/alert/update", + "alerting:siem.indicatorRule/siem/alert/get", + "alerting:siem.indicatorRule/siem/alert/find", + "alerting:siem.indicatorRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.indicatorRule/siem/alert/getAlertSummary", + "alerting:siem.indicatorRule/siem/alert/update", + "alerting:siem.mlRule/siem/alert/get", + "alerting:siem.mlRule/siem/alert/find", + "alerting:siem.mlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.mlRule/siem/alert/getAlertSummary", + "alerting:siem.mlRule/siem/alert/update", + "alerting:siem.queryRule/siem/alert/get", + "alerting:siem.queryRule/siem/alert/find", + "alerting:siem.queryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.queryRule/siem/alert/getAlertSummary", + "alerting:siem.queryRule/siem/alert/update", + "alerting:siem.savedQueryRule/siem/alert/get", + "alerting:siem.savedQueryRule/siem/alert/find", + "alerting:siem.savedQueryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.savedQueryRule/siem/alert/getAlertSummary", + "alerting:siem.savedQueryRule/siem/alert/update", + "alerting:siem.thresholdRule/siem/alert/get", + "alerting:siem.thresholdRule/siem/alert/find", + "alerting:siem.thresholdRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.thresholdRule/siem/alert/getAlertSummary", + "alerting:siem.thresholdRule/siem/alert/update", + "alerting:siem.newTermsRule/siem/alert/get", + "alerting:siem.newTermsRule/siem/alert/find", + "alerting:siem.newTermsRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.newTermsRule/siem/alert/getAlertSummary", + "alerting:siem.newTermsRule/siem/alert/update", + "app:discover", + "ui:catalogue/discover", + "ui:navLinks/discover", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "ui:discover/show", + "ui:discover/createShortUrl", + "api:bulkGetUserProfiles", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "ui:dashboard/show", + "ui:dashboard/createShortUrl", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "ui:visualize/show", + "ui:visualize/createShortUrl", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps/show", + ], + "trusted_applications_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-writeTrustedApplications", + "api:securitySolution-readTrustedApplications", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siem/writeTrustedApplications", + "ui:siem/readTrustedApplications", + ], + "trusted_applications_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readTrustedApplications", + "ui:siem/readTrustedApplications", + ], + }, + } + `); + }); + }); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/security/platform_security/index.ts b/x-pack/test_serverless/api_integration/test_suites/security/platform_security/index.ts new file mode 100644 index 0000000000000..5271f15b683f1 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/platform_security/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Platform security APIs', function () { + loadTestFile(require.resolve('./authorization')); + }); +} diff --git a/x-pack/test_serverless/tsconfig.json b/x-pack/test_serverless/tsconfig.json index 5dff8ab3431fd..e80bebb0e90ae 100644 --- a/x-pack/test_serverless/tsconfig.json +++ b/x-pack/test_serverless/tsconfig.json @@ -101,6 +101,7 @@ "@kbn/dataset-quality-plugin", "@kbn/alerting-comparators", "@kbn/search-types", - "@kbn/reporting-server" + "@kbn/reporting-server", + "@kbn/features-plugin" ] } From 556531b33336dad8ce502b36e119b90c7825b44a Mon Sep 17 00:00:00 2001 From: Nick Partridge Date: Thu, 6 Jun 2024 06:56:33 -0700 Subject: [PATCH 044/122] Fix sort field error message for last value (#184883) This PR fixes a minor bug on the **Last Value** editor config in which the **Sort by date field** was always considered invalid. --- .../definitions/last_value.test.tsx | 68 +++++++++++++++++++ .../operations/definitions/last_value.tsx | 11 ++- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx index 61748339d2a72..2beefab2f1439 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx @@ -21,6 +21,7 @@ import type { FormBasedLayer } from '../../types'; import { TermsIndexPatternColumn } from './terms'; import { EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; import { buildExpression, parseExpression } from '@kbn/expressions-plugin/common'; +import { FormRow } from './shared_components'; const uiSettingsMock = {} as IUiSettingsClient; @@ -877,6 +878,7 @@ describe('last_value', () => { expect(new Harness(instance).showArrayValuesSwitchDisabled).toBeTruthy(); }); + it('should not display an array for the last value if the column is referenced', () => { const updateLayerSpy = jest.fn(); const instance = shallow( @@ -892,6 +894,72 @@ describe('last_value', () => { expect(new Harness(instance).arrayValuesSwitchNotExisiting).toBeTruthy(); }); + + it('should show valid sort field for date field', () => { + const instance = shallow( + + ); + + expect(instance.find(FormRow).prop('isInvalid')).toBe(false); + }); + + it('should show invalid sort field for missing field', () => { + const instance = shallow( + + ); + + expect(instance.find(FormRow).prop('isInvalid')).toBe(true); + }); + + it('should show invalid sort field for non-date field', () => { + const instance = shallow( + + ); + + expect(instance.find(FormRow).prop('isInvalid')).toBe(true); + }); }); }); diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx index b508534a19800..337ec8052d0ed 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx @@ -69,7 +69,7 @@ const supportedTypes = new Set([ 'date_range', ]); -function getInvalidSortFieldMessage( +function getInvalidSortFieldMessages( sortField: string, columnId: string, indexPattern?: IndexPattern @@ -226,7 +226,7 @@ export const lastValueOperation: OperationDefinition< const column = layer.columns[columnId] as LastValueIndexPatternColumn; return [ ...getInvalidFieldMessage(layer, columnId, indexPattern), - ...getInvalidSortFieldMessage(column.params.sortField, columnId, indexPattern), + ...getInvalidSortFieldMessages(column.params.sortField, columnId, indexPattern), ...getColumnReducedTimeRangeError(layer, columnId, indexPattern), ]; }, @@ -331,11 +331,8 @@ export const lastValueOperation: OperationDefinition< }); const dateFields = getDateFields(indexPattern); - const isSortFieldInvalid = !!getInvalidSortFieldMessage( - currentColumn.params.sortField, - '', - indexPattern - ); + const isSortFieldInvalid = + getInvalidSortFieldMessages(currentColumn.params.sortField, '', indexPattern).length > 0; const usingTopValues = Object.keys(layer.columns).some( (_columnId) => layer.columns[_columnId].operationType === 'terms' From 318f1532904fd9f14cc9291d3813278f005bd5ee Mon Sep 17 00:00:00 2001 From: Jill Guyonnet Date: Thu, 6 Jun 2024 15:18:29 +0100 Subject: [PATCH 045/122] [IUI] Add unprivilieged agent install instruction (#184845) ## Summary Closes https://github.com/elastic/ingest-dev/issues/3356 This PR adds a sentence to the `Add agent` flyout to instruct how to install an unprivileged Elastic Agent. Screenshot 2024-06-05 at 16 53 13 --- .../install_section.tsx | 2 ++ .../unprivileged_info.tsx | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 x-pack/plugins/fleet/public/components/enrollment_instructions/unprivileged_info.tsx diff --git a/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx b/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx index 372f81ca47f96..b94291e48663a 100644 --- a/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx +++ b/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx @@ -15,6 +15,7 @@ import type { K8sMode, CloudSecurityIntegration } from '../agent_enrollment_flyo import { PlatformSelector } from '../platform_selector'; import { RootPrivilegesCallout } from './root_privileges_callout'; +import { UnprivilegedInfo } from './unprivileged_info'; interface Props { installCommand: CommandsByPlatform; @@ -43,6 +44,7 @@ export const InstallSection: React.FunctionComponent = ({ <> + { + return ( + <> + +

+ --unprivileged, + command: sudo ./elastic-agent, + }} + /> +

+
+ + + ); +}; From 15424370e167f7377e3b1a93fd40e03c4639e95e Mon Sep 17 00:00:00 2001 From: elena-shostak <165678770+elena-shostak@users.noreply.github.com> Date: Thu, 6 Jun 2024 16:23:56 +0200 Subject: [PATCH 046/122] [Spaces] Support for query params in next route when entering space (#184858) ## Summary Added support for query params in next route when entering space. ### 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 ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) __Fixes: https://github.com/elastic/kibana/issues/184857__ --- x-pack/plugins/spaces/server/routes/views/index.test.ts | 7 +++++++ x-pack/plugins/spaces/server/routes/views/index.ts | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/spaces/server/routes/views/index.test.ts b/x-pack/plugins/spaces/server/routes/views/index.test.ts index 6c035a5694fe4..ad4cd61029af1 100644 --- a/x-pack/plugins/spaces/server/routes/views/index.test.ts +++ b/x-pack/plugins/spaces/server/routes/views/index.test.ts @@ -198,6 +198,13 @@ describe('Enter Space view routes', () => { }, expectedLocation: '/mock-server-basepath/app/management/kibana/home', }, + { + query: { + next: '/app/management/kibana/objects?initialQuery=type:(visualization)', + }, + expectedLocation: + '/mock-server-basepath/app/management/kibana/objects?initialQuery=type:(visualization)', + }, ]) { const request = httpServerMock.createKibanaRequest({ query, diff --git a/x-pack/plugins/spaces/server/routes/views/index.ts b/x-pack/plugins/spaces/server/routes/views/index.ts index 73fa47338dd76..495e0132059be 100644 --- a/x-pack/plugins/spaces/server/routes/views/index.ts +++ b/x-pack/plugins/spaces/server/routes/views/index.ts @@ -42,11 +42,11 @@ export function initSpacesViewsRoutes(deps: ViewRouteDeps) { const route = nextCandidateRoute === '/' ? defaultRoute : nextCandidateRoute; // need to get reed of ../../ to make sure we will not be out of space basePath - const normalizedRoute = new URL(route, 'https://localhost').pathname; + const normalizedRoute = new URL(route, 'https://localhost'); return response.redirected({ headers: { - location: `${basePath}${normalizedRoute}`, + location: `${basePath}${normalizedRoute.pathname}${normalizedRoute.search}`, }, }); } catch (e) { From 620359f893912189cc9e4d51d635879778b55d6a Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Thu, 6 Jun 2024 16:36:02 +0200 Subject: [PATCH 047/122] [APM] Trace sample performance improvements (#183802) Fixes #178985 ## Summary This PR changes the frontend logic to render the trace waterfall component. Instead of recursively rendering transactions/spans and their child transactions/spans, which causes high memory usage depending on the amount of data/how complex the trace to be rendered is, it now uses tree data structure and BFS/DFS algorithms. Besides that, the trace sample component can render a very long list. To avoid rendering too many elements in the DOM, this PR changes it to use a virtual list ### Memory consumption 15-minutes worth of data | before | after | |-------|-------| |image|image| 30-minutes worth of data | before | after | |-------|-------| |image|image| 1-hour worth of data | before | after | |-------|-------| |image|image| ### Extra Sticky header fix https://github.com/elastic/kibana/assets/2767137/632485ee-80c5-486d-aaa2-c34047b9c11e ### How to test The best way to test is to connect to an oblt cluster - Navigate to APM > Dependencies - Go into `cartService` - Click on `Operations` tab and click on `POST /nodejs/addToCart` operation. - Select different date ranges and services ### For reviewers There is a problem with positioning the trace elements in the grid when rendering data for large date ranges https://github.com/elastic/kibana/issues/178985#issuecomment-2137480777. This won't be addressed in this PR --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../src/lib/apm/apm_error.ts | 11 +- .../src/lib/apm/mobile_device.ts | 4 +- .../src/lib/utils/generate_id.ts | 31 +- .../test/scenarios/01_simple_trace.test.ts | 67 ++- .../01_simple_trace.test.ts.snap | 180 ++++---- .../cypress/e2e/errors/error_details.cy.ts | 4 +- .../large_traces_in_waterfall.cy.ts | 8 +- .../index.tsx | 58 ++- .../trace_explorer_waterfall.tsx | 93 ++-- .../distribution/index.tsx | 28 +- .../waterfall_with_summary/index.tsx | 20 +- .../waterfall/accordion_waterfall.tsx | 228 +++++---- .../waterfall/context/use_waterfall.tsx | 13 + .../waterfall/context/waterfall_context.tsx | 118 +++++ .../waterfall_container/waterfall/index.tsx | 134 +++--- .../waterfall_helpers.test.ts | 436 +++++++++++++----- .../waterfall_helpers/waterfall_helpers.ts | 203 +++++++- .../waterfall/waterfall_item.tsx | 4 +- .../__snapshots__/timeline.test.tsx.snap | 354 +++++++++++++- .../shared/charts/timeline/index.tsx | 54 ++- .../shared/charts/timeline/plot_utils.ts | 3 - .../shared/charts/timeline/timeline.test.tsx | 25 +- .../shared/charts/timeline/timeline_axis.tsx | 7 +- .../shared/charts/timeline/vertical_lines.tsx | 10 +- 24 files changed, 1591 insertions(+), 502 deletions(-) create mode 100644 x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/context/use_waterfall.tsx create mode 100644 x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/context/waterfall_context.tsx diff --git a/packages/kbn-apm-synthtrace-client/src/lib/apm/apm_error.ts b/packages/kbn-apm-synthtrace-client/src/lib/apm/apm_error.ts index 216397f1e1b40..250375623dfc3 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/apm/apm_error.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/apm/apm_error.ts @@ -8,7 +8,7 @@ import { ApmFields } from './apm_fields'; import { Serializable } from '../serializable'; -import { generateLongId, generateShortId } from '../utils/generate_id'; +import { generateLongIdWithSeed, generateShortId, generateLongId } from '../utils/generate_id'; export class ApmError extends Serializable { constructor(fields: ApmFields) { @@ -21,10 +21,13 @@ export class ApmError extends Serializable { } serialize() { + const errorMessage = + this.fields['error.grouping_name'] || this.fields['error.exception']?.[0]?.message; + const [data] = super.serialize(); - data['error.grouping_key'] = generateLongId( - this.fields['error.grouping_name'] || this.fields['error.exception']?.[0]?.message - ); + data['error.grouping_key'] = errorMessage + ? generateLongIdWithSeed(errorMessage) + : generateLongId(); return [data]; } diff --git a/packages/kbn-apm-synthtrace-client/src/lib/apm/mobile_device.ts b/packages/kbn-apm-synthtrace-client/src/lib/apm/mobile_device.ts index b0ea0aea4663e..205cc7d07f14f 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/apm/mobile_device.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/apm/mobile_device.ts @@ -11,7 +11,7 @@ import { Span } from './span'; import { Transaction } from './transaction'; import { Event } from './event'; import { ApmApplicationMetricFields, ApmFields, GeoLocation, SpanParams } from './apm_fields'; -import { generateLongId } from '../utils/generate_id'; +import { generateLongIdWithSeed, generateLongId } from '../utils/generate_id'; import { Metricset } from './metricset'; import { ApmError } from './apm_error'; @@ -259,7 +259,7 @@ export class MobileDevice extends Entity { return new ApmError({ ...this.fields, 'error.type': 'crash', - 'error.id': generateLongId(message), + 'error.id': generateLongIdWithSeed(message), 'error.exception': [{ message, ...{ type: 'crash' } }], 'error.grouping_name': groupingName || message, }); diff --git a/packages/kbn-apm-synthtrace-client/src/lib/utils/generate_id.ts b/packages/kbn-apm-synthtrace-client/src/lib/utils/generate_id.ts index c65c2843ddd3b..6815b79ef5cf8 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/utils/generate_id.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/utils/generate_id.ts @@ -7,16 +7,33 @@ */ let seq = 0; +const pid = String(process.pid); -function generateId(seed?: string, length: number = 32) { - const str = seed ?? String(seq++); - return str.padStart(length, '0'); +const LONG_ID_LENGTH = 32; +const SHORT_ID_LENGTH = 16; + +function generateId(length: number = LONG_ID_LENGTH) { + const id = String(seq++); + const generatedId = pid + id.padStart(length - pid.length, '0'); + if (generatedId.length > length) { + throw new Error(`generated id is longer than ${length} characters: ${generatedId.length}`); + } + + return generatedId; +} + +function generateIdWithSeed(seed: string, length: number = LONG_ID_LENGTH) { + return seed?.padStart(length, '0'); +} + +export function generateShortId() { + return generateId(SHORT_ID_LENGTH); } -export function generateShortId(seed?: string) { - return generateId(seed, 16); +export function generateLongId() { + return generateId(LONG_ID_LENGTH); } -export function generateLongId(seed?: string) { - return generateId(seed, 32); +export function generateLongIdWithSeed(seed: string) { + return generateIdWithSeed(seed, LONG_ID_LENGTH); } diff --git a/packages/kbn-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts b/packages/kbn-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts index 5c12116163721..df512cc6a8a4f 100644 --- a/packages/kbn-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts +++ b/packages/kbn-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts @@ -48,7 +48,24 @@ describe('simple trace', () => { // TODO this is not entirely factual, since id's are generated of a global sequence number it('generates the same data every time', () => { - expect(events).toMatchSnapshot(); + expect(events).toMatchSnapshot( + events.map((event) => { + const matchers: Record = {}; + if (event['transaction.id']) { + matchers['transaction.id'] = expect.any(String); + } + if (event['trace.id']) { + matchers['trace.id'] = expect.any(String); + } + if (event['span.id']) { + matchers['span.id'] = expect.any(String); + } + if (event['parent.id']) { + matchers['parent.id'] = expect.any(String); + } + return matchers; + }) + ); }); it('generates 15 transaction events', () => { @@ -83,9 +100,9 @@ describe('simple trace', () => { 'service.name': 'opbeans-java', 'service.node.name': 'instance-1', 'timestamp.us': 1609459200000000, - 'trace.id': '00000000000000000000000000000241', + 'trace.id': expect.stringContaining('00000000000000000000000241'), 'transaction.duration.us': 1000000, - 'transaction.id': '0000000000000240', + 'transaction.id': expect.stringContaining('0000000240'), 'transaction.name': 'GET /api/product/list', 'transaction.type': 'request', 'transaction.sampled': true, @@ -95,26 +112,28 @@ describe('simple trace', () => { it('outputs span events', () => { const [, span] = events; - expect(span).toEqual({ - '@timestamp': 1609459200050, - 'agent.name': 'java', - 'container.id': 'instance-1', - 'event.outcome': 'success', - 'host.name': 'instance-1', - 'parent.id': '0000000000000300', - 'processor.event': 'span', - 'processor.name': 'transaction', - 'service.environment': 'production', - 'service.name': 'opbeans-java', - 'service.node.name': 'instance-1', - 'span.duration.us': 900000, - 'span.id': '0000000000000302', - 'span.name': 'GET apm-*/_search', - 'span.subtype': 'elasticsearch', - 'span.type': 'db', - 'timestamp.us': 1609459200050000, - 'trace.id': '00000000000000000000000000000301', - 'transaction.id': '0000000000000300', - }); + expect(span).toEqual( + expect.objectContaining({ + '@timestamp': 1609459200050, + 'agent.name': 'java', + 'container.id': 'instance-1', + 'event.outcome': 'success', + 'host.name': 'instance-1', + 'parent.id': expect.stringContaining('0000000300'), + 'processor.event': 'span', + 'processor.name': 'transaction', + 'service.environment': 'production', + 'service.name': 'opbeans-java', + 'service.node.name': 'instance-1', + 'span.duration.us': 900000, + 'span.id': expect.stringContaining('0000000302'), + 'span.name': 'GET apm-*/_search', + 'span.subtype': 'elasticsearch', + 'span.type': 'db', + 'timestamp.us': 1609459200050000, + 'trace.id': expect.stringContaining('00000000000000000000000301'), + 'transaction.id': expect.stringContaining('0000000300'), + }) + ); }); }); diff --git a/packages/kbn-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap b/packages/kbn-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap index 15883c2711f43..f318942f397b3 100644 --- a/packages/kbn-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap +++ b/packages/kbn-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap @@ -14,9 +14,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459200000000, - "trace.id": "00000000000000000000000000000001", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000000", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -27,20 +27,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000000", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000002", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459200050000, - "trace.id": "00000000000000000000000000000001", - "transaction.id": "0000000000000000", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459200000, @@ -95,9 +95,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459260000000, - "trace.id": "00000000000000000000000000000005", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000004", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -108,20 +108,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000004", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000006", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459260050000, - "trace.id": "00000000000000000000000000000005", - "transaction.id": "0000000000000004", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459260000, @@ -176,9 +176,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459320000000, - "trace.id": "00000000000000000000000000000009", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000008", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -189,20 +189,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000008", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000010", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459320050000, - "trace.id": "00000000000000000000000000000009", - "transaction.id": "0000000000000008", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459320000, @@ -257,9 +257,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459380000000, - "trace.id": "00000000000000000000000000000013", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000012", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -270,20 +270,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000012", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000014", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459380050000, - "trace.id": "00000000000000000000000000000013", - "transaction.id": "0000000000000012", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459380000, @@ -338,9 +338,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459440000000, - "trace.id": "00000000000000000000000000000017", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000016", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -351,20 +351,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000016", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000018", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459440050000, - "trace.id": "00000000000000000000000000000017", - "transaction.id": "0000000000000016", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459440000, @@ -419,9 +419,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459500000000, - "trace.id": "00000000000000000000000000000021", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000020", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -432,20 +432,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000020", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000022", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459500050000, - "trace.id": "00000000000000000000000000000021", - "transaction.id": "0000000000000020", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459500000, @@ -500,9 +500,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459560000000, - "trace.id": "00000000000000000000000000000025", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000024", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -513,20 +513,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000024", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000026", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459560050000, - "trace.id": "00000000000000000000000000000025", - "transaction.id": "0000000000000024", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459560000, @@ -581,9 +581,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459620000000, - "trace.id": "00000000000000000000000000000029", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000028", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -594,20 +594,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000028", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000030", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459620050000, - "trace.id": "00000000000000000000000000000029", - "transaction.id": "0000000000000028", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459620000, @@ -662,9 +662,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459680000000, - "trace.id": "00000000000000000000000000000033", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000032", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -675,20 +675,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000032", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000034", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459680050000, - "trace.id": "00000000000000000000000000000033", - "transaction.id": "0000000000000032", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459680000, @@ -743,9 +743,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459740000000, - "trace.id": "00000000000000000000000000000037", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000036", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -756,20 +756,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000036", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000038", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459740050000, - "trace.id": "00000000000000000000000000000037", - "transaction.id": "0000000000000036", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459740000, @@ -824,9 +824,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459800000000, - "trace.id": "00000000000000000000000000000041", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000040", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -837,20 +837,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000040", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000042", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459800050000, - "trace.id": "00000000000000000000000000000041", - "transaction.id": "0000000000000040", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459800000, @@ -905,9 +905,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459860000000, - "trace.id": "00000000000000000000000000000045", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000044", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -918,20 +918,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000044", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000046", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459860050000, - "trace.id": "00000000000000000000000000000045", - "transaction.id": "0000000000000044", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459860000, @@ -986,9 +986,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459920000000, - "trace.id": "00000000000000000000000000000049", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000048", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -999,20 +999,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000048", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000050", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459920050000, - "trace.id": "00000000000000000000000000000049", - "transaction.id": "0000000000000048", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459920000, @@ -1067,9 +1067,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609459980000000, - "trace.id": "00000000000000000000000000000053", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000052", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -1080,20 +1080,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000052", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000054", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609459980050000, - "trace.id": "00000000000000000000000000000053", - "transaction.id": "0000000000000052", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609459980000, @@ -1148,9 +1148,9 @@ Array [ "service.name": "opbeans-java", "service.node.name": "instance-1", "timestamp.us": 1609460040000000, - "trace.id": "00000000000000000000000000000057", + "trace.id": Any, "transaction.duration.us": 1000000, - "transaction.id": "0000000000000056", + "transaction.id": Any, "transaction.name": "GET /api/product/list", "transaction.sampled": true, "transaction.type": "request", @@ -1161,20 +1161,20 @@ Array [ "container.id": "instance-1", "event.outcome": "success", "host.name": "instance-1", - "parent.id": "0000000000000056", + "parent.id": Any, "processor.event": "span", "processor.name": "transaction", "service.environment": "production", "service.name": "opbeans-java", "service.node.name": "instance-1", "span.duration.us": 900000, - "span.id": "0000000000000058", + "span.id": Any, "span.name": "GET apm-*/_search", "span.subtype": "elasticsearch", "span.type": "db", "timestamp.us": 1609460040050000, - "trace.id": "00000000000000000000000000000057", - "transaction.id": "0000000000000056", + "trace.id": Any, + "transaction.id": Any, }, Object { "@timestamp": 1609460040000, diff --git a/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/errors/error_details.cy.ts b/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/errors/error_details.cy.ts index e61762629a537..31030036c1ae1 100644 --- a/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/errors/error_details.cy.ts +++ b/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/errors/error_details.cy.ts @@ -6,7 +6,7 @@ */ import { getErrorGroupingKey } from '@kbn/apm-synthtrace-client/src/lib/apm/instance'; -import { generateLongId } from '@kbn/apm-synthtrace-client/src/lib/utils/generate_id'; +import { generateLongIdWithSeed } from '@kbn/apm-synthtrace-client/src/lib/utils/generate_id'; import url from 'url'; import { synthtrace } from '../../../synthtrace'; @@ -71,7 +71,7 @@ describe('Error details', () => { }); describe('when error has data', () => { - const errorGroupingKey = generateLongId('Error 1'); + const errorGroupingKey = generateLongIdWithSeed('Error 1'); const errorGroupingKeyShort = errorGroupingKey.slice(0, 5); const errorDetailsPageHref = url.format({ pathname: `/app/apm/services/opbeans-java/errors/${errorGroupingKey}`, diff --git a/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/transaction_details/large_trace_in_waterfall/large_traces_in_waterfall.cy.ts b/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/transaction_details/large_trace_in_waterfall/large_traces_in_waterfall.cy.ts index 5f40687274fb5..915ea4de95bc8 100644 --- a/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/transaction_details/large_trace_in_waterfall/large_traces_in_waterfall.cy.ts +++ b/x-pack/plugins/observability_solution/apm/ftr_e2e/cypress/e2e/transaction_details/large_trace_in_waterfall/large_traces_in_waterfall.cy.ts @@ -42,7 +42,9 @@ describe('Large Trace in waterfall', () => { }); it('renders waterfall items', () => { - cy.getByTestSubj('waterfallItem').should('have.length.greaterThan', 200); + // it renders a virtual list, so the number of items rendered is not the same as the number of items in the trace + cy.getByTestSubj('waterfallItem').should('have.length.at.least', 39); + cy.getByTestSubj('waterfall').should('have.css', 'height').and('eq', '10011px'); }); it('shows warning about trace size', () => { @@ -70,7 +72,9 @@ describe('Large Trace in waterfall', () => { }); it('renders waterfall items', () => { - cy.getByTestSubj('waterfallItem').should('have.length.greaterThan', 400); + // it renders a virtual list, so the number of items rendered is not the same as the number of items in the trace + cy.getByTestSubj('waterfallItem').should('have.length.at.least', 39); + cy.getByTestSubj('waterfall').should('have.css', 'height').and('eq', '10011px'); }); it('does not show the warning about trace size', () => { diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/dependency_operation_detail_view/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/dependency_operation_detail_view/index.tsx index 6505ed7697290..63a7bf42c6650 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/dependency_operation_detail_view/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/dependency_operation_detail_view/index.tsx @@ -7,7 +7,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { omit, orderBy } from 'lodash'; -import React, { useEffect, useMemo, useRef } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context'; import { useApmParams } from '../../../hooks/use_apm_params'; @@ -20,6 +20,7 @@ import { ResettingHeightRetainer } from '../../shared/height_retainer/resetting_ import { push, replace } from '../../shared/links/url_helpers'; import { useWaterfallFetcher } from '../transaction_details/use_waterfall_fetcher'; import { WaterfallWithSummary } from '../transaction_details/waterfall_with_summary'; +import { TransactionTab } from '../transaction_details/waterfall_with_summary/transaction_tabs'; import { DependencyOperationDistributionChart } from './dependency_operation_distribution_chart'; import { DetailViewHeader } from './detail_view_header'; import { maybeRedirectToAvailableSpanSample } from './maybe_redirect_to_available_span_sample'; @@ -115,9 +116,37 @@ export function DependencyOperationDetailView() { const isWaterfallLoading = spanFetch.status === FETCH_STATUS.NOT_INITIATED || (spanFetch.status === FETCH_STATUS.LOADING && samples.length === 0) || - waterfallFetch.status === FETCH_STATUS.LOADING || - !waterfallFetch.waterfall.entryWaterfallTransaction; + (waterfallFetch.status === FETCH_STATUS.LOADING && + !waterfallFetch.waterfall.entryWaterfallTransaction); + const onSampleClick = useCallback( + (sample: any) => { + push(history, { query: { spanId: sample.spanId } }); + }, + [history] + ); + + const onTabClick = useCallback( + (nextDetailTab: TransactionTab) => { + push(history, { + query: { + detailTab: nextDetailTab, + }, + }); + }, + [history] + ); + + const onShowCriticalPathChange = useCallback( + (nextShowCriticalPath: boolean) => { + push(history, { + query: { + showCriticalPath: nextShowCriticalPath ? 'true' : 'false', + }, + }); + }, + [history] + ); return ( @@ -147,31 +176,18 @@ export function DependencyOperationDetailView() { { - push(history, { query: { spanId: sample.spanId } }); - }} - onTabClick={(tab) => { - push(history, { - query: { - detailTab: tab, - }, - }); - }} + onSampleClick={onSampleClick} + onTabClick={onTabClick} serviceName={waterfallFetch.waterfall.entryWaterfallTransaction?.doc.service.name} waterfallItemId={waterfallItemId} detailTab={detailTab} selectedSample={selectedSample || null} showCriticalPath={showCriticalPath} - onShowCriticalPathChange={(nextShowCriticalPath) => { - push(history, { - query: { - showCriticalPath: nextShowCriticalPath ? 'true' : 'false', - }, - }); - }} + onShowCriticalPathChange={onShowCriticalPathChange} /> diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/trace_explorer/trace_explorer_waterfall.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/trace_explorer/trace_explorer_waterfall.tsx index 3a65c865f574c..1bda6985e534e 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/trace_explorer/trace_explorer_waterfall.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/trace_explorer/trace_explorer_waterfall.tsx @@ -4,14 +4,17 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useEffect } from 'react'; +import { FETCH_STATUS } from '@kbn/observability-shared-plugin/public'; +import React, { useCallback, useEffect } from 'react'; import { useHistory } from 'react-router-dom'; import { useApmParams } from '../../../hooks/use_apm_params'; import { useTimeRange } from '../../../hooks/use_time_range'; import { useTraceExplorerSamples } from '../../../hooks/use_trace_explorer_samples'; +import { ResettingHeightRetainer } from '../../shared/height_retainer/resetting_height_container'; import { push, replace } from '../../shared/links/url_helpers'; import { useWaterfallFetcher } from '../transaction_details/use_waterfall_fetcher'; import { WaterfallWithSummary } from '../transaction_details/waterfall_with_summary'; +import { TransactionTab } from '../transaction_details/waterfall_with_summary/transaction_tabs'; export function TraceExplorerWaterfall() { const history = useHistory(); @@ -52,39 +55,61 @@ export function TraceExplorerWaterfall() { end, }); + const onSampleClick = useCallback( + (sample: any) => { + push(history, { + query: { + traceId: sample.traceId, + transactionId: sample.transactionId, + waterfallItemId: '', + }, + }); + }, + [history] + ); + + const onTabClick = useCallback( + (nextDetailTab: TransactionTab) => { + push(history, { + query: { + detailTab: nextDetailTab, + }, + }); + }, + [history] + ); + + const onShowCriticalPathChange = useCallback( + (nextShowCriticalPath: boolean) => { + push(history, { + query: { + showCriticalPath: nextShowCriticalPath ? 'true' : 'false', + }, + }); + }, + [history] + ); + + const isWaterfallLoading = + waterfallFetchResult.status === FETCH_STATUS.LOADING && + !waterfallFetchResult.waterfall.entryWaterfallTransaction; + return ( - { - push(history, { - query: { - traceId: sample.traceId, - transactionId: sample.transactionId, - waterfallItemId: '', - }, - }); - }} - onTabClick={(nextDetailTab) => { - push(history, { - query: { - detailTab: nextDetailTab, - }, - }); - }} - detailTab={detailTab} - waterfallItemId={waterfallItemId} - serviceName={waterfallFetchResult.waterfall.entryWaterfallTransaction?.doc.service.name} - showCriticalPath={showCriticalPath} - onShowCriticalPathChange={(nextShowCriticalPath) => { - push(history, { - query: { - showCriticalPath: nextShowCriticalPath ? 'true' : 'false', - }, - }); - }} - /> + + + ); } diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/distribution/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/distribution/index.tsx index 31c989169f26f..f7a976b3cc82d 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/distribution/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/distribution/index.tsx @@ -92,6 +92,20 @@ export function TransactionDistribution({ [history] ); + const onSampleClick = useCallback( + (sample: { transactionId: string; traceId: string }) => { + history.push({ + ...history.location, + search: fromQuery({ + ...toQuery(history.location.search), + transactionId: sample.transactionId, + traceId: sample.traceId, + }), + }); + }, + [history] + ); + return (
@@ -111,21 +125,13 @@ export function TransactionDistribution({ { - history.push({ - ...history.location, - search: fromQuery({ - ...toQuery(history.location.search), - transactionId: sample.transactionId, - traceId: sample.traceId, - }), - }); - }} + onSampleClick={onSampleClick} onTabClick={onTabClick} serviceName={serviceName} waterfallItemId={waterfallItemId} detailTab={detailTab as TransactionTab | undefined} - waterfallFetchResult={waterfallFetchResult} + waterfallFetchResult={waterfallFetchResult.waterfall} + waterfallFetchStatus={waterfallFetchResult.status} traceSamplesFetchStatus={traceSamplesFetchResult.status} traceSamples={traceSamplesFetchResult.data?.traceSamples} showCriticalPath={showCriticalPath} diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx index c4008570f5c0b..4c52c2df57432 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx @@ -25,9 +25,10 @@ import { FETCH_STATUS } from '../../../../hooks/use_fetcher'; import { WaterfallFetchResult } from '../use_waterfall_fetcher'; interface Props { - waterfallFetchResult: WaterfallFetchResult; + waterfallFetchResult: WaterfallFetchResult['waterfall']; traceSamples?: TSample[]; traceSamplesFetchStatus: FETCH_STATUS; + waterfallFetchStatus: FETCH_STATUS; environment: Environment; onSampleClick: (sample: TSample) => void; onTabClick: (tab: TransactionTab) => void; @@ -41,6 +42,7 @@ interface Props { export function WaterfallWithSummary({ waterfallFetchResult, + waterfallFetchStatus, traceSamples, traceSamplesFetchStatus, environment, @@ -58,12 +60,12 @@ export function WaterfallWithSummary({ const isControlled = selectedSample !== undefined; const isLoading = - waterfallFetchResult.status === FETCH_STATUS.LOADING || + waterfallFetchStatus === FETCH_STATUS.LOADING || traceSamplesFetchStatus === FETCH_STATUS.LOADING; // When traceId is not present, call to waterfallFetchResult will not be initiated const isSucceded = - (waterfallFetchResult.status === FETCH_STATUS.SUCCESS || - waterfallFetchResult.status === FETCH_STATUS.NOT_INITIATED) && + (waterfallFetchStatus === FETCH_STATUS.SUCCESS || + waterfallFetchStatus === FETCH_STATUS.NOT_INITIATED) && traceSamplesFetchStatus === FETCH_STATUS.SUCCESS; useEffect(() => { @@ -86,7 +88,7 @@ export function WaterfallWithSummary({ : 0 : sampleActivePage; - const { entryTransaction } = waterfallFetchResult.waterfall; + const { entryTransaction } = waterfallFetchResult; if (!entryTransaction && traceSamples?.length === 0 && isSucceded) { return ( @@ -136,7 +138,7 @@ export function WaterfallWithSummary({ @@ -153,8 +155,8 @@ export function WaterfallWithSummary({ ) : ( @@ -167,7 +169,7 @@ export function WaterfallWithSummary({ serviceName={serviceName} waterfallItemId={waterfallItemId} onTabClick={onTabClick} - waterfall={waterfallFetchResult.waterfall} + waterfall={waterfallFetchResult} isLoading={isLoading} showCriticalPath={showCriticalPath} onShowCriticalPathChange={onShowCriticalPathChange} diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx index c807731057594..d0197f23d5fd5 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx @@ -15,20 +15,24 @@ import { EuiToolTip, } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { groupBy } from 'lodash'; import { transparentize } from 'polished'; -import React, { useState } from 'react'; +import React, { useEffect, useRef } from 'react'; +import { WindowScroller, AutoSizer } from 'react-virtualized'; +import { areEqual, ListChildComponentProps, VariableSizeList as List } from 'react-window'; import { asBigNumber } from '../../../../../../../common/utils/formatters'; -import { getCriticalPath } from '../../../../../../../common/critical_path/get_critical_path'; import { useTheme } from '../../../../../../hooks/use_theme'; import { Margins } from '../../../../../shared/charts/timeline'; -import { IWaterfall, IWaterfallSpanOrTransaction } from './waterfall_helpers/waterfall_helpers'; +import { + IWaterfallNodeFlatten, + IWaterfall, + IWaterfallSpanOrTransaction, +} from './waterfall_helpers/waterfall_helpers'; import { WaterfallItem } from './waterfall_item'; +import { WaterfallContextProvider } from './context/waterfall_context'; +import { useWaterfallContext } from './context/use_waterfall'; interface AccordionWaterfallProps { isOpen: boolean; - item: IWaterfallSpanOrTransaction; - level: number; duration: IWaterfall['duration']; waterfallItemId?: string; waterfall: IWaterfall; @@ -38,24 +42,27 @@ interface AccordionWaterfallProps { maxLevelOpen: number; } -const ACCORDION_HEIGHT = '48px'; +type WaterfallProps = Omit< + AccordionWaterfallProps, + 'item' | 'maxLevelOpen' | 'showCriticalPath' | 'waterfall' | 'isOpen' +>; + +interface WaterfallNodeProps extends WaterfallProps { + node: IWaterfallNodeFlatten; +} + +const ACCORDION_HEIGHT = 48; const StyledAccordion = euiStyled(EuiAccordion).withConfig({ - shouldForwardProp: (prop) => !['childrenCount', 'marginLeftLevel', 'hasError'].includes(prop), + shouldForwardProp: (prop) => !['marginLeftLevel', 'hasError'].includes(prop), })< EuiAccordionProps & { - childrenCount: number; marginLeftLevel: number; hasError: boolean; } >` - .waterfall_accordion { - border-top: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; - } - .euiAccordion__childWrapper { - transition: none; - } + border-top: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; ${(props) => { const borderLeft = props.hasError @@ -63,7 +70,7 @@ const StyledAccordion = euiStyled(EuiAccordion).withConfig({ : `1px solid ${props.theme.eui.euiColorLightShade};`; return `.button_${props.id} { width: 100%; - height: ${ACCORDION_HEIGHT}; + height: ${ACCORDION_HEIGHT}px; margin-left: ${props.marginLeftLevel}px; border-left: ${borderLeft} &:hover { @@ -78,111 +85,166 @@ const StyledAccordion = euiStyled(EuiAccordion).withConfig({ } `; -export function AccordionWaterfall(props: AccordionWaterfallProps) { - const { - item, - level, - duration, - waterfall, - waterfallItemId, - timelineMargins, - onClickWaterfallItem, - showCriticalPath, - maxLevelOpen, - } = props; - const theme = useTheme(); +export function AccordionWaterfall({ + maxLevelOpen, + showCriticalPath, + waterfall, + isOpen, + ...props +}: AccordionWaterfallProps) { + return ( + + + + ); +} - const [isOpen, setIsOpen] = useState(props.isOpen); +function Waterfall(props: WaterfallProps) { + const listRef = useRef(null); + const rowSizeMapRef = useRef(new Map()); + const { traceList } = useWaterfallContext(); - let children = waterfall.childrenByParentId[item.id] || []; + const onRowLoad = (index: number, size: number) => { + rowSizeMapRef.current.set(index, size); + }; - const criticalPath = showCriticalPath ? getCriticalPath(waterfall) : undefined; + const getRowSize = (index: number) => { + // adds 1px for the border top + return rowSizeMapRef.current.get(index) || ACCORDION_HEIGHT + 1; + }; - const criticalPathSegmentsById = groupBy(criticalPath?.segments, (segment) => segment.item.id); + const onScroll = ({ scrollTop }: { scrollTop: number }) => { + listRef.current?.scrollTo(scrollTop); + }; - let displayedColor = item.color; + return ( + + {({ registerChild }) => ( + + {({ width }) => ( +
+ + {VirtualRow} + +
+ )} +
+ )} +
+ ); +} - if (showCriticalPath) { - children = children.filter((child) => criticalPathSegmentsById[child.id]?.length); - displayedColor = transparentize(0.5, item.color); - } +const VirtualRow = React.memo( + ({ + index, + style, + data, + }: ListChildComponentProps< + Omit & { + traceList: IWaterfallNodeFlatten[]; + onLoad: (index: number, size: number) => void; + } + >) => { + const { onLoad, traceList, ...props } = data; - const errorCount = waterfall.getErrorCount(item.id); + const ref = React.useRef(null); + useEffect(() => { + onLoad(index, ref.current?.getBoundingClientRect().height ?? ACCORDION_HEIGHT); + }, [index, onLoad]); - // To indent the items creating the parent/child tree - const marginLeftLevel = 8 * level; + return ( +
+ +
+ ); + }, + areEqual +); - function toggleAccordion() { - setIsOpen((isCurrentOpen) => !isCurrentOpen); - } +const WaterfallNode = React.memo((props: WaterfallNodeProps) => { + const theme = useTheme(); + const { duration, waterfallItemId, onClickWaterfallItem, timelineMargins, node } = props; + const { criticalPathSegmentsById, getErrorCount, updateTreeNode, showCriticalPath } = + useWaterfallContext(); - const hasToggle = !!children.length; + const displayedColor = showCriticalPath ? transparentize(0.5, node.item.color) : node.item.color; + const marginLeftLevel = 8 * node.level; + const hasToggle = !!node.childrenToLoad; + const errorCount = getErrorCount(node.item.id); + + const segments = criticalPathSegmentsById[node.item.id] + ?.filter((segment) => segment.self) + .map((segment) => ({ + id: segment.item.id, + color: theme.eui.euiColorAccent, + left: (segment.offset - node.item.offset - node.item.skew) / node.item.duration, + width: segment.duration / node.item.duration, + })); + + const toggleAccordion = () => { + updateTreeNode({ ...node, expanded: !node.expanded }); + }; + + const onWaterfallItemClick = (flyoutDetailTab: string) => { + onClickWaterfallItem(node.item, flyoutDetailTab); + }; return ( + { - onClickWaterfallItem(item, flyoutDetailTab); - }} - segments={criticalPathSegmentsById[item.id] - ?.filter((segment) => segment.self) - .map((segment) => ({ - color: theme.eui.euiColorAccent, - left: (segment.offset - item.offset - item.skew) / item.duration, - width: segment.duration / item.duration, - }))} + onClick={onWaterfallItemClick} + segments={segments} /> } arrowDisplay="none" - initialIsOpen={true} - forceState={isOpen ? 'open' : 'closed'} + initialIsOpen + forceState={node.expanded ? 'open' : 'closed'} onToggle={toggleAccordion} - > - {isOpen && - children.map((child) => ( - level} - level={level + 1} - item={child} - /> - ))} - + /> ); -} +}); function ToggleAccordionButton({ show, @@ -206,7 +268,7 @@ function ToggleAccordionButton({ display: 'flex', }} > - + {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
; + showCriticalPath: boolean; + traceList: IWaterfallNodeFlatten[]; + getErrorCount: (waterfallItemId: string) => number; + updateTreeNode: (newTree: IWaterfallNodeFlatten) => void; + } & Pick +>({ + criticalPathSegmentsById: {} as Dictionary, + showCriticalPath: false, + traceList: [], + getErrorCount: () => 0, + updateTreeNode: () => undefined, +}); + +export function WaterfallContextProvider({ + showCriticalPath, + waterfall, + maxLevelOpen, + children, + isOpen, +}: PropsWithChildren) { + const [tree, setTree] = useState(null); + const criticalPathSegmentsById = useMemo(() => { + if (!showCriticalPath) { + return {}; + } + + const criticalPath = getCriticalPath(waterfall); + return groupBy(criticalPath.segments, (segment) => segment.item.id); + }, [showCriticalPath, waterfall]); + + const traceList = useMemo(() => { + return convertTreeToList(tree); + }, [tree]); + + const getErrorCount = useCallback( + (waterfallItemId) => waterfall.getErrorCount(waterfallItemId), + [waterfall] + ); + + const updateTreeNode = useCallback( + (updatedNode: IWaterfallNodeFlatten) => { + if (!tree) return; + + const newTree = updateTraceTreeNode({ + root: tree, + updatedNode, + waterfall, + path: { + criticalPathSegmentsById, + showCriticalPath, + }, + }); + + if (newTree) { + setTree(newTree); + } + }, + [criticalPathSegmentsById, showCriticalPath, tree, waterfall] + ); + + useEffect(() => { + const root = buildTraceTree({ + waterfall, + maxLevelOpen, + isOpen, + path: { + criticalPathSegmentsById, + showCriticalPath, + }, + }); + + setTree(root); + }, [criticalPathSegmentsById, isOpen, maxLevelOpen, showCriticalPath, waterfall]); + + return ( + + {children} + + ); +} diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx index 54ff6f86fb734..dbdc877742e1c 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx @@ -11,7 +11,12 @@ import { History } from 'history'; import React, { useMemo, useState } from 'react'; import { useHistory } from 'react-router-dom'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { Timeline } from '../../../../../shared/charts/timeline'; +import { css } from '@emotion/react'; +import { useTheme } from '../../../../../../hooks/use_theme'; +import { + VerticalLinesContainer, + TimelineAxisContainer, +} from '../../../../../shared/charts/timeline'; import { fromQuery, toQuery } from '../../../../../shared/links/url_helpers'; import { getAgentMarks } from '../marks/get_agent_marks'; import { getErrorMarks } from '../marks/get_error_marks'; @@ -22,7 +27,6 @@ import { IWaterfall, IWaterfallItem } from './waterfall_helpers/waterfall_helper const Container = euiStyled.div` transition: 0.1s padding ease; position: relative; - overflow: hidden; `; const toggleFlyout = ({ @@ -59,35 +63,35 @@ function getWaterfallMaxLevel(waterfall: IWaterfall) { if (!entryId) { return 0; } + let maxLevel = 1; - function countLevels(id: string, currentLevel: number) { + const visited = new Set(); + const queue: Array<{ id: string; level: number }> = [{ id: entryId, level: 1 }]; + + while (queue.length > 0) { + const { id, level } = queue.shift()!; const children = waterfall.childrenByParentId[id] || []; - if (children.length) { - children.forEach((child) => { - // Skip processing when a child node has the same ID as its parent - // to prevent infinite loop - if (child.id !== id) { - countLevels(child.id, currentLevel + 1); - } - }); - } else { - if (maxLevel < currentLevel) { - maxLevel = currentLevel; + + maxLevel = Math.max(maxLevel, level); + visited.add(id); + + children.forEach((child) => { + if (child.id !== id && !visited.has(child.id)) { + queue.push({ id: child.id, level: level + 1 }); + visited.add(child.id); } - } + }); } - countLevels(entryId, 1); return maxLevel; } -// level starts with 0 -const maxLevelOpen = 2; + +const MAX_DEPTH_OPEN_LIMIT = 2; export function Waterfall({ waterfall, waterfallItemId, showCriticalPath }: Props) { const history = useHistory(); + const theme = useTheme(); const [isAccordionOpen, setIsAccordionOpen] = useState(true); - const itemContainerHeight = 58; // TODO: This is a nasty way to calculate the height of the svg element. A better approach should be found - const waterfallHeight = itemContainerHeight * waterfall.items.length; const { duration } = waterfall; @@ -124,47 +128,59 @@ export function Waterfall({ waterfall, waterfallItemId, showCriticalPath }: Prop })} /> )} -
-
- { - setIsAccordionOpen((isOpen) => !isOpen); - }} - /> - -
- - {!waterfall.entryWaterfallTransaction ? null : ( - - toggleFlyout({ history, item, flyoutDetailTab }) - } - showCriticalPath={showCriticalPath} - maxLevelOpen={ - waterfall.traceDocsTotal > 500 ? maxLevelOpen : waterfall.traceDocsTotal - } - /> - )} - + +
+ { + setIsAccordionOpen((isOpen) => !isOpen); + }} + /> +
+ + + {!waterfall.entryWaterfallTransaction ? null : ( + + toggleFlyout({ history, item, flyoutDetailTab }) + } + showCriticalPath={showCriticalPath} + maxLevelOpen={ + waterfall.traceDocsTotal > 500 ? MAX_DEPTH_OPEN_LIMIT : waterfall.traceDocsTotal + } + /> + )} + + { - describe('getWaterfall', () => { - const hits = [ - { - processor: { event: 'transaction' }, - trace: { id: 'myTraceId' }, - service: { name: 'opbeans-node' }, - transaction: { - duration: { us: 49660 }, - name: 'GET /api', - id: 'myTransactionId1', - }, - timestamp: { us: 1549324795784006 }, - } as Transaction, - { - parent: { id: 'mySpanIdA' }, - processor: { event: 'span' }, - trace: { id: 'myTraceId' }, - service: { name: 'opbeans-ruby' }, - transaction: { id: 'myTransactionId2' }, - timestamp: { us: 1549324795825633 }, - span: { - duration: { us: 481 }, - name: 'SELECT FROM products', - id: 'mySpanIdB', - }, - } as Span, - { - parent: { id: 'myTransactionId2' }, - processor: { event: 'span' }, - trace: { id: 'myTraceId' }, - service: { name: 'opbeans-ruby' }, - transaction: { id: 'myTransactionId2' }, - span: { - duration: { us: 6161 }, - name: 'Api::ProductsController#index', - id: 'mySpanIdA', - }, - timestamp: { us: 1549324795824504 }, - } as Span, - { - parent: { id: 'mySpanIdA' }, - processor: { event: 'span' }, - trace: { id: 'myTraceId' }, - service: { name: 'opbeans-ruby' }, - transaction: { id: 'myTransactionId2' }, - span: { - duration: { us: 532 }, - name: 'SELECT FROM product', - id: 'mySpanIdC', - }, - timestamp: { us: 1549324795827905 }, - } as Span, - { - parent: { id: 'myTransactionId1' }, - processor: { event: 'span' }, - trace: { id: 'myTraceId' }, - service: { name: 'opbeans-node' }, - transaction: { id: 'myTransactionId1' }, - span: { - duration: { us: 47557 }, - name: 'GET opbeans-ruby:3000/api/products', - id: 'mySpanIdD', - }, - timestamp: { us: 1549324795785760 }, - } as Span, - { - parent: { id: 'mySpanIdD' }, - processor: { event: 'transaction' }, - trace: { id: 'myTraceId' }, - service: { name: 'opbeans-ruby' }, - transaction: { - duration: { us: 8634 }, - name: 'Api::ProductsController#index', - id: 'myTransactionId2', - marks: { - agent: { - domInteractive: 382, - domComplete: 383, - timeToFirstByte: 14, - }, - }, - }, - timestamp: { us: 1549324795823304 }, - } as unknown as Transaction, - ]; - const errorDocs = [ - { - processor: { event: 'error' }, - parent: { id: 'myTransactionId1' }, - timestamp: { us: 1549324795810000 }, - trace: { id: 'myTraceId' }, - transaction: { id: 'myTransactionId1' }, - error: { - id: 'error1', - grouping_key: 'errorGroupingKey1', - log: { - message: 'error message', + const hits = [ + { + processor: { event: 'transaction' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-node' }, + transaction: { + duration: { us: 49660 }, + name: 'GET /api', + id: 'myTransactionId1', + }, + timestamp: { us: 1549324795784006 }, + } as Transaction, + { + parent: { id: 'mySpanIdA' }, + processor: { event: 'span' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-ruby' }, + transaction: { id: 'myTransactionId2' }, + timestamp: { us: 1549324795825633 }, + span: { + duration: { us: 481 }, + name: 'SELECT FROM products', + id: 'mySpanIdB', + }, + } as Span, + { + parent: { id: 'myTransactionId2' }, + processor: { event: 'span' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-ruby' }, + transaction: { id: 'myTransactionId2' }, + span: { + duration: { us: 6161 }, + name: 'Api::ProductsController#index', + id: 'mySpanIdA', + }, + timestamp: { us: 1549324795824504 }, + } as Span, + { + parent: { id: 'mySpanIdA' }, + processor: { event: 'span' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-ruby' }, + transaction: { id: 'myTransactionId2' }, + span: { + duration: { us: 532 }, + name: 'SELECT FROM product', + id: 'mySpanIdC', + }, + timestamp: { us: 1549324795827905 }, + } as Span, + { + parent: { id: 'myTransactionId1' }, + processor: { event: 'span' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-node' }, + transaction: { id: 'myTransactionId1' }, + span: { + duration: { us: 47557 }, + name: 'GET opbeans-ruby:3000/api/products', + id: 'mySpanIdD', + }, + timestamp: { us: 1549324795785760 }, + } as Span, + { + parent: { id: 'mySpanIdD' }, + processor: { event: 'transaction' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-ruby' }, + transaction: { + duration: { us: 8634 }, + name: 'Api::ProductsController#index', + id: 'myTransactionId2', + marks: { + agent: { + domInteractive: 382, + domComplete: 383, + timeToFirstByte: 14, }, }, - service: { name: 'opbeans-ruby' }, - agent: { - name: 'ruby', - version: '2', + }, + timestamp: { us: 1549324795823304 }, + } as unknown as Transaction, + ]; + const errorDocs = [ + { + processor: { event: 'error' }, + parent: { id: 'myTransactionId1' }, + timestamp: { us: 1549324795810000 }, + trace: { id: 'myTraceId' }, + transaction: { id: 'myTransactionId1' }, + error: { + id: 'error1', + grouping_key: 'errorGroupingKey1', + log: { + message: 'error message', }, - } as unknown as APMError, - ]; + }, + service: { name: 'opbeans-ruby' }, + agent: { + name: 'ruby', + version: '2', + }, + } as unknown as APMError, + ]; + describe('getWaterfall', () => { it('should return full waterfall', () => { const apiResp = { traceItems: { @@ -750,4 +755,229 @@ describe('waterfall_helpers', () => { expect(getOrphanTraceItemsCount(traceItems)).toBe(1); }); }); + + describe('#trace tree', () => { + const waterfall = getWaterfall({ + traceItems: { + traceDocs: hits, + errorDocs, + exceedsMax: false, + spanLinksCountById: {}, + traceDocsTotal: hits.length, + maxTraceItems: 5000, + }, + entryTransaction: { + processor: { event: 'transaction' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-node' }, + transaction: { + duration: { us: 49660 }, + name: 'GET /api', + id: 'myTransactionId1', + }, + timestamp: { us: 1549324795784006 }, + } as Transaction, + }); + + const tree: IWaterfallNode = { + id: 'myTransactionId1', + item: { + docType: 'transaction', + doc: { + agent: { name: 'nodejs' }, + processor: { event: 'transaction' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-node' }, + transaction: { + duration: { us: 49660 }, + name: 'GET /api', + id: 'myTransactionId1', + type: 'request', + }, + timestamp: { us: 1549324795784006 }, + }, + id: 'myTransactionId1', + duration: 49660, + offset: 0, + skew: 0, + legendValues: { serviceName: 'opbeans-node', spanType: '' }, + color: '', + spanLinksCount: { linkedParents: 0, linkedChildren: 0 }, + }, + children: [ + { + id: '0-mySpanIdD-0', + item: { + docType: 'span', + doc: { + agent: { name: 'nodejs' }, + parent: { id: 'myTransactionId1' }, + processor: { event: 'span' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-node' }, + transaction: { id: 'myTransactionId1' }, + span: { + duration: { us: 47557 }, + name: 'GET opbeans-ruby:3000/api/products', + id: 'mySpanIdD', + type: 'request', + }, + timestamp: { us: 1549324795785760 }, + }, + id: 'mySpanIdD', + parentId: 'myTransactionId1', + duration: 47557, + offset: 1754, + skew: 0, + legendValues: { serviceName: 'opbeans-node', spanType: '' }, + color: '', + spanLinksCount: { linkedParents: 0, linkedChildren: 0 }, + }, + children: [], + childrenToLoad: 1, + level: 1, + expanded: false, + hasInitializedChildren: false, + }, + ], + level: 0, + childrenToLoad: 1, + expanded: true, + hasInitializedChildren: true, + }; + + describe('buildTraceTree', () => { + it('should build the trace tree correctly', () => { + const result = buildTraceTree({ + waterfall, + path: { + criticalPathSegmentsById: {}, + showCriticalPath: false, + }, + maxLevelOpen: 1, + isOpen: true, + }); + + expect(result).toEqual( + expect.objectContaining({ + item: expect.objectContaining({ id: 'myTransactionId1' }), + level: 0, + expanded: true, + hasInitializedChildren: true, + }) + ); + + expect(result?.children[0]).toEqual( + expect.objectContaining({ + item: expect.objectContaining({ id: 'mySpanIdD' }), + level: 1, + expanded: false, + childrenToLoad: 1, + children: [], + hasInitializedChildren: false, + }) + ); + }); + }); + + describe('convertTreeToList', () => { + it('should convert the trace tree to a list correctly', () => { + const result = convertTreeToList(tree); + + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + item: expect.objectContaining({ id: 'myTransactionId1' }), + level: 0, + expanded: true, + hasInitializedChildren: true, + childrenToLoad: 1, + }), + expect.objectContaining({ + item: expect.objectContaining({ id: 'mySpanIdD' }), + level: 1, + expanded: false, + hasInitializedChildren: false, + childrenToLoad: 1, + }), + ]) + ); + }); + }); + + describe('updateTraceTreeNode', () => { + it('should update the "mySpanIdD" node setting "expanded" to true', () => { + const updatedNode: IWaterfallNodeFlatten = { + id: '0-mySpanIdD-0', + item: { + docType: 'span', + doc: { + agent: { name: 'nodejs' }, + parent: { id: 'myTransactionId1' }, + processor: { event: 'span' }, + trace: { id: 'myTraceId' }, + service: { name: 'opbeans-node' }, + transaction: { id: 'myTransactionId1' }, + span: { + duration: { us: 47557 }, + name: 'GET opbeans-ruby:3000/api/products', + id: 'mySpanIdD', + type: 'request', + }, + timestamp: { us: 1549324795785760 }, + }, + id: 'mySpanIdD', + parentId: 'myTransactionId1', + duration: 47557, + offset: 1754, + skew: 0, + legendValues: { serviceName: 'opbeans-node', spanType: '' }, + color: '', + spanLinksCount: { linkedParents: 0, linkedChildren: 0 }, + }, + childrenToLoad: 1, + level: 1, + expanded: true, + hasInitializedChildren: false, + }; + + const result = updateTraceTreeNode({ + root: tree, + updatedNode, + waterfall, + path: { + criticalPathSegmentsById: {}, + showCriticalPath: false, + }, + }); + + expect(result).toEqual( + expect.objectContaining({ + item: expect.objectContaining({ id: 'myTransactionId1' }), + level: 0, + expanded: true, + hasInitializedChildren: true, + }) + ); + + expect(result?.children[0]).toEqual( + expect.objectContaining({ + item: expect.objectContaining({ id: 'mySpanIdD' }), + level: 1, + expanded: true, + hasInitializedChildren: true, + }) + ); + + expect(result?.children[0].children[0]).toEqual( + expect.objectContaining({ + item: expect.objectContaining({ id: 'myTransactionId2' }), + level: 2, + expanded: false, + hasInitializedChildren: false, + }) + ); + }); + }); + }); }); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.ts b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.ts index 4d96da07e42fe..b9a8f1d8cd15c 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.ts +++ b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.ts @@ -6,8 +6,9 @@ */ import { euiPaletteColorBlind } from '@elastic/eui'; -import { first, flatten, groupBy, isEmpty, sortBy, uniq } from 'lodash'; +import { Dictionary, first, flatten, groupBy, isEmpty, sortBy, uniq } from 'lodash'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { CriticalPathSegment } from '../../../../../../../../common/critical_path/types'; import type { APIReturnType } from '../../../../../../../services/rest/create_call_apm_api'; import type { Transaction } from '../../../../../../../../typings/es_schemas/ui/transaction'; import { @@ -93,6 +94,23 @@ export interface IWaterfallLegend { color: string; } +export interface IWaterfallNode { + id: string; + item: IWaterfallItem; + // children that are loaded + children: IWaterfallNode[]; + // total number of children that needs to be loaded + childrenToLoad: number; + // collapsed or expanded state + expanded: boolean; + // level in the tree + level: number; + // flag to indicate if children are loaded + hasInitializedChildren: boolean; +} + +export type IWaterfallNodeFlatten = Omit; + function getLegendValues(transactionOrSpan: WaterfallTransaction | WaterfallSpan) { return { [WaterfallLegendType.ServiceName]: transactionOrSpan.service.name, @@ -462,3 +480,186 @@ export function getWaterfall(apiResponse: TraceAPIResponse): IWaterfall { orphanTraceItemsCount, }; } + +function getChildren({ + path, + waterfall, + waterfallItemId, +}: { + waterfallItemId: string; + waterfall: IWaterfall; + path: { + criticalPathSegmentsById: Dictionary; + showCriticalPath: boolean; + }; +}) { + const children = waterfall.childrenByParentId[waterfallItemId] ?? []; + return path.showCriticalPath + ? children.filter((child) => path.criticalPathSegmentsById[child.id]?.length) + : children; +} + +function buildTree({ + root, + waterfall, + maxLevelOpen, + path, +}: { + root: IWaterfallNode; + waterfall: IWaterfall; + maxLevelOpen: number; + path: { + criticalPathSegmentsById: Dictionary; + showCriticalPath: boolean; + }; +}) { + const tree = { ...root }; + const queue: IWaterfallNode[] = [tree]; + + for (let queueIndex = 0; queueIndex < queue.length; queueIndex++) { + const node = queue[queueIndex]; + + const children = getChildren({ path, waterfall, waterfallItemId: node.item.id }); + + // Set childrenToLoad for all nodes enqueued. + // this allows lazy loading of child nodes + node.childrenToLoad = children.length; + + if (maxLevelOpen > node.level) { + children.forEach((child, index) => { + const level = node.level + 1; + + const currentNode: IWaterfallNode = { + id: `${level}-${child.id}-${index}`, + item: child, + children: [], + level, + expanded: level < maxLevelOpen, + childrenToLoad: 0, + hasInitializedChildren: false, + }; + + node.children.push(currentNode); + queue.push(currentNode); + }); + + node.hasInitializedChildren = true; + } + } + + return tree; +} + +export function buildTraceTree({ + waterfall, + maxLevelOpen, + isOpen, + path, +}: { + waterfall: IWaterfall; + maxLevelOpen: number; + isOpen: boolean; + path: { + criticalPathSegmentsById: Dictionary; + showCriticalPath: boolean; + }; +}): IWaterfallNode | null { + const entry = waterfall.entryWaterfallTransaction; + if (!entry) { + return null; + } + + const root: IWaterfallNode = { + id: entry.id, + item: entry, + children: [], + level: 0, + expanded: isOpen, + childrenToLoad: 0, + hasInitializedChildren: false, + }; + + return buildTree({ root, maxLevelOpen, waterfall, path }); +} + +export const convertTreeToList = (root: IWaterfallNode | null): IWaterfallNodeFlatten[] => { + if (!root) { + return []; + } + + const result: IWaterfallNodeFlatten[] = []; + const stack: IWaterfallNode[] = [root]; + + while (stack.length > 0) { + const node = stack.pop()!; + + const { children, ...nodeWithoutChildren } = node; + result.push(nodeWithoutChildren); + + if (node.expanded) { + for (let i = node.children.length - 1; i >= 0; i--) { + stack.push(node.children[i]); + } + } + } + + return result; +}; + +export const updateTraceTreeNode = ({ + root, + updatedNode, + waterfall, + path, +}: { + root: IWaterfallNode; + updatedNode: IWaterfallNodeFlatten; + waterfall: IWaterfall; + path: { + criticalPathSegmentsById: Dictionary; + showCriticalPath: boolean; + }; +}) => { + if (!root) { + return; + } + + const tree = { ...root }; + const stack: Array<{ parent: IWaterfallNode | null; index: number; node: IWaterfallNode }> = [ + { parent: null, index: 0, node: root }, + ]; + + while (stack.length > 0) { + const { parent, index, node } = stack.pop()!; + + if (node.id === updatedNode.id) { + Object.assign(node, updatedNode); + + if (updatedNode.expanded && !updatedNode.hasInitializedChildren) { + Object.assign( + node, + buildTree({ + root: node, + waterfall, + maxLevelOpen: node.level + 1, // Only one level above the current node will be loaded + path, + }) + ); + } + + if (parent) { + parent.children[index] = node; + } else { + Object.assign(tree, node); + } + + return tree; + } + + for (let i = node.children.length - 1; i >= 0; i--) { + stack.push({ parent: node, index: i, node: node.children[i] }); + } + } + + return tree; +}; diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx index 6260c37ffdc5a..11d0f9bba9298 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx @@ -7,7 +7,7 @@ import { EuiBadge, EuiIcon, EuiText, EuiTitle, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { ReactNode, useRef, useState, useEffect } from 'react'; +import React, { ReactNode, useRef, useEffect, useState } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { useTheme } from '../../../../../../hooks/use_theme'; import { isMobileAgentName, isRumAgentName } from '../../../../../../../common/agent_name'; @@ -115,6 +115,7 @@ interface IWaterfallItemProps { errorCount: number; marginLeftLevel: number; segments?: Array<{ + id: string; left: number; width: number; color: string; @@ -267,6 +268,7 @@ export function WaterfallItem({ {segments?.map((segment) => ( +
+ + + + 0 μs + + + 200 μs + + + 400 μs + + + 600 μs + + + 800 μs + + + 1,000 μs + + + +
+ + .c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + font-size: 14px; + color: #69707d; + cursor: pointer; + opacity: 1; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.c1 { + width: 11px; + height: 11px; + margin-right: 0; + background: #98a2b3; + border-radius: 100%; +} + + +
+ +
+
+
+
+ + .c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + font-size: 14px; + color: #69707d; + cursor: pointer; + opacity: 1; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.c1 { + width: 11px; + height: 11px; + margin-right: 0; + background: #98a2b3; + border-radius: 100%; +} + + +
+ +
+
+
+
+ + .c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + font-size: 14px; + color: #69707d; + cursor: pointer; + opacity: 1; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.c1 { + width: 11px; + height: 11px; + margin-right: 0; + background: #98a2b3; + border-radius: 100%; +} + + +
+ +
+
+
+
+
+`; + +exports[`Timeline VerticalLinesContainer should render with data 1`] = `
+> + + + + + + + + + + + + + + +
`; diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/index.tsx index 8c3f4ab7104e4..8b0a966b91b44 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/index.tsx @@ -22,39 +22,59 @@ export interface Margins { left: number; } -interface TimelineProps { +export interface TimelineProps { marks?: Mark[]; xMin?: number; xMax?: number; - height: number; margins: Margins; - width?: number; } -function TimeLineContainer({ width, xMin, xMax, height, marks, margins }: TimelineProps) { - if (xMax == null || !width) { +export function TimelineAxisContainer({ xMax, xMin, margins, marks }: TimelineProps) { + const [width, setWidth] = useState(0); + if (xMax === undefined) { return null; } - const plotValues = getPlotValues({ width, xMin, xMax, height, margins }); - const topTraceDuration = xMax - (xMin ?? 0); return ( - <> - - - + setWidth(size.width)}> + {(resizeRef) => { + const plotValues = getPlotValues({ width, xMin, xMax, margins }); + const topTraceDuration = xMax - (xMin ?? 0); + return ( +
+ +
+ ); + }} +
); } -export function Timeline(props: TimelineProps) { +export function VerticalLinesContainer({ xMax, xMin, margins, marks }: TimelineProps) { const [width, setWidth] = useState(0); + if (xMax == null) { + return null; + } + return ( setWidth(size.width)}> - {(resizeRef) => ( -
- -
- )} + {(resizeRef) => { + const plotValues = getPlotValues({ width, xMin, xMax, margins }); + const topTraceDuration = xMax - (xMin ?? 0); + return ( +
+ +
+ ); + }}
); } diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/plot_utils.ts b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/plot_utils.ts index 67fdc04d6529c..a099c2c39313a 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/plot_utils.ts +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/plot_utils.ts @@ -14,13 +14,11 @@ export function getPlotValues({ width, xMin = 0, xMax, - height, margins, }: { width: number; xMin?: number; xMax: number; - height: number; margins: Margins; }) { const xScale = scaleLinear() @@ -28,7 +26,6 @@ export function getPlotValues({ .range([margins.left, width - margins.right]); return { - height, margins, tickValues: xScale.ticks(7), width, diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline.test.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline.test.tsx index 82483f609a469..e6b9d30000229 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline.test.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline.test.tsx @@ -12,10 +12,10 @@ import { mockMoment, toJson, } from '../../../../utils/test_helpers'; -import { Timeline } from '.'; +import { TimelineAxisContainer, TimelineProps, VerticalLinesContainer } from '.'; import { AgentMark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks'; -describe('Timeline', () => { +describe.each([[TimelineAxisContainer], [VerticalLinesContainer]])(`Timeline`, (Component) => { let consoleMock: jest.SpyInstance; beforeAll(() => { @@ -27,19 +27,15 @@ describe('Timeline', () => { consoleMock.mockRestore(); }); - it('should render with data', () => { - const props = { - traceRootDuration: 200000, - width: 1000, - duration: 200000, - height: 116, + it(`${Component.name} should render with data`, () => { + const props: TimelineProps = { + xMax: 1000, margins: { top: 100, left: 50, right: 50, bottom: 0, }, - animation: null, marks: [ { id: 'timeToFirstByte', @@ -62,17 +58,14 @@ describe('Timeline', () => { ] as AgentMark[], }; - const wrapper = mountWithTheme(); + const wrapper = mountWithTheme(); expect(toJson(wrapper)).toMatchSnapshot(); }); - it('should not crash if traceRootDuration is 0', () => { - const props = { - traceRootDuration: 0, - width: 1000, + it(`${Component.name} should not crash if traceRootDuration is 0`, () => { + const props: TimelineProps = { xMax: 0, - height: 116, margins: { top: 100, left: 50, @@ -81,7 +74,7 @@ describe('Timeline', () => { }, }; - const mountTimeline = () => mountWithTheme(); + const mountTimeline = () => mountWithTheme(); expect(mountTimeline).not.toThrow(); }); diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline_axis.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline_axis.tsx index 766008d0c623f..96bc7da552f90 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline_axis.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/timeline_axis.tsx @@ -6,7 +6,7 @@ */ import { inRange } from 'lodash'; -import React, { ReactNode } from 'react'; +import React from 'react'; import { getDurationFormatter } from '../../../../../common/utils/formatters'; import { useTheme } from '../../../../hooks/use_theme'; import { Mark } from '.'; @@ -30,7 +30,6 @@ const getXAxisTickValues = (tickValues: number[], topTraceDuration?: number) => }; interface TimelineAxisProps { - header?: ReactNode; plotValues: PlotValues; marks?: Mark[]; topTraceDuration: number; @@ -54,11 +53,7 @@ export function TimelineAxis({ plotValues, marks = [], topTraceDuration }: Timel return (
diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/vertical_lines.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/vertical_lines.tsx index 60e89e6b0075f..96ab6a51e49f3 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/vertical_lines.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/timeline/vertical_lines.tsx @@ -17,7 +17,7 @@ interface VerticalLinesProps { } export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: VerticalLinesProps) { - const { width, height, margins, tickValues, xScale } = plotValues; + const { width, margins, tickValues, xScale } = plotValues; const markTimes = marks.filter((mark) => mark.verticalLine).map(({ offset }) => offset); @@ -38,7 +38,7 @@ export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: Vert return ( ))} @@ -62,7 +62,7 @@ export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: Vert x1={position} x2={position} y1={0} - y2={height} + y2="100%" stroke={theme.eui.euiColorMediumShade} /> ))} @@ -72,7 +72,7 @@ export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: Vert x1={topTraceDurationPosition} x2={topTraceDurationPosition} y1={0} - y2={height} + y2="100%" stroke={theme.eui.euiColorMediumShade} /> )} From 7897e42016806a7f445fdfdae4a3b2ff84b08829 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 6 Jun 2024 10:46:14 -0400 Subject: [PATCH 048/122] [Observability Onboarding] Update copy to be stateful/serverless agnostic (#184867) ## Summary Resolves #183469. Simple change to update the copy so it will work for both Stateful and Serverless versions of Kibana. --- .../public/application/header/header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/application/header/header.tsx b/x-pack/plugins/observability_solution/observability_onboarding/public/application/header/header.tsx index e05c8cfdd0be2..79789525c8318 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/public/application/header/header.tsx +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/application/header/header.tsx @@ -27,7 +27,7 @@ export const Header = () => { 'xpack.observability_onboarding.experimentalOnboardingFlow.startIngestingDataIntoTextLabel', { defaultMessage: - 'Start ingesting data into your Observability project. Return to this page at any time by clicking Add data.', + 'Start ingesting Observability data into Elastic. Return to this page at any time by clicking Add data.', } )} From 202b9eea377a9417f25db0b19ede952dd9b561a8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 08:08:40 -0700 Subject: [PATCH 049/122] Update dependency @elastic/elasticsearch to ^8.13.1 (main) (#184863) --- package.json | 2 +- .../server/service/knowledge_base_service/index.ts | 1 - x-pack/plugins/security/common/model/api_key.ts | 2 +- yarn.lock | 12 ++++++------ 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index ed541c789626d..f8b779401c0b0 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "@elastic/charts": "65.2.0", "@elastic/datemath": "5.0.3", "@elastic/ecs": "^8.11.1", - "@elastic/elasticsearch": "^8.13.0", + "@elastic/elasticsearch": "^8.13.1", "@elastic/ems-client": "8.5.1", "@elastic/eui": "94.6.0", "@elastic/filesaver": "1.1.2", diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts index 8281c9b5fba07..1f9ad5bc936f8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts @@ -91,7 +91,6 @@ export class KnowledgeBaseService { input: { field_names: ['text_field'], }, - // @ts-expect-error wait_for_completion: true, }, { requestTimeout: '20m' } diff --git a/x-pack/plugins/security/common/model/api_key.ts b/x-pack/plugins/security/common/model/api_key.ts index 91b144cdc4326..639cf6568c709 100644 --- a/x-pack/plugins/security/common/model/api_key.ts +++ b/x-pack/plugins/security/common/model/api_key.ts @@ -113,5 +113,5 @@ interface BaseQueryApiKeyResult { canManageApiKeys: boolean; canManageOwnApiKeys: boolean; aggregationTotal: number; - aggregations: Record | undefined; + aggregations: Record | undefined; } diff --git a/yarn.lock b/yarn.lock index 4f691866a05af..181a7fe9a4c6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1707,12 +1707,12 @@ "@elastic/transport" "^8.3.1" tslib "^2.4.0" -"@elastic/elasticsearch@^8.13.0": - version "8.13.0" - resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.13.0.tgz#625c6fba3caf944370c6859482fbd5cf3543aea8" - integrity sha512-OAYgzqArPqgDaIJ1yT0RX31YCgr1lleo53zL+36i23PFjHu08CA6Uq+BmBzEV05yEidl+ILPdeSfF3G8hPG/JQ== +"@elastic/elasticsearch@^8.13.1": + version "8.13.1" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.13.1.tgz#0fbe8318cf7f21c599165bb901277428639d57ec" + integrity sha512-2G4Vu6OHw4+XTrp7AGIcOEezpPEoVrWg2JTK1v/exEKSLYquZkUdd+m4yOL3/UZ6bTj7hmXwrmYzW76BnLCkJQ== dependencies: - "@elastic/transport" "^8.4.0" + "@elastic/transport" "~8.4.1" tslib "^2.4.0" "@elastic/ems-client@8.5.1": @@ -1887,7 +1887,7 @@ undici "^5.21.2" yaml "^2.2.2" -"@elastic/transport@^8.3.1", "@elastic/transport@^8.4.0": +"@elastic/transport@^8.3.1", "@elastic/transport@~8.4.1": version "8.4.1" resolved "https://registry.yarnpkg.com/@elastic/transport/-/transport-8.4.1.tgz#f98c5a5e2156bcb3f01170b4aca7e7de4d8b61b8" integrity sha512-/SXVuVnuU5b4dq8OFY4izG+dmGla185PcoqgK6+AJMpmOeY1QYVNbWtCwvSvoAANN5D/wV+EBU8+x7Vf9EphbA== From c3c5744f3d57d9a290d9746926971a9a7f618d4e Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Thu, 6 Jun 2024 10:10:55 -0500 Subject: [PATCH 050/122] [EntSearch] standardize side nav header to search for all apps (#184773) ## Summary Fix to ensure the solution nav name is consistent for all Search pages. --- .../ai_search/components/layout/page_template.test.tsx | 2 +- .../ai_search/components/layout/page_template.tsx | 4 ++-- .../analytics/components/layout/page_template.tsx | 4 ++-- .../applications/components/layout/page_template.tsx | 4 ++-- .../elasticsearch/components/layout/page_template.test.tsx | 2 +- .../elasticsearch/components/layout/page_template.tsx | 4 ++-- .../components/layout/page_template.tsx | 4 ++-- .../components/layout/page_template.tsx | 4 ++-- .../search_experiences/components/layout/page_template.tsx | 4 ++-- .../vector_search/components/layout/page_template.test.tsx | 2 +- .../vector_search/components/layout/page_template.tsx | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.test.tsx b/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.test.tsx index e5cee004d6782..42a84efd0ccc4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.test.tsx @@ -28,7 +28,7 @@ describe('EnterpriseSearchAISearchPageTemplate', () => { ); expect(wrapper.type()).toEqual(EnterpriseSearchPageTemplateWrapper); - expect(wrapper.prop('solutionNav')).toEqual({ name: 'AI Search', items: [] }); + expect(wrapper.prop('solutionNav')).toEqual({ name: 'Search', items: [] }); expect(wrapper.find('.hello').text()).toEqual('world'); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.tsx index ec0c94b57455d..ea18568c29189 100644 --- a/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/ai_search/components/layout/page_template.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { AI_SEARCH_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { SetAiSearchChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; import { useEnterpriseSearchNav } from '../../../shared/layout'; @@ -23,7 +23,7 @@ export const EnterpriseSearchAISearchPageTemplate: React.FC = } diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/components/layout/page_template.tsx index 67180252e45d7..cf46363c23600 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/components/layout/page_template.tsx @@ -13,7 +13,7 @@ import useObservable from 'react-use/lib/useObservable'; import type { EuiSideNavItemTypeEnhanced } from '@kbn/core-chrome-browser'; -import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { generateEncodedPath } from '../../../shared/encode_path_params'; import { KibanaLogic } from '../../../shared/kibana'; import { SetAnalyticsChrome } from '../../../shared/kibana_chrome'; @@ -87,7 +87,7 @@ export const EnterpriseSearchAnalyticsPageTemplate: React.FC< {...pageTemplateProps} solutionNav={{ items: chromeStyle === 'classic' ? navItems : undefined, - name: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAME, + name: SEARCH_PRODUCT_NAME, }} setPageChrome={pageChrome && } > diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/page_template.tsx index f8f390b1785b8..ec745ce77be2f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/page_template.tsx @@ -13,7 +13,7 @@ import useObservable from 'react-use/lib/useObservable'; import type { EuiSideNavItemTypeEnhanced } from '@kbn/core-chrome-browser'; -import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { KibanaLogic } from '../../../shared/kibana'; import { SetEnterpriseSearchApplicationsChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; @@ -99,7 +99,7 @@ export const EnterpriseSearchApplicationsPageTemplate: React.FC< {...pageTemplateProps} solutionNav={{ items: chromeStyle === 'classic' ? navItems : undefined, - name: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAME, + name: SEARCH_PRODUCT_NAME, }} restrictWidth={restrictWidth} setPageChrome={pageChrome && } diff --git a/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.test.tsx b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.test.tsx index a6885bb8adc9c..99eba7d57b108 100644 --- a/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.test.tsx @@ -28,7 +28,7 @@ describe('EnterpriseSearchElasticsearchPageTemplate', () => { ); expect(wrapper.type()).toEqual(EnterpriseSearchPageTemplateWrapper); - expect(wrapper.prop('solutionNav')).toEqual({ name: 'Elasticsearch', items: [] }); + expect(wrapper.prop('solutionNav')).toEqual({ name: 'Search', items: [] }); expect(wrapper.find('.hello').text()).toEqual('world'); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.tsx index 81ba64913879e..7f2eded8a6565 100644 --- a/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/components/layout/page_template.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { ELASTICSEARCH_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { SetElasticsearchChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; import { useEnterpriseSearchNav } from '../../../shared/layout'; @@ -24,7 +24,7 @@ export const EnterpriseSearchElasticsearchPageTemplate: React.FC} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx index 0ff30a31ebd34..f1f271a5e0cf2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/page_template.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { SetEnterpriseSearchContentChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; import { useEnterpriseSearchNav } from '../../../shared/layout'; @@ -24,7 +24,7 @@ export const EnterpriseSearchContentPageTemplate: React.FC = {...pageTemplateProps} solutionNav={{ items: useEnterpriseSearchNav(), - name: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAME, + name: SEARCH_PRODUCT_NAME, }} setPageChrome={pageChrome && } > diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/page_template.tsx index 0929e81d02cbe..b3589189b9a55 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/page_template.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { SetSearchChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; import { useEnterpriseSearchNav } from '../../../shared/layout'; @@ -23,7 +23,7 @@ export const EnterpriseSearchOverviewPageTemplate: React.FC = } diff --git a/x-pack/plugins/enterprise_search/public/applications/search_experiences/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/search_experiences/components/layout/page_template.tsx index 704f9d06f3e19..11044fa04b956 100644 --- a/x-pack/plugins/enterprise_search/public/applications/search_experiences/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/search_experiences/components/layout/page_template.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { SetSearchExperiencesChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; import { useEnterpriseSearchNav } from '../../../shared/layout'; @@ -23,7 +23,7 @@ export const EnterpriseSearchSearchExperiencesPageTemplate: React.FC} diff --git a/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.test.tsx b/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.test.tsx index ab6585f5e6961..5f6fe605858bf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.test.tsx @@ -28,7 +28,7 @@ describe('EnterpriseSearchVectorSearchPageTemplate', () => { ); expect(wrapper.type()).toEqual(EnterpriseSearchPageTemplateWrapper); - expect(wrapper.prop('solutionNav')).toEqual({ items: [], name: 'Vector Search' }); + expect(wrapper.prop('solutionNav')).toEqual({ items: [], name: 'Search' }); expect(wrapper.find('.hello').text()).toEqual('world'); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.tsx index 44db21bb070d9..60b998958b6b2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/vector_search/components/layout/page_template.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { VECTOR_SEARCH_PLUGIN } from '../../../../../common/constants'; +import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants'; import { SetVectorSearchChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, @@ -26,7 +26,7 @@ export const EnterpriseSearchVectorSearchPageTemplate: React.FC} > From 966736e4b4d9db6caa9dd870e0bc5f9a8d7e3bef Mon Sep 17 00:00:00 2001 From: Cristina Amico Date: Thu, 6 Jun 2024 17:13:52 +0200 Subject: [PATCH 051/122] [Fleet] Add rate limiting to install by upload endpoint (#184036) Fixes https://github.com/elastic/ingest-dev/issues/3217 ## Summary Add rate limiting to "install by upload" endpoint. Implemented with a cache that is set with the timestamp of each install by upload, independently from the package name/version. If the time elapsed since the last timestamp it's less than retry time (10s), the endpoint will return `429 Too many requests`. ### Testing - Upload a package with ``` curl -XPOST -H 'content-type: application/zip' -H 'kbn-xsrf: true' http://localhost:5601/YOUR_PATH/api/fleet/epm/packages -u elastic:changeme --data-binary @PACKAGE_NAME.zip ``` - Upload another package shortly after. It can be the same one or another one, as the rate limiting is applied across all uploads, no matter the package name. - If the second upload happens <10s after the first one, should return error `429 Too Many Requests. Please wait 10s before uploading again.` ### Checklist - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/fleet/common/openapi/bundled.json | 3 ++ .../plugins/fleet/common/openapi/bundled.yaml | 2 + .../openapi/components/responses/error.yaml | 2 +- .../common/openapi/paths/epm@packages.yaml | 2 + .../plugins/fleet/server/errors/handlers.ts | 5 +++ x-pack/plugins/fleet/server/errors/index.ts | 2 +- .../fleet/server/routes/epm/handlers.ts | 21 +++++++++- .../services/epm/packages/install.test.ts | 16 ++++---- .../server/services/epm/packages/install.ts | 30 ++++++++++++++ .../server/services/epm/packages/utils.ts | 16 ++++++++ .../fleet_api_integration/apis/epm/file.ts | 2 + .../fleet_api_integration/apis/epm/get.ts | 39 +++++++++---------- .../apis/epm/install_bundled.ts | 6 +-- .../apis/epm/install_by_upload.ts | 35 ++++++++++++++++- .../apis/epm/remove_legacy_templates.ts | 4 +- .../apis/kibana/index.ts | 2 +- .../monitoring_api_integration/packages.ts | 4 +- 17 files changed, 148 insertions(+), 43 deletions(-) diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index 35ef539cfe299..62de596088edb 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -606,6 +606,9 @@ }, "400": { "$ref": "#/components/responses/error" + }, + "429": { + "$ref": "#/components/responses/error" } }, "operationId": "install-package-by-upload", diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 3f2745267a5d0..ac1d7b76979ff 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -392,6 +392,8 @@ paths: - items '400': $ref: '#/components/responses/error' + '429': + $ref: '#/components/responses/error' operationId: install-package-by-upload description: '' parameters: diff --git a/x-pack/plugins/fleet/common/openapi/components/responses/error.yaml b/x-pack/plugins/fleet/common/openapi/components/responses/error.yaml index 8199a81cb6b5a..0f0c54f1c3d38 100644 --- a/x-pack/plugins/fleet/common/openapi/components/responses/error.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/responses/error.yaml @@ -9,4 +9,4 @@ content: error: type: string message: - type: string \ No newline at end of file + type: string diff --git a/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml b/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml index f8b1ccaf46fe1..7eaf0b6584915 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml @@ -79,6 +79,8 @@ post: - items '400': $ref: ../components/responses/error.yaml + '429': + $ref: ../components/responses/error.yaml operationId: install-package-by-upload description: '' parameters: diff --git a/x-pack/plugins/fleet/server/errors/handlers.ts b/x-pack/plugins/fleet/server/errors/handlers.ts index fef8cd1872413..dfd92951c8919 100644 --- a/x-pack/plugins/fleet/server/errors/handlers.ts +++ b/x-pack/plugins/fleet/server/errors/handlers.ts @@ -43,6 +43,7 @@ import { PackagePolicyRequestError, FleetNotFoundError, PackageSavedObjectConflictError, + FleetTooManyRequestsError, } from '.'; type IngestErrorHandler = ( @@ -114,6 +115,10 @@ const getHTTPResponseCode = (error: FleetError): number => { if (error instanceof PackageUnsupportedMediaTypeError) { return 415; } + // Too many requests + if (error instanceof FleetTooManyRequestsError) { + return 429; + } // Internal Server Error if (error instanceof UninstallTokenError) { return 500; diff --git a/x-pack/plugins/fleet/server/errors/index.ts b/x-pack/plugins/fleet/server/errors/index.ts index 6a69581c11965..02c72a5d8a25e 100644 --- a/x-pack/plugins/fleet/server/errors/index.ts +++ b/x-pack/plugins/fleet/server/errors/index.ts @@ -44,7 +44,6 @@ export class PackageRemovalError extends FleetError {} export class PackageESError extends FleetError {} export class ConcurrentInstallOperationError extends FleetError {} export class PackageSavedObjectConflictError extends FleetError {} - export class KibanaSOReferenceError extends FleetError {} export class PackageAlreadyInstalledError extends FleetError {} @@ -81,6 +80,7 @@ export class FleetSetupError extends FleetError {} export class GenerateServiceTokenError extends FleetError {} export class FleetUnauthorizedError extends FleetError {} export class FleetNotFoundError extends FleetError {} +export class FleetTooManyRequestsError extends FleetError {} export class OutputUnauthorizedError extends FleetError {} export class OutputInvalidError extends FleetError {} diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts index e46b9d5b3445a..709bd7b362a9f 100644 --- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts @@ -65,7 +65,12 @@ import { getTemplateInputs, } from '../../services/epm/packages'; import type { BulkInstallResponse } from '../../services/epm/packages'; -import { defaultFleetErrorHandler, fleetErrorToResponseOptions, FleetError } from '../../errors'; +import { + defaultFleetErrorHandler, + fleetErrorToResponseOptions, + FleetError, + FleetTooManyRequestsError, +} from '../../errors'; import { appContextService, checkAllowedPackages } from '../../services'; import { getPackageUsageStats } from '../../services/epm/packages/get'; import { updatePackage } from '../../services/epm/packages/update'; @@ -80,6 +85,7 @@ import type { import { getDataStreams } from '../../services/epm/data_streams'; import { NamingCollisionError } from '../../services/epm/packages/custom_integrations/validation/check_naming_collision'; import { DatasetNamePrefixError } from '../../services/epm/packages/custom_integrations/validation/check_dataset_name_format'; +import { UPLOAD_RETRY_AFTER_MS } from '../../services/epm/packages/install'; const CACHE_CONTROL_10_MINUTES_HEADER: HttpResponseOptions['headers'] = { 'cache-control': 'max-age=600', @@ -451,7 +457,6 @@ export const installPackageByUploadHandler: FleetRequestHandler< const archiveBuffer = Buffer.from(request.body); const spaceId = fleetContext.spaceId; const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; - const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request, user?.username); const res = await installPackage({ @@ -475,6 +480,18 @@ export const installPackageByUploadHandler: FleetRequestHandler< }; return response.ok({ body }); } else { + if (res.error instanceof FleetTooManyRequestsError) { + return response.customError({ + statusCode: 429, + body: { + message: res.error.message, + }, + headers: { + // retry-after expects seconds + 'retry-after': Math.ceil(UPLOAD_RETRY_AFTER_MS / 1000).toString(), + }, + }); + } return defaultFleetErrorHandler({ error: res.error, response }); } }; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts index bbaa10728754b..14f3068795120 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.test.ts @@ -426,7 +426,6 @@ describe('install', () => { }); afterEach(() => { (install._installPackage as jest.Mock).mockClear(); - // jest.resetAllMocks(); }); afterAll(() => { jest.mocked(appContextService.getExperimentalFeatures).mockReturnValue({ @@ -834,10 +833,14 @@ describe('installAssetsForInputPackagePolicy', () => { describe('handleInstallPackageFailure', () => { const mockedLogger = jest.mocked(appContextService.getLogger()); + const savedObjectsClient = savedObjectsClientMock.create(); + beforeEach(() => { + mockedLogger.error.mockClear(); jest.mocked(install._installPackage).mockClear(); + mockGetBundledPackageByPkgKey.mockReset(); + jest.mocked(install._installPackage).mockResolvedValue({} as any); - mockedLogger.error.mockClear(); mockGetBundledPackageByPkgKey.mockResolvedValue(undefined); jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(true); jest.spyOn(Registry, 'splitPkgKey').mockImplementation((pkgKey: string) => { @@ -860,9 +863,7 @@ describe('handleInstallPackageFailure', () => { }); const pkgName = 'test_package'; - it('should do nothing if error is ', async () => { - const savedObjectsClient = savedObjectsClientMock.create(); - + it('should do nothing if error is ConcurrentInstallOperationError', async () => { const installedPkg: SavedObject = { id: 'test-package', references: [], @@ -893,8 +894,6 @@ describe('handleInstallPackageFailure', () => { }); it('Should rollback on upgrade on FleetError', async () => { - const savedObjectsClient = savedObjectsClientMock.create(); - const installedPkg: SavedObject = { id: 'test-package', references: [], @@ -933,11 +932,10 @@ describe('handleInstallPackageFailure', () => { }), }) ); + jest.mocked(getInstallationObject).mockReset(); }); it('Should update the installation status to: install_failed on rollback error', async () => { - const savedObjectsClient = savedObjectsClientMock.create(); - jest.mocked(install._installPackage).mockRejectedValue(new Error('test error')); const installedPkg: SavedObject = { diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index c5ce7e5f0eca8..9f200e97c3cfd 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -9,6 +9,7 @@ import apm from 'elastic-apm-node'; import { i18n } from '@kbn/i18n'; import semverLt from 'semver/functions/lt'; import type Boom from '@hapi/boom'; +import moment from 'moment'; import type { ElasticsearchClient, SavedObject, @@ -53,6 +54,7 @@ import { ConcurrentInstallOperationError, FleetUnauthorizedError, PackageNotFoundError, + FleetTooManyRequestsError, } from '../../../errors'; import { PACKAGES_SAVED_OBJECT_TYPE, MAX_TIME_COMPLETE_INSTALL } from '../../../constants'; import { dataStreamService, licenseService } from '../..'; @@ -89,7 +91,9 @@ import { checkDatasetsNameFormat } from './custom_integrations/validation/check_ import { addErrorToLatestFailedAttempts } from './install_errors_helpers'; import { installIndexTemplatesAndPipelines } from './install_index_template_pipeline'; import { optimisticallyAddEsAssetReferences } from './es_assets_reference'; +import { setLastUploadInstallCache, getLastUploadInstallCache } from './utils'; +export const UPLOAD_RETRY_AFTER_MS = 10000; // 10s const MAX_ENSURE_INSTALL_TIME = 60 * 1000; export async function isPackageInstalled(options: { @@ -361,6 +365,7 @@ interface InstallUploadedArchiveParams { ignoreMappingUpdateErrors?: boolean; skipDataStreamRollover?: boolean; isBundledPackage?: boolean; + skipRateLimitCheck?: boolean; } function getTelemetryEvent(pkgName: string, pkgVersion: string): PackageUpdateEvent { @@ -887,11 +892,33 @@ async function installPackageByUpload({ ignoreMappingUpdateErrors, skipDataStreamRollover, isBundledPackage, + skipRateLimitCheck, }: InstallUploadedArchiveParams): Promise { + const logger = appContextService.getLogger(); + // if an error happens during getInstallType, report that we don't know let installType: InstallType = 'unknown'; const installSource = isBundledPackage ? 'bundled' : 'upload'; + + const timeToWaitString = moment + .utc(moment.duration(UPLOAD_RETRY_AFTER_MS).asMilliseconds()) + .format('s[s]'); + try { + // Check cached timestamp for rate limiting + const lastInstalledBy = getLastUploadInstallCache(); + + if (lastInstalledBy && !skipRateLimitCheck) { + const msSinceLastFetched = Date.now() - (lastInstalledBy || 0); + if (msSinceLastFetched < UPLOAD_RETRY_AFTER_MS) { + logger.error( + `Install by Upload - Too many requests. Wait ${timeToWaitString} before uploading again.` + ); + throw new FleetTooManyRequestsError( + `Too many requests. Please wait ${timeToWaitString} before uploading again.` + ); + } + } const { packageInfo } = await generatePackageInfoFromArchiveBuffer(archiveBuffer, contentType); const pkgName = packageInfo.name; @@ -928,6 +955,8 @@ async function installPackageByUpload({ assetsMap, paths, }; + // update the timestamp of latest installation + setLastUploadInstallCache(); return await installPackageCommon({ packageInstallContext, @@ -1006,6 +1035,7 @@ export async function installPackage(args: InstallPackageParams): Promise = new Map(); + +export const setLastUploadInstallCache = () => { + const logger = appContextService.getLogger(); + const key = 'upload'; + const time = Date.now(); + logger.debug(`Setting timestamp ${time} to cache for install by ${key}`); + return lastInstalledByUpload.set(key, time); +}; + +export const getLastUploadInstallCache = () => { + return lastInstalledByUpload.get('upload'); +}; diff --git a/x-pack/test/fleet_api_integration/apis/epm/file.ts b/x-pack/test/fleet_api_integration/apis/epm/file.ts index db4c463acb96e..e44aa2f4e2634 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/file.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/file.ts @@ -21,6 +21,8 @@ export default function (providerContext: FtrProviderContext) { skipIfNoDockerRegistry(providerContext); describe('it gets files from registry', () => { it('fetches a .png screenshot image', async function () { + // wait 10s before uploading again to avoid getting 429 just in case a previous test was hitting the same endpoint + await new Promise((resolve) => setTimeout(resolve, 10000)); const res = await supertest .get('/api/fleet/epm/packages/filetest/0.1.0/img/screenshots/metricbeat_dashboard.png') .set('kbn-xsrf', 'xxx') diff --git a/x-pack/test/fleet_api_integration/apis/epm/get.ts b/x-pack/test/fleet_api_integration/apis/epm/get.ts index 7b79272bbef0b..c98bb318bdf41 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/get.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/get.ts @@ -40,6 +40,18 @@ export default function (providerContext: FtrProviderContext) { '../fixtures/direct_upload_packages/apache_0.1.4.zip' ); + async function uploadPackage(zipPackage: string) { + // wait 10s before uploading again to avoid getting 429 + await new Promise((resolve) => setTimeout(resolve, 10000)); + const buf = fs.readFileSync(zipPackage); + return await supertest + .post(`/api/fleet/epm/packages`) + .set('kbn-xsrf', 'xxxx') + .type('application/zip') + .send(buf) + .expect(200); + } + describe('EPM - get', () => { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); @@ -57,14 +69,9 @@ export default function (providerContext: FtrProviderContext) { expect(packageInfo.download).to.not.equal(undefined); await uninstallPackage(testPkgName, testPkgVersion); }); + it('returns correct package info if it was installed by upload', async function () { - const buf = fs.readFileSync(testPkgArchiveZip); - await supertest - .post(`/api/fleet/epm/packages`) - .set('kbn-xsrf', 'xxxx') - .type('application/zip') - .send(buf) - .expect(200); + await uploadPackage(testPkgArchiveZip); const res = await supertest .get(`/api/fleet/epm/packages/${testPkgName}/${testPkgVersion}`) @@ -76,14 +83,9 @@ export default function (providerContext: FtrProviderContext) { expect(packageInfo.download).to.not.equal(undefined); await uninstallPackage(testPkgName, testPkgVersion); }); + it('returns correct package info from registry if a different version is installed by upload', async function () { - const buf = fs.readFileSync(testPkgArchiveZip); - await supertest - .post(`/api/fleet/epm/packages`) - .set('kbn-xsrf', 'xxxx') - .type('application/zip') - .send(buf) - .expect(200); + await uploadPackage(testPkgArchiveZip); const res = await supertest.get(`/api/fleet/epm/packages/apache/0.1.3`).expect(200); const packageInfo = res.body.item; @@ -97,13 +99,7 @@ export default function (providerContext: FtrProviderContext) { path.dirname(__filename), '../fixtures/direct_upload_packages/apache_9999.0.0.zip' ); - const buf = fs.readFileSync(testPkgArchiveZipV9999); - await supertest - .post(`/api/fleet/epm/packages`) - .set('kbn-xsrf', 'xxxx') - .type('application/zip') - .send(buf) - .expect(200); + await uploadPackage(testPkgArchiveZipV9999); const res = await supertest.get(`/api/fleet/epm/packages/apache/9999.0.0`).expect(200); const packageInfo = res.body.item; @@ -111,6 +107,7 @@ export default function (providerContext: FtrProviderContext) { expect(packageInfo.download).to.equal(undefined); await uninstallPackage(testPkgName, '9999.0.0'); }); + describe('Installed Packages', () => { before(async () => { await installPackage(testPkgName, testPkgVersion); diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_bundled.ts b/x-pack/test/fleet_api_integration/apis/epm/install_bundled.ts index 4b91e8ac88e54..ffef558628804 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_bundled.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_bundled.ts @@ -56,7 +56,7 @@ export default function (providerContext: FtrProviderContext) { const supertest = getService('supertest'); const log = getService('log'); - describe('installing bundled packages', async () => { + describe('Installing bundled packages', async () => { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); @@ -89,7 +89,6 @@ export default function (providerContext: FtrProviderContext) { .type('application/json') .send({ force: true }) .expect(200); - expect(installResponse.body._meta.install_source).to.be('bundled'); const updateResponse = await supertest @@ -103,8 +102,6 @@ export default function (providerContext: FtrProviderContext) { }); it('should load package archive from bundled package', async () => { - await bundlePackage('nginx-1.2.1'); - const response = await supertest .get(`/api/fleet/epm/packages/nginx/1.2.1?full=true`) .expect(200); @@ -117,7 +114,6 @@ export default function (providerContext: FtrProviderContext) { describe('with registry', () => { it('allows for updating from registry when outdated package is installed from bundled source', async () => { await bundlePackage('nginx-1.1.0'); - const bundledInstallResponse = await supertest .post(`/api/fleet/epm/packages/nginx/1.1.0`) .set('kbn-xsrf', 'xxxx') diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts index 729a0b4cc5196..e7f3d1d3c0f66 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts @@ -16,6 +16,11 @@ import { skipIfNoDockerRegistry, isDockerRegistryEnabledOrSkipped } from '../../ import { setupFleetAndAgents } from '../agents/services'; import { testUsers } from '../test_users'; +/* + * This test takes long to execute because of the wait time between uploads + * The upload endpoint is rate limited with a minimum wait time of 10s + */ + export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); @@ -64,7 +69,7 @@ export default function (providerContext: FtrProviderContext) { await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); }; - describe('installs packages from direct upload', async () => { + describe('Installs packages from direct upload', async () => { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); @@ -77,6 +82,8 @@ export default function (providerContext: FtrProviderContext) { async function uploadPackage() { const buf = fs.readFileSync(testPkgArchiveTgz); + // wait 10s before uploading again to avoid getting 429 + await new Promise((resolve) => setTimeout(resolve, 10000)); return await supertest .post(`/api/fleet/epm/packages`) .set('kbn-xsrf', 'xxxx') @@ -93,6 +100,7 @@ export default function (providerContext: FtrProviderContext) { it('should upgrade when uploading a newer zip archive', async () => { await uploadPackage(); + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveZipNewer); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -147,7 +155,23 @@ export default function (providerContext: FtrProviderContext) { expect(epmPackageAssetsRes.hits.total).to.equal(0); }); + it('should get 429 when trying to upload packages too soon', async () => { + await uploadPackage(); + + const buf = fs.readFileSync(testPkgArchiveZipNewer); + const res = await supertest + .post(`/api/fleet/epm/packages`) + .set('kbn-xsrf', 'xxxx') + .type('application/zip') + .send(buf) + .expect(429); + expect((res.error as HTTPError).text).to.equal( + '{"statusCode":429,"error":"Too Many Requests","message":"Too many requests. Please wait 10s before uploading again."}' + ); + }); + it('should install a zip archive correctly and package info should return correctly after validation', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveZip); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -159,6 +183,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should throw an error if the archive is zip but content type is gzip', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveZip); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -172,6 +197,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should throw an error if the archive is tar.gz but content type is zip', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveTgz); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -185,6 +211,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should throw an error if the archive contains two top-level directories', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveInvalidTwoToplevels); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -198,6 +225,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should throw an error if the archive does not contain a manifest', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveInvalidNoManifest); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -211,6 +239,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should throw an error if the archive manifest contains invalid YAML', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveInvalidManifestInvalidYaml); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -224,6 +253,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should throw an error if the archive manifest misses a mandatory field', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveInvalidManifestMissingField); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -237,6 +267,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should throw an error if the toplevel directory name does not match the package key', async function () { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveInvalidToplevelMismatch); const res = await supertest .post(`/api/fleet/epm/packages`) @@ -250,6 +281,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should not allow users without all access', async () => { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveTgz); await supertestWithoutAuth .post(`/api/fleet/epm/packages`) @@ -261,6 +293,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should allow user with all access', async () => { + await new Promise((resolve) => setTimeout(resolve, 10000)); const buf = fs.readFileSync(testPkgArchiveTgz); await supertestWithoutAuth .post(`/api/fleet/epm/packages`) diff --git a/x-pack/test/fleet_api_integration/apis/epm/remove_legacy_templates.ts b/x-pack/test/fleet_api_integration/apis/epm/remove_legacy_templates.ts index 0ab9e68d3e59a..bce10e14428f7 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/remove_legacy_templates.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/remove_legacy_templates.ts @@ -98,7 +98,7 @@ export default function (providerContext: FtrProviderContext) { await supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); }; - describe('legacy component template removal', async () => { + describe('Legacy component template removal', async () => { skipIfNoDockerRegistry(providerContext); setupFleetAndAgents(providerContext); @@ -137,6 +137,8 @@ export default function (providerContext: FtrProviderContext) { }); await waitUntilLegacyComponentTemplatesCreated(); + // wait 10s before uploading again to avoid getting 429 + await sleep(10000); await installUploadPackage(); const { component_templates: allComponentTemplates } = diff --git a/x-pack/test/monitoring_api_integration/apis/kibana/index.ts b/x-pack/test/monitoring_api_integration/apis/kibana/index.ts index 4409c5a871397..8b6ca6b8e58f1 100644 --- a/x-pack/test/monitoring_api_integration/apis/kibana/index.ts +++ b/x-pack/test/monitoring_api_integration/apis/kibana/index.ts @@ -10,7 +10,7 @@ import { installPackage } from '../../packages'; export default function ({ loadTestFile, getService }: FtrProviderContext) { describe('Kibana', () => { - before(() => installPackage(getService('supertest'), 'kibana')); + before(async () => await installPackage(getService('supertest'), 'kibana')); loadTestFile(require.resolve('./overview')); loadTestFile(require.resolve('./instances')); diff --git a/x-pack/test/monitoring_api_integration/packages.ts b/x-pack/test/monitoring_api_integration/packages.ts index 981845eb460dc..ec9d9911b189f 100644 --- a/x-pack/test/monitoring_api_integration/packages.ts +++ b/x-pack/test/monitoring_api_integration/packages.ts @@ -30,12 +30,14 @@ export const getPackagesArgs = (): string[] => { export const bundledPackagesLocation = path.join(path.dirname(__filename), '/fixtures/packages'); -export function installPackage(supertest: SuperTest.Agent, packageName: SupportedPackage) { +export async function installPackage(supertest: SuperTest.Agent, packageName: SupportedPackage) { const pkg = PACKAGES.find(({ name }) => name === packageName); const request = supertest .post('/api/fleet/epm/packages') .set('kbn-xsrf', 'xxx') .set('content-type', 'application/zip'); + // wait 10s before uploading again to avoid getting 429 from upload endpoint + await new Promise((resolve) => setTimeout(resolve, 10000)); return new Promise((resolve, reject) => { createReadStream(path.join(bundledPackagesLocation, `${pkg!.name}-${pkg!.version}.zip`)) From 5743aa09cf2a598685214fe4af9f3d997f556e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Thu, 6 Jun 2024 18:55:40 +0200 Subject: [PATCH 052/122] [Obs AI Assistant] Use const for function names (#184830) Some of the AI Assistant functions have very generic names. One example is the `context` function. When stumbling upon code like ``` const contextRequest = functionClient.hasFunction('context') ``` ... it is quite difficult to navigate to the context function implementation without knowing it's exact location. Searching for `context` is futile since it's a term used for many different things. Using a constant to refer to a function makes it much easier to navigate to where the function is registered. It also avoids typos but that's a side-effect, not the main motivation for this. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../server/functions/context.ts | 6 ++-- .../functions/get_dataset_info/index.ts | 4 ++- .../server/functions/index.ts | 36 ++++++++++--------- .../server/functions/summarize.ts | 4 ++- .../chat_function_client/index.test.ts | 6 ++-- .../service/chat_function_client/index.ts | 4 ++- .../get_system_message_instructions.ts | 3 +- .../get_context_function_request_if_needed.ts | 5 +-- .../server/service/client/index.test.ts | 11 +++--- .../server/service/client/index.ts | 3 +- .../client/operators/continue_conversation.ts | 3 +- .../public/components/chat/chat_body.test.tsx | 9 ++--- ..._timeline_items_from_conversation.test.tsx | 9 ++--- .../server/functions/changes/index.ts | 4 ++- .../server/functions/query/index.ts | 16 +++++---- .../server/index.ts | 2 ++ 16 files changed, 75 insertions(+), 50 deletions(-) diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts index 4a347c2710ef4..4bc32a2330acd 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/context.ts @@ -26,6 +26,8 @@ import { parseSuggestionScores } from './parse_suggestion_scores'; const MAX_TOKEN_COUNT_FOR_DATA_ON_SCREEN = 1000; +export const CONTEXT_FUNCTION_NAME = 'context'; + export function registerContextFunction({ client, functions, @@ -34,7 +36,7 @@ export function registerContextFunction({ }: FunctionRegistrationParameters & { isKnowledgeBaseAvailable: boolean }) { functions.registerFunction( { - name: 'context', + name: CONTEXT_FUNCTION_NAME, description: 'This function provides context as to what the user is looking at on their screen, and recalled documents from the knowledge base that matches their query', visibility: FunctionVisibility.Internal, @@ -157,7 +159,7 @@ export function registerContextFunction({ .then(({ content, data }) => { subscriber.next( createFunctionResponseMessage({ - name: 'context', + name: CONTEXT_FUNCTION_NAME, content, data, }) diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts index f016ae126ca53..bac7963cecbdf 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/get_dataset_info/index.ts @@ -9,13 +9,15 @@ import { FunctionRegistrationParameters } from '..'; import { FunctionVisibility } from '../../../common/functions/types'; import { getRelevantFieldNames } from './get_relevant_field_names'; +export const GET_DATASET_INFO_FUNCTION_NAME = 'get_dataset_info'; + export function registerGetDatasetInfoFunction({ resources, functions, }: FunctionRegistrationParameters) { functions.registerFunction( { - name: 'get_dataset_info', + name: GET_DATASET_INFO_FUNCTION_NAME, visibility: FunctionVisibility.AssistantOnly, description: `Use this function to get information about indices/datasets available and the fields available on them. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/index.ts index 7f706046a693c..4cf8147d31c71 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/index.ts @@ -6,13 +6,17 @@ */ import dedent from 'dedent'; -import { registerContextFunction } from './context'; -import { registerSummarizationFunction } from './summarize'; +import { CONTEXT_FUNCTION_NAME, registerContextFunction } from './context'; +import { registerSummarizationFunction, SUMMARIZE_FUNCTION_NAME } from './summarize'; import type { RegistrationCallback } from '../service/types'; import { registerElasticsearchFunction } from './elasticsearch'; -import { registerGetDatasetInfoFunction } from './get_dataset_info'; +import { GET_DATASET_INFO_FUNCTION_NAME, registerGetDatasetInfoFunction } from './get_dataset_info'; import { registerKibanaFunction } from './kibana'; import { registerExecuteConnectorFunction } from './execute_connector'; +import { GET_DATA_ON_SCREEN_FUNCTION_NAME } from '../service/chat_function_client'; + +// cannot be imported from x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts due to circular dependency +export const QUERY_FUNCTION_NAME = 'query'; export type FunctionRegistrationParameters = Omit< Parameters[0], @@ -59,30 +63,30 @@ export const registerFunctions: RegistrationCallback = async ({ functions.registerInstruction(({ availableFunctionNames }) => { const instructions: string[] = []; - if (availableFunctionNames.includes('get_dataset_info')) { - instructions.push(`You MUST use the get_dataset_info function ${ - functions.hasFunction('get_apm_dataset_info') ? 'or get_apm_dataset_info' : '' - } function before calling the "query" or "changes" function. + if (availableFunctionNames.includes(GET_DATASET_INFO_FUNCTION_NAME)) { + instructions.push(`You MUST use the "${GET_DATASET_INFO_FUNCTION_NAME}" ${ + functions.hasFunction('get_apm_dataset_info') ? 'or the get_apm_dataset_info' : '' + } function before calling the "${QUERY_FUNCTION_NAME}" or the "changes" functions. - If a function requires an index, you MUST use the results from the dataset info functions.`); + If a function requires an index, you MUST use the results from the dataset info functions.`); } - if (availableFunctionNames.includes('get_data_on_screen')) { - instructions.push(`You have access to data on the screen by calling the "get_data_on_screen" function. - Use it to help the user understand what they are looking at. A short summary of what they are looking at is available in the return of the "context" function. - Data that is compact enough automatically gets included in the response for the "context" function.`); + if (availableFunctionNames.includes(GET_DATA_ON_SCREEN_FUNCTION_NAME)) { + instructions.push(`You have access to data on the screen by calling the "${GET_DATA_ON_SCREEN_FUNCTION_NAME}" function. + Use it to help the user understand what they are looking at. A short summary of what they are looking at is available in the return of the "${CONTEXT_FUNCTION_NAME}" function. + Data that is compact enough automatically gets included in the response for the "${CONTEXT_FUNCTION_NAME}" function.`); } if (isReady) { - if (availableFunctionNames.includes('summarize')) { - instructions.push(`You can use the "summarize" functions to store new information you have learned in a knowledge database. + if (availableFunctionNames.includes(SUMMARIZE_FUNCTION_NAME)) { + instructions.push(`You can use the "${SUMMARIZE_FUNCTION_NAME}" function to store new information you have learned in a knowledge database. Only use this function when the user asks for it. All summaries MUST be created in English, even if the conversation was carried out in a different language.`); } - if (availableFunctionNames.includes('context')) { + if (availableFunctionNames.includes(CONTEXT_FUNCTION_NAME)) { instructions.push( - `Additionally, you can use the "context" function to retrieve relevant information from the knowledge database.` + `Additionally, you can use the "${CONTEXT_FUNCTION_NAME}" function to retrieve relevant information from the knowledge database.` ); } } else { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/summarize.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/summarize.ts index 4ff8e3ee4da91..ff14f5a3d3db3 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/summarize.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/functions/summarize.ts @@ -8,13 +8,15 @@ import type { FunctionRegistrationParameters } from '.'; import { KnowledgeBaseEntryRole } from '../../common'; +export const SUMMARIZE_FUNCTION_NAME = 'summarize'; + export function registerSummarizationFunction({ client, functions, }: FunctionRegistrationParameters) { functions.registerFunction( { - name: 'summarize', + name: SUMMARIZE_FUNCTION_NAME, description: `Use this function to store facts in the knowledge database if the user requests it. You can score the learnings with a confidence metric, whether it is a correction on a previous learning. An embedding will be created that you can recall later with a semantic search. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts index bdce24d65d2c7..cbb833d0aeb76 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts @@ -5,7 +5,7 @@ * 2.0. */ import dedent from 'dedent'; -import { ChatFunctionClient } from '.'; +import { ChatFunctionClient, GET_DATA_ON_SCREEN_FUNCTION_NAME } from '.'; import { FunctionVisibility } from '../../../common/functions/types'; describe('chatFunctionClient', () => { @@ -88,7 +88,7 @@ describe('chatFunctionClient', () => { expect(functions[0]).toEqual({ definition: { description: expect.any(String), - name: 'get_data_on_screen', + name: GET_DATA_ON_SCREEN_FUNCTION_NAME, parameters: expect.any(Object), visibility: FunctionVisibility.AssistantOnly, }, @@ -103,7 +103,7 @@ describe('chatFunctionClient', () => { const result = await client.executeFunction({ chat: jest.fn(), - name: 'get_data_on_screen', + name: GET_DATA_ON_SCREEN_FUNCTION_NAME, args: JSON.stringify({ data: ['my_dummy_data'] }), messages: [], signal: new AbortController().signal, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts index e882616e202cc..0b0f202e703cd 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts @@ -31,6 +31,8 @@ const ajv = new Ajv({ strict: false, }); +export const GET_DATA_ON_SCREEN_FUNCTION_NAME = 'get_data_on_screen'; + export class ChatFunctionClient { private readonly instructions: RegisteredInstruction[] = []; private readonly functionRegistry: FunctionHandlerRegistry = new Map(); @@ -46,7 +48,7 @@ export class ChatFunctionClient { if (allData.length) { this.registerFunction( { - name: 'get_data_on_screen', + name: GET_DATA_ON_SCREEN_FUNCTION_NAME, description: dedent(`Get data that is on the screen: ${allData.map((data) => `${data.name}: ${data.description}`).join('\n')} `), diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/simulate_function_calling/get_system_message_instructions.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/simulate_function_calling/get_system_message_instructions.ts index 2bf1052ec30e5..a409a80716320 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/simulate_function_calling/get_system_message_instructions.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/adapters/simulate_function_calling/get_system_message_instructions.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { CONTEXT_FUNCTION_NAME } from '../../../../functions/context'; import { FunctionDefinition } from '../../../../../common'; import { TOOL_USE_END, TOOL_USE_START } from './constants'; @@ -17,7 +18,7 @@ export function getSystemMessageInstructions({ return `In this environment, you have access to a set of tools you can use to answer the user's question. ${ - functions?.find((fn) => fn.name === 'context') + functions?.find((fn) => fn.name === CONTEXT_FUNCTION_NAME) ? `The "context" tool is ALWAYS used after a user question. Even if it was used before, your job is to answer the last user question, even if the "context" tool was executed after that. Consider the tools you need to answer the user's question.` : '' diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts index 8f05cf144a33b..74cc19d8aa153 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/get_context_function_request_if_needed.ts @@ -8,6 +8,7 @@ import { findLastIndex } from 'lodash'; import { Message, MessageAddEvent, MessageRole } from '../../../common'; import { createFunctionRequestMessage } from '../../../common/utils/create_function_request_message'; +import { CONTEXT_FUNCTION_NAME } from '../../functions/context'; export function getContextFunctionRequestIfNeeded( messages: Message[] @@ -19,14 +20,14 @@ export function getContextFunctionRequestIfNeeded( const hasContextSinceLastUserMessage = messages .slice(indexOfLastUserMessage) - .some((message) => message.message.name === 'context'); + .some((message) => message.message.name === CONTEXT_FUNCTION_NAME); if (hasContextSinceLastUserMessage) { return undefined; } return createFunctionRequestMessage({ - name: 'context', + name: CONTEXT_FUNCTION_NAME, args: { queries: [], categories: [], diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts index add345ffce9c5..829f0097875f8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts @@ -24,6 +24,7 @@ import { StreamingChatResponseEventType, } from '../../../common/conversation_complete'; import { createFunctionResponseMessage } from '../../../common/utils/create_function_response_message'; +import { CONTEXT_FUNCTION_NAME } from '../../functions/context'; import { ChatFunctionClient } from '../chat_function_client'; import type { KnowledgeBaseService } from '../knowledge_base_service'; import { observableIntoStream } from '../util/observable_into_stream'; @@ -145,7 +146,7 @@ describe('Observability AI Assistant client', () => { functionClientMock.getFunctions.mockReturnValue([]); functionClientMock.hasFunction.mockImplementation((name) => { - return name !== 'context'; + return name !== CONTEXT_FUNCTION_NAME; }); functionClientMock.hasAction.mockReturnValue(false); @@ -1230,7 +1231,7 @@ describe('Observability AI Assistant client', () => { content: '', role: MessageRole.Assistant, function_call: { - name: 'context', + name: CONTEXT_FUNCTION_NAME, arguments: JSON.stringify({ queries: [], categories: [] }), trigger: MessageRole.Assistant, }, @@ -1248,7 +1249,7 @@ describe('Observability AI Assistant client', () => { message: { content: JSON.stringify([{ id: 'my_document', text: 'My document' }]), role: MessageRole.User, - name: 'context', + name: CONTEXT_FUNCTION_NAME, }, }, }); @@ -1440,7 +1441,7 @@ describe('Observability AI Assistant client', () => { it('executes the context function', async () => { expect(functionClientMock.executeFunction).toHaveBeenCalledWith( - expect.objectContaining({ name: 'context' }) + expect.objectContaining({ name: CONTEXT_FUNCTION_NAME }) ); }); @@ -1454,7 +1455,7 @@ describe('Observability AI Assistant client', () => { content: '', role: MessageRole.Assistant, function_call: { - name: 'context', + name: CONTEXT_FUNCTION_NAME, arguments: JSON.stringify({ queries: [], categories: [] }), trigger: MessageRole.Assistant, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts index 694fbb3233edc..6af7ee9aa36ee 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts @@ -53,6 +53,7 @@ import { type Message, } from '../../../common/types'; import { withoutTokenCountEvents } from '../../../common/utils/without_token_count_events'; +import { CONTEXT_FUNCTION_NAME } from '../../functions/context'; import type { ChatFunctionClient } from '../chat_function_client'; import { KnowledgeBaseEntryOperationType, @@ -271,7 +272,7 @@ export class ObservabilityAIAssistantClient { ]).pipe( switchMap(([messagesWithUpdatedSystemMessage, knowledgeBaseInstructions]) => { // if needed, inject a context function request here - const contextRequest = functionClient.hasFunction('context') + const contextRequest = functionClient.hasFunction(CONTEXT_FUNCTION_NAME) ? getContextFunctionRequestIfNeeded(messagesWithUpdatedSystemMessage) : undefined; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts index ba9e8138fe95a..b7b134afc955c 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts @@ -21,6 +21,7 @@ import { switchMap, throwError, } from 'rxjs'; +import { CONTEXT_FUNCTION_NAME } from '../../../functions/context'; import { createFunctionNotFoundError, Message, MessageRole } from '../../../../common'; import { createFunctionLimitExceededError, @@ -209,7 +210,7 @@ export function continueConversation({ function executeNextStep() { if (isUserMessage) { const operationName = - lastMessage.name && lastMessage.name !== 'context' + lastMessage.name && lastMessage.name !== CONTEXT_FUNCTION_NAME ? `function_response ${lastMessage.name}` : 'user_message'; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/components/chat/chat_body.test.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/components/chat/chat_body.test.tsx index cfb85f7945240..e39bcf5d1891e 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/components/chat/chat_body.test.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/components/chat/chat_body.test.tsx @@ -6,6 +6,7 @@ */ import { Message } from '@kbn/observability-ai-assistant-plugin/common'; +import { CONTEXT_FUNCTION_NAME } from '@kbn/observability-ai-assistant-plugin/server/functions/context'; import { reverseToLastUserMessage } from './chat_body'; describe('', () => { @@ -38,7 +39,7 @@ describe('', () => { message: { role: 'assistant', function_call: { - name: 'context', + name: CONTEXT_FUNCTION_NAME, arguments: '{"queries":[],"categories":[]}', trigger: 'assistant', }, @@ -48,7 +49,7 @@ describe('', () => { { message: { role: 'user', - name: 'context', + name: CONTEXT_FUNCTION_NAME, content: '[]', }, }, @@ -86,7 +87,7 @@ describe('', () => { message: { role: 'assistant', function_call: { - name: 'context', + name: CONTEXT_FUNCTION_NAME, arguments: '{"queries":[],"categories":[]}', trigger: 'assistant', }, @@ -96,7 +97,7 @@ describe('', () => { { message: { role: 'user', - name: 'context', + name: CONTEXT_FUNCTION_NAME, content: '[]', }, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/utils/get_timeline_items_from_conversation.test.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/utils/get_timeline_items_from_conversation.test.tsx index e73555540b1e8..6fb7e1a323d08 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/utils/get_timeline_items_from_conversation.test.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/utils/get_timeline_items_from_conversation.test.tsx @@ -12,6 +12,7 @@ import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { ChatState, Message, MessageRole } from '@kbn/observability-ai-assistant-plugin/public'; import { createMockChatService } from './create_mock_chat_service'; import { KibanaContextProvider } from '@kbn/triggers-actions-ui-plugin/public/common/lib/kibana'; +import { CONTEXT_FUNCTION_NAME } from '@kbn/observability-ai-assistant-plugin/server/functions/context'; const mockChatService = createMockChatService(); @@ -135,7 +136,7 @@ describe('getTimelineItemsFromConversation', () => { message: { role: MessageRole.Assistant, function_call: { - name: 'context', + name: CONTEXT_FUNCTION_NAME, arguments: JSON.stringify({ queries: [], contexts: [] }), trigger: MessageRole.Assistant, }, @@ -145,7 +146,7 @@ describe('getTimelineItemsFromConversation', () => { '@timestamp': new Date().toISOString(), message: { role: MessageRole.User, - name: 'context', + name: CONTEXT_FUNCTION_NAME, content: JSON.stringify([]), }, }, @@ -430,7 +431,7 @@ describe('getTimelineItemsFromConversation', () => { message: { role: MessageRole.Assistant, function_call: { - name: 'context', + name: CONTEXT_FUNCTION_NAME, arguments: JSON.stringify({ queries: [], contexts: [] }), trigger: MessageRole.User, }, @@ -440,7 +441,7 @@ describe('getTimelineItemsFromConversation', () => { '@timestamp': new Date().toISOString(), message: { role: MessageRole.User, - name: 'context', + name: CONTEXT_FUNCTION_NAME, content: JSON.stringify([]), }, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts index 89ebfa90cb774..987414214a17b 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts @@ -17,6 +17,8 @@ import { import { getMetricChanges } from './get_metric_changes'; import { getLogChanges } from './get_log_changes'; +export const CHANGES_FUNCTION_NAME = 'changes'; + export function registerChangesFunction({ functions, resources: { @@ -26,7 +28,7 @@ export function registerChangesFunction({ }: FunctionRegistrationParameters) { functions.registerFunction( { - name: 'changes', + name: CHANGES_FUNCTION_NAME, description: 'Returns change points like spikes and dips for logs and metrics.', parameters: changesFunctionParameters, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts index 92d79053ad4af..8a81d9ae32123 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts @@ -26,6 +26,8 @@ import type { FunctionRegistrationParameters } from '..'; import { correctCommonEsqlMistakes } from './correct_common_esql_mistakes'; import { runAndValidateEsqlQuery } from './validate_esql_query'; +export const QUERY_FUNCTION_NAME = 'query'; + const readFile = promisify(Fs.readFile); const readdir = promisify(Fs.readdir); @@ -69,8 +71,8 @@ const loadEsqlDocs = once(async () => { export function registerQueryFunction({ functions, resources }: FunctionRegistrationParameters) { functions.registerInstruction(({ availableFunctionNames }) => - availableFunctionNames.includes('query') - ? `You MUST use the "query" function when the user wants to: + availableFunctionNames.includes(QUERY_FUNCTION_NAME) + ? `You MUST use the "${QUERY_FUNCTION_NAME}" function when the user wants to: - visualize data - run any arbitrary query - breakdown or filter ES|QL queries that are displayed on the current page @@ -78,11 +80,11 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra - asks general questions about ES|QL DO NOT UNDER ANY CIRCUMSTANCES generate ES|QL queries or explain anything about the ES|QL query language yourself. - DO NOT UNDER ANY CIRCUMSTANCES try to correct an ES|QL query yourself - always use the "query" function for this. + DO NOT UNDER ANY CIRCUMSTANCES try to correct an ES|QL query yourself - always use the "${QUERY_FUNCTION_NAME}" function for this. If the user asks for a query, and one of the dataset info functions was called and returned no results, you should still call the query function to generate an example query. - Even if the "context" function was used before that, follow it up with the "query" function. If a query fails, do not attempt to correct it yourself. Again you should call the "query" function, + Even if the "${QUERY_FUNCTION_NAME}" function was used before that, follow it up with the "${QUERY_FUNCTION_NAME}" function. If a query fails, do not attempt to correct it yourself. Again you should call the "${QUERY_FUNCTION_NAME}" function, even if it has been called before. When the "visualize_query" function has been called, a visualization has been displayed to the user. DO NOT UNDER ANY CIRCUMSTANCES follow up a "visualize_query" function call with your own visualization attempt. @@ -132,7 +134,7 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra ); functions.registerFunction( { - name: 'query', + name: QUERY_FUNCTION_NAME, description: `This function generates, executes and/or visualizes a query based on the user's request. It also explains how ES|QL works and how to convert queries from one language to another. Make sure you call one of the get_dataset functions first if you need index or field names. This function takes no input.`, visibility: FunctionVisibility.AssistantOnly, }, @@ -159,7 +161,7 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra await chat('classify_esql', { messages: withEsqlSystemMessage().concat( createFunctionResponseMessage({ - name: 'query', + name: QUERY_FUNCTION_NAME, content: {}, }).message, { @@ -323,7 +325,7 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra } const queryFunctionResponseMessage = createFunctionResponseMessage({ - name: 'query', + name: QUERY_FUNCTION_NAME, content: {}, data: { // add the included docs for debugging diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/index.ts index 36217f5a762e5..bf14959a2fba9 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/index.ts @@ -8,6 +8,8 @@ import type { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server'; import type { ObservabilityAIAssistantAppConfig } from './config'; +export { CHANGES_FUNCTION_NAME } from './functions/changes'; +export { QUERY_FUNCTION_NAME } from './functions/query'; import { config as configSchema } from './config'; export type { ObservabilityAIAssistantAppServerStart, From 7d8fc904911453927e6691773498a3276a7f8f62 Mon Sep 17 00:00:00 2001 From: Rachel Shen Date: Thu, 6 Jun 2024 10:57:55 -0600 Subject: [PATCH 053/122] [Share Modal][Fix] Serverless environments customizations (#184700) ## Summary Closes [184539](https://github.com/elastic/kibana/issues/184539) There is a misleading message for serverless deployments that do not do upgrades manually. This PR removes the callout in serverless environments. Also copy post url needs to be removed since there are no public apis for CSV reports in serverless. cc @tsullivan --- .../share/public/components/context/index.tsx | 1 + .../components/tabs/export/export_content.tsx | 52 ++++++++++++------- .../public/components/tabs/export/index.tsx | 3 +- .../public/services/share_menu_manager.tsx | 3 ++ src/plugins/share/public/types.ts | 1 + 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/plugins/share/public/components/context/index.tsx b/src/plugins/share/public/components/context/index.tsx index 1426bd42c805a..46cdea37f002f 100644 --- a/src/plugins/share/public/components/context/index.tsx +++ b/src/plugins/share/public/components/context/index.tsx @@ -31,6 +31,7 @@ export interface IShareContext extends ShareContext { isEmbedded: boolean; theme: ThemeServiceSetup; i18n: I18nStart; + publicAPIEnabled?: boolean; anchorElement?: HTMLElement; } diff --git a/src/plugins/share/public/components/tabs/export/export_content.tsx b/src/plugins/share/public/components/tabs/export/export_content.tsx index b979a61c5398c..b1106b7df7774 100644 --- a/src/plugins/share/public/components/tabs/export/export_content.tsx +++ b/src/plugins/share/public/components/tabs/export/export_content.tsx @@ -33,9 +33,16 @@ type ExportProps = Pick { +const ExportContentUi = ({ + isDirty, + aggregateReportTypes, + intl, + onClose, + publicAPIEnabled, +}: ExportProps) => { const [isCreatingExport, setIsCreatingExport] = useState(false); const [usePrintLayout, setPrintLayout] = useState(false); @@ -116,7 +123,7 @@ const ExportContentUi = ({ isDirty, aggregateReportTypes, intl, onClose }: Expor }, [usePrintLayout, renderLayoutOptionSwitch, handlePrintLayoutChange]); const showCopyURLButton = useCallback(() => { - if (renderCopyURLButton) + if (renderCopyURLButton && publicAPIEnabled) return ( @@ -151,7 +158,7 @@ const ExportContentUi = ({ isDirty, aggregateReportTypes, intl, onClose }: Expor ); - }, [absoluteUrl, renderCopyURLButton]); + }, [absoluteUrl, renderCopyURLButton, publicAPIEnabled]); const renderGenerateReportButton = useCallback(() => { return ( @@ -185,6 +192,28 @@ const ExportContentUi = ({ isDirty, aggregateReportTypes, intl, onClose }: Expor } }; + const renderHelpText = () => { + const showHelpText = publicAPIEnabled && isDirty; + return ( + showHelpText && ( + <> + + + } + > + + + + ) + ); + }; + return ( <> @@ -192,22 +221,7 @@ const ExportContentUi = ({ isDirty, aggregateReportTypes, intl, onClose }: Expor <>{helpText} <>{renderRadioOptions()} - {isDirty && ( - <> - - - } - > - - - - )} + {renderHelpText()} diff --git a/src/plugins/share/public/components/tabs/export/index.tsx b/src/plugins/share/public/components/tabs/export/index.tsx index 28066ee3d65c6..68a329c0a54a5 100644 --- a/src/plugins/share/public/components/tabs/export/index.tsx +++ b/src/plugins/share/public/components/tabs/export/index.tsx @@ -15,7 +15,7 @@ import { useShareTabsContext, type ShareMenuItemV2 } from '../../context'; type IExportTab = IModalTabDeclaration; const ExportTabContent = () => { - const { shareMenuItems, objectType, isDirty, onClose } = useShareTabsContext()!; + const { shareMenuItems, objectType, isDirty, onClose, publicAPIEnabled } = useShareTabsContext()!; return ( { onClose={onClose} // we are guaranteed that shareMenuItems will be a ShareMenuItem V2 variant aggregateReportTypes={shareMenuItems as unknown as ShareMenuItemV2[]} + publicAPIEnabled={publicAPIEnabled ?? true} /> ); }; diff --git a/src/plugins/share/public/services/share_menu_manager.tsx b/src/plugins/share/public/services/share_menu_manager.tsx index 1bec2d9f6416e..0f58e875cfcd5 100644 --- a/src/plugins/share/public/services/share_menu_manager.tsx +++ b/src/plugins/share/public/services/share_menu_manager.tsx @@ -52,6 +52,7 @@ export class ShareMenuManager { overlays: core.overlays, i18n: core.i18n, toasts: core.notifications.toasts, + publicAPIEnabled: !disableEmbed, }); }, }; @@ -86,6 +87,7 @@ export class ShareMenuManager { isDirty, toasts, delegatedShareUrlHandler, + publicAPIEnabled, }: ShowShareMenuOptions & { anchorElement: HTMLElement; menuItems: ShareMenuItem[]; @@ -111,6 +113,7 @@ export class ShareMenuManager { toMountPoint( { embedUrlParamExtensions?: UrlParamExtension[]; snapshotShareWarning?: string; onClose?: () => void; + publicAPIEnabled?: boolean; } export interface ClientConfigType { From 667a9d36910e17eb8cb2a1f75134d4a8e1fd8949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Thu, 6 Jun 2024 18:06:21 +0100 Subject: [PATCH 054/122] [Stateful sidenav] Add cloud yml setting for onboarding default solution (#184808) --- .../test_suites/core_plugins/rendering.ts | 1 + x-pack/plugins/cloud/common/index.ts | 8 ++++ .../parse_onboarding_default_solution.test.ts | 33 ++++++++++++++++ .../parse_onboarding_default_solution.ts | 39 +++++++++++++++++++ x-pack/plugins/cloud/common/types.ts | 8 ++++ x-pack/plugins/cloud/public/mocks.tsx | 1 + x-pack/plugins/cloud/public/plugin.test.ts | 9 +++++ x-pack/plugins/cloud/public/plugin.tsx | 10 ++++- x-pack/plugins/cloud/public/types.ts | 10 +++++ .../server/__snapshots__/plugin.test.ts.snap | 3 ++ x-pack/plugins/cloud/server/config.ts | 8 ++++ x-pack/plugins/cloud/server/mocks.ts | 1 + x-pack/plugins/cloud/server/plugin.test.ts | 9 +++++ x-pack/plugins/cloud/server/plugin.ts | 14 +++++++ .../get_cloud_enterprise_search_host.test.ts | 4 ++ .../plugins/fleet/.storybook/context/cloud.ts | 1 + .../fleet_server_host.test.ts | 5 +++ 17 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/cloud/common/index.ts create mode 100644 x-pack/plugins/cloud/common/parse_onboarding_default_solution.test.ts create mode 100644 x-pack/plugins/cloud/common/parse_onboarding_default_solution.ts create mode 100644 x-pack/plugins/cloud/common/types.ts diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index df4353beb569c..7ccbc90d8760e 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -256,6 +256,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.cloud.serverless.project_id (string)', 'xpack.cloud.serverless.project_name (string)', 'xpack.cloud.serverless.project_type (string)', + 'xpack.cloud.onboarding.default_solution (string)', 'xpack.discoverEnhanced.actions.exploreDataInChart.enabled (boolean)', 'xpack.discoverEnhanced.actions.exploreDataInContextMenu.enabled (boolean)', 'xpack.fleet.agents.enabled (boolean)', diff --git a/x-pack/plugins/cloud/common/index.ts b/x-pack/plugins/cloud/common/index.ts new file mode 100644 index 0000000000000..4aa6ce8d5edf0 --- /dev/null +++ b/x-pack/plugins/cloud/common/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 type { OnBoardingDefaultSolution } from './types'; diff --git a/x-pack/plugins/cloud/common/parse_onboarding_default_solution.test.ts b/x-pack/plugins/cloud/common/parse_onboarding_default_solution.test.ts new file mode 100644 index 0000000000000..de8b305ee452b --- /dev/null +++ b/x-pack/plugins/cloud/common/parse_onboarding_default_solution.test.ts @@ -0,0 +1,33 @@ +/* + * 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 { parseOnboardingSolution } from './parse_onboarding_default_solution'; + +describe('parseOnboardingSolution', () => { + it('should return undefined if there is no default solution defined', () => { + expect(parseOnboardingSolution()).toBeUndefined(); + }); + + it('should map correctly the cloud values to the Kibana values, regardless of case', () => { + [ + ['elasticsearch', 'es'], + ['Elasticsearch', 'es'], + ['observability', 'oblt'], + ['Observability', 'oblt'], + ['security', 'security'], + ['Security', 'security'], + ].forEach(([cloudValue, kibanaValue]) => { + expect(parseOnboardingSolution(cloudValue)).toBe(kibanaValue); + expect(parseOnboardingSolution(cloudValue.toUpperCase())).toBe(kibanaValue); + expect(parseOnboardingSolution(cloudValue.toLowerCase())).toBe(kibanaValue); + }); + }); + + it('should return undefined for unknown values', () => { + expect(parseOnboardingSolution('unknown')).toBeUndefined(); + }); +}); diff --git a/x-pack/plugins/cloud/common/parse_onboarding_default_solution.ts b/x-pack/plugins/cloud/common/parse_onboarding_default_solution.ts new file mode 100644 index 0000000000000..e5938f77af92f --- /dev/null +++ b/x-pack/plugins/cloud/common/parse_onboarding_default_solution.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { OnBoardingDefaultSolution } from './types'; + +/** + * Cloud does not type the value of the "use case" that is set during onboarding for a deployment. Any string can + * be passed. This function maps the known values to the Kibana values. + * + * @param value The solution value set by Cloud. + * @returns The default solution value for onboarding that matches Kibana naming. + */ +export function parseOnboardingSolution(value?: string): OnBoardingDefaultSolution | undefined { + if (!value) return; + + const solutions: Array<{ + cloudValue: 'elasticsearch' | 'observability' | 'security'; + kibanaValue: OnBoardingDefaultSolution; + }> = [ + { + cloudValue: 'elasticsearch', + kibanaValue: 'es', + }, + { + cloudValue: 'observability', + kibanaValue: 'oblt', + }, + { + cloudValue: 'security', + kibanaValue: 'security', + }, + ]; + + return solutions.find(({ cloudValue }) => value.toLowerCase() === cloudValue)?.kibanaValue; +} diff --git a/x-pack/plugins/cloud/common/types.ts b/x-pack/plugins/cloud/common/types.ts new file mode 100644 index 0000000000000..ac4593fd0e259 --- /dev/null +++ b/x-pack/plugins/cloud/common/types.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 type OnBoardingDefaultSolution = 'es' | 'oblt' | 'security'; diff --git a/x-pack/plugins/cloud/public/mocks.tsx b/x-pack/plugins/cloud/public/mocks.tsx index 8bd4a933a0f1b..dd5c5eced618a 100644 --- a/x-pack/plugins/cloud/public/mocks.tsx +++ b/x-pack/plugins/cloud/public/mocks.tsx @@ -26,6 +26,7 @@ function createSetupMock(): jest.Mocked { isElasticStaffOwned: true, trialEndDate: new Date('2020-10-01T14:13:12Z'), registerCloudService: jest.fn(), + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, diff --git a/x-pack/plugins/cloud/public/plugin.test.ts b/x-pack/plugins/cloud/public/plugin.test.ts index 99e6f97946cca..61ed450324637 100644 --- a/x-pack/plugins/cloud/public/plugin.test.ts +++ b/x-pack/plugins/cloud/public/plugin.test.ts @@ -122,6 +122,15 @@ describe('Cloud Plugin', () => { expect(decodeCloudIdMock).toHaveBeenCalledWith('cloudId', expect.any(Object)); }); + it('exposes `onboarding.default_solution`', () => { + const { setup } = setupPlugin({ + onboarding: { + default_solution: 'Elasticsearch', + }, + }); + expect(setup.onboarding.defaultSolution).toBe('es'); + }); + describe('isServerlessEnabled', () => { it('is `true` when `serverless.projectId` is set', () => { const { setup } = setupPlugin({ diff --git a/x-pack/plugins/cloud/public/plugin.tsx b/x-pack/plugins/cloud/public/plugin.tsx index f0a561194b562..0d071900418c3 100644 --- a/x-pack/plugins/cloud/public/plugin.tsx +++ b/x-pack/plugins/cloud/public/plugin.tsx @@ -8,13 +8,15 @@ import React, { FC, PropsWithChildren } from 'react'; import type { Logger } from '@kbn/logging'; import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; + import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context'; import { getIsCloudEnabled } from '../common/is_cloud_enabled'; import { parseDeploymentIdFromDeploymentUrl } from '../common/parse_deployment_id_from_deployment_url'; import { CLOUD_SNAPSHOTS_PATH } from '../common/constants'; import { decodeCloudId, type DecodedCloudId } from '../common/decode_cloud_id'; -import type { CloudSetup, CloudStart } from './types'; import { getFullCloudUrl } from '../common/utils'; +import { parseOnboardingSolution } from '../common/parse_onboarding_default_solution'; +import type { CloudSetup, CloudStart } from './types'; import { getSupportUrl } from './utils'; export interface CloudConfigType { @@ -31,6 +33,9 @@ export interface CloudConfigType { performance_url?: string; trial_end_date?: string; is_elastic_staff_owned?: boolean; + onboarding?: { + default_solution?: string; + }; serverless?: { project_id: string; project_name?: string; @@ -95,6 +100,9 @@ export class CloudPlugin implements Plugin { trialEndDate: trialEndDate ? new Date(trialEndDate) : undefined, isElasticStaffOwned, isCloudEnabled: this.isCloudEnabled, + onboarding: { + defaultSolution: parseOnboardingSolution(this.config.onboarding?.default_solution), + }, isServerlessEnabled: this.isServerlessEnabled, serverless: { projectId: this.config.serverless?.project_id, diff --git a/x-pack/plugins/cloud/public/types.ts b/x-pack/plugins/cloud/public/types.ts index 8de4f226beea4..a7e34c79a8505 100644 --- a/x-pack/plugins/cloud/public/types.ts +++ b/x-pack/plugins/cloud/public/types.ts @@ -6,6 +6,7 @@ */ import type { FC, PropsWithChildren } from 'react'; +import type { OnBoardingDefaultSolution } from '../common'; export interface CloudStart { /** @@ -174,6 +175,15 @@ export interface CloudSetup { * @param contextProvider The React component from the Service Provider. */ registerCloudService: (contextProvider: FC) => void; + /** + * Onboarding configuration + */ + onboarding: { + /** + * The default solution selected during onboarding. + */ + defaultSolution?: OnBoardingDefaultSolution; + }; /** * `true` when running on Serverless Elastic Cloud * Note that `isCloudEnabled` will always be true when `isServerlessEnabled` is. diff --git a/x-pack/plugins/cloud/server/__snapshots__/plugin.test.ts.snap b/x-pack/plugins/cloud/server/__snapshots__/plugin.test.ts.snap index c1fbbc93e96b5..41002d0c48e6b 100644 --- a/x-pack/plugins/cloud/server/__snapshots__/plugin.test.ts.snap +++ b/x-pack/plugins/cloud/server/__snapshots__/plugin.test.ts.snap @@ -17,6 +17,9 @@ Object { "isElasticStaffOwned": undefined, "isServerlessEnabled": false, "kibanaUrl": undefined, + "onboarding": Object { + "defaultSolution": undefined, + }, "projectsUrl": "https://cloud.elastic.co/projects/", "serverless": Object { "projectId": undefined, diff --git a/x-pack/plugins/cloud/server/config.ts b/x-pack/plugins/cloud/server/config.ts index 39babd548d99a..de4ebd94b6f2b 100644 --- a/x-pack/plugins/cloud/server/config.ts +++ b/x-pack/plugins/cloud/server/config.ts @@ -33,6 +33,11 @@ const configSchema = schema.object({ projects_url: offeringBasedSchema({ serverless: schema.string({ defaultValue: '/projects/' }) }), trial_end_date: schema.maybe(schema.string()), is_elastic_staff_owned: schema.maybe(schema.boolean()), + onboarding: schema.maybe( + schema.object({ + default_solution: schema.maybe(schema.string()), + }) + ), serverless: schema.maybe( schema.object( { @@ -68,6 +73,9 @@ export const config: PluginConfigDescriptor = { project_name: true, project_type: true, }, + onboarding: { + default_solution: true, + }, }, schema: configSchema, }; diff --git a/x-pack/plugins/cloud/server/mocks.ts b/x-pack/plugins/cloud/server/mocks.ts index 78ef284a5c949..e77f58902bf3e 100644 --- a/x-pack/plugins/cloud/server/mocks.ts +++ b/x-pack/plugins/cloud/server/mocks.ts @@ -25,6 +25,7 @@ function createSetupMock(): jest.Mocked { url: undefined, secretToken: undefined, }, + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, diff --git a/x-pack/plugins/cloud/server/plugin.test.ts b/x-pack/plugins/cloud/server/plugin.test.ts index d13e04ca1138a..f2ef8375b417e 100644 --- a/x-pack/plugins/cloud/server/plugin.test.ts +++ b/x-pack/plugins/cloud/server/plugin.test.ts @@ -98,6 +98,15 @@ describe('Cloud Plugin', () => { expect(decodeCloudIdMock).toHaveBeenCalledWith('cloudId', expect.any(Object)); }); + it('exposes `onboarding.default_solution`', () => { + const { setup } = setupPlugin({ + onboarding: { + default_solution: 'Elasticsearch', + }, + }); + expect(setup.onboarding.defaultSolution).toBe('es'); + }); + describe('isServerlessEnabled', () => { it('is `true` when `serverless.projectId` is set', () => { const { setup } = setupPlugin({ diff --git a/x-pack/plugins/cloud/server/plugin.ts b/x-pack/plugins/cloud/server/plugin.ts index 322794b11fa21..d8d5d397655e3 100644 --- a/x-pack/plugins/cloud/server/plugin.ts +++ b/x-pack/plugins/cloud/server/plugin.ts @@ -11,9 +11,11 @@ import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context'; import type { CloudConfigType } from './config'; import { registerCloudUsageCollector } from './collectors'; +import type { OnBoardingDefaultSolution } from '../common'; import { getIsCloudEnabled } from '../common/is_cloud_enabled'; import { parseDeploymentIdFromDeploymentUrl } from '../common/parse_deployment_id_from_deployment_url'; import { decodeCloudId, DecodedCloudId } from '../common/decode_cloud_id'; +import { parseOnboardingSolution } from '../common/parse_onboarding_default_solution'; import { getFullCloudUrl } from '../common/utils'; import { readInstanceSizeMb } from './env'; @@ -88,6 +90,15 @@ export interface CloudSetup { url?: string; secretToken?: string; }; + /** + * Onboarding configuration. + */ + onboarding: { + /** + * The default solution selected during onboarding. + */ + defaultSolution?: OnBoardingDefaultSolution; + }; /** * `true` when running on Serverless Elastic Cloud * Note that `isCloudEnabled` will always be true when `isServerlessEnabled` is. @@ -188,6 +199,9 @@ export class CloudPlugin implements Plugin { url: this.config.apm?.url, secretToken: this.config.apm?.secret_token, }, + onboarding: { + defaultSolution: parseOnboardingSolution(this.config.onboarding?.default_solution), + }, isServerlessEnabled, serverless: { projectId, diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/get_cloud_enterprise_search_host/get_cloud_enterprise_search_host.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/get_cloud_enterprise_search_host/get_cloud_enterprise_search_host.test.ts index 06d07f12668ee..71b413b487090 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/get_cloud_enterprise_search_host/get_cloud_enterprise_search_host.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/get_cloud_enterprise_search_host/get_cloud_enterprise_search_host.test.ts @@ -15,6 +15,7 @@ const defaultPortCloud = { cloudHost: 'us-central1.gcp.cloud.es.io', cloudDefaultPort: '443', registerCloudService: jest.fn(), + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, @@ -29,6 +30,7 @@ const customPortCloud = { cloudHost: 'us-central1.gcp.cloud.es.io', cloudDefaultPort: '9243', registerCloudService: jest.fn(), + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, @@ -39,6 +41,7 @@ const missingDeploymentIdCloud = { 'dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvOjkyNDMkYWMzMWViYjkwMjQxNzczMTU3MDQzYzM0ZmQyNmZkNDYkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA=', isCloudEnabled: true, registerCloudService: jest.fn(), + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, @@ -48,6 +51,7 @@ const noCloud = { cloudId: undefined, isCloudEnabled: false, registerCloudService: jest.fn(), + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, diff --git a/x-pack/plugins/fleet/.storybook/context/cloud.ts b/x-pack/plugins/fleet/.storybook/context/cloud.ts index 9acbbd221059b..00efa8702ac16 100644 --- a/x-pack/plugins/fleet/.storybook/context/cloud.ts +++ b/x-pack/plugins/fleet/.storybook/context/cloud.ts @@ -18,6 +18,7 @@ export const getCloud = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => { profileUrl: 'https://profile.url', snapshotsUrl: 'https://snapshots.url', registerCloudService: () => {}, + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts index 22651dfae1405..de7578129a09b 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts @@ -159,6 +159,7 @@ describe('getCloudFleetServersHosts', () => { deploymentId: 'deployment-id-1', cloudHost: 'us-east-1.aws.found.io', apm: {}, + onboarding: {}, isServerlessEnabled: true, serverless: { projectId: undefined, @@ -176,6 +177,7 @@ describe('getCloudFleetServersHosts', () => { deploymentId: 'deployment-id-1', cloudHost: 'us-east-1.aws.found.io', apm: {}, + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, @@ -198,6 +200,7 @@ describe('getCloudFleetServersHosts', () => { cloudHost: 'test.fr', cloudDefaultPort: '9243', apm: {}, + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, @@ -233,6 +236,7 @@ describe('createCloudFleetServerHostIfNeeded', () => { isCloudEnabled: true, deploymentId: 'deployment-id-1', apm: {}, + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, @@ -256,6 +260,7 @@ describe('createCloudFleetServerHostIfNeeded', () => { deploymentId: 'deployment-id-1', cloudHost: 'us-east-1.aws.found.io', apm: {}, + onboarding: {}, isServerlessEnabled: false, serverless: { projectId: undefined, From 9a4ceaf59de69ebf349a389c83ffea67e8bb187d Mon Sep 17 00:00:00 2001 From: Philippe Oberti Date: Thu, 6 Jun 2024 12:50:41 -0500 Subject: [PATCH 055/122] [Security Solution][Alert details] - fix timeline osquery flyout showm behind (#184951) --- .../components/osquery/osquery_flyout.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx index b4758bf79616d..d08d405d5d674 100644 --- a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import { EuiFlyout, @@ -13,6 +13,7 @@ import { EuiFlyoutBody, EuiFlyoutHeader, EuiTitle, + useEuiTheme, useGeneratedHtmlId, } from '@elastic/eui'; import { useQueryClient } from '@tanstack/react-query'; @@ -46,6 +47,14 @@ const OsqueryFlyoutComponent: React.FC = ({ onClose, ecsData, }) => { + const { euiTheme } = useEuiTheme(); + + // we need this flyout to be above the timeline flyout (which has a z-index of 1002) + const maskProps = useMemo( + () => ({ style: `z-index: ${(euiTheme.levels.flyout as number) + 3}` }), + [euiTheme.levels.flyout] + ); + const { services: { osquery }, } = useKibana(); @@ -63,7 +72,13 @@ const OsqueryFlyoutComponent: React.FC = ({ if (osquery?.OsqueryAction) { return ( - +

{ACTION_OSQUERY}

From 1ff87eb551ef75fd6c35cbcb2bb5cbc0253aeff4 Mon Sep 17 00:00:00 2001 From: honeyn303 <117302426+honeyn303@users.noreply.github.com> Date: Thu, 6 Jun 2024 19:52:35 +0200 Subject: [PATCH 056/122] Gemini connector integration (#183668) --- .github/CODEOWNERS | 5 + docs/management/action-types.asciidoc | 4 + .../connectors/action-types/gemini.asciidoc | 74 ++++ .../connectors/images/gemini-connector.png | Bin 0 -> 265115 bytes .../connectors/images/gemini-params.png | Bin 0 -> 196522 bytes docs/management/connectors/index.asciidoc | 1 + docs/settings/alert-action-settings.asciidoc | 7 +- package.json | 1 + .../impl/mock/connectors.ts | 10 + .../docs/openapi/bundled_serverless.json | 167 ++++++++ ...connector_types_generativeai_response.yaml | 10 + .../connector_response_properties.yaml | 2 + .../components/schemas/connector_types.yaml | 1 + .../schemas/create_connector_request.yaml | 2 + .../schemas/update_connector_request.yaml | 1 + .../connector_types.test.ts.snap | 365 +++++++++++++++++ .../mocks/connector_types.ts | 1 + .../server/lib/gen_ai_token_tracking.test.ts | 53 +++ .../server/lib/gen_ai_token_tracking.ts | 22 +- .../lib/get_gcp_oauth_access_token.test.ts | 172 ++++++++ .../server/lib/get_gcp_oauth_access_token.ts | 89 ++++ .../common/gemini/constants.ts | 27 ++ .../stack_connectors/common/gemini/schema.ts | 59 +++ .../stack_connectors/common/gemini/types.ts | 25 ++ .../connector_types/gemini/connector.test.tsx | 203 ++++++++++ .../connector_types/gemini/connector.tsx | 34 ++ .../connector_types/gemini/constants.tsx | 157 +++++++ .../connector_types/gemini/dashboard_link.tsx | 51 +++ .../connector_types/gemini/gemini.test.tsx | 85 ++++ .../public/connector_types/gemini/gemini.tsx | 62 +++ .../public/connector_types/gemini/index.ts | 8 + .../public/connector_types/gemini/logo.tsx | 35 ++ .../connector_types/gemini/params.test.tsx | 206 ++++++++++ .../public/connector_types/gemini/params.tsx | 124 ++++++ .../connector_types/gemini/translations.ts | 109 +++++ .../public/connector_types/gemini/types.ts | 28 ++ .../public/connector_types/index.ts | 2 + .../lib/gen_ai/use_get_dashboard.ts | 13 +- .../connector_types/gemini/gemini.test.ts | 192 +++++++++ .../server/connector_types/gemini/gemini.ts | 188 +++++++++ .../connector_types/gemini/index.test.ts | 89 ++++ .../server/connector_types/gemini/index.ts | 53 +++ .../connector_types/gemini/render.test.ts | 52 +++ .../server/connector_types/gemini/render.ts | 27 ++ .../server/connector_types/index.ts | 2 + .../lib/gen_ai/create_gen_ai_dashboard.ts | 2 +- .../lib/gen_ai/gen_ai_dashboard.ts | 42 +- .../stack_connectors/server/plugin.test.ts | 11 +- .../server/gemini_simulation.ts | 53 +++ .../tests/actions/connector_types/gemini.ts | 382 ++++++++++++++++++ .../check_registered_connector_types.ts | 1 + .../check_registered_task_types.ts | 1 + .../configs/ess.config.ts | 2 +- yarn.lock | 69 +++- 54 files changed, 3353 insertions(+), 28 deletions(-) create mode 100644 docs/management/connectors/action-types/gemini.asciidoc create mode 100644 docs/management/connectors/images/gemini-connector.png create mode 100644 docs/management/connectors/images/gemini-params.png create mode 100644 x-pack/plugins/actions/server/lib/get_gcp_oauth_access_token.test.ts create mode 100644 x-pack/plugins/actions/server/lib/get_gcp_oauth_access_token.ts create mode 100644 x-pack/plugins/stack_connectors/common/gemini/constants.ts create mode 100644 x-pack/plugins/stack_connectors/common/gemini/schema.ts create mode 100644 x-pack/plugins/stack_connectors/common/gemini/types.ts create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/connector.test.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/connector.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/constants.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/dashboard_link.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/gemini.test.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/gemini.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/index.ts create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/logo.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/params.test.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/params.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/translations.ts create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/gemini/types.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.test.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/gemini/gemini.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/gemini/index.test.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/gemini/index.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/gemini/render.test.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/gemini/render.ts create mode 100644 x-pack/test/alerting_api_integration/common/plugins/actions_simulators/server/gemini_simulation.ts create mode 100644 x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/gemini.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 322780e137b67..5f0a5a3f4bc3d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1497,6 +1497,11 @@ x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout @elastic/ /x-pack/plugins/stack_connectors/server/connector_types/bedrock @elastic/security-generative-ai /x-pack/plugins/stack_connectors/common/bedrock @elastic/security-generative-ai +# Gemini +/x-pack/plugins/stack_connectors/public/connector_types/gemini @elastic/security-generative-ai +/x-pack/plugins/stack_connectors/server/connector_types/gemini @elastic/security-generative-ai +/x-pack/plugins/stack_connectors/common/gemini @elastic/security-generative-ai + ## Defend Workflows owner connectors /x-pack/plugins/stack_connectors/public/connector_types/sentinelone @elastic/security-defend-workflows /x-pack/plugins/stack_connectors/server/connector_types/sentinelone @elastic/security-defend-workflows diff --git a/docs/management/action-types.asciidoc b/docs/management/action-types.asciidoc index 0d8f43925a1fc..d1dc68045110b 100644 --- a/docs/management/action-types.asciidoc +++ b/docs/management/action-types.asciidoc @@ -20,6 +20,10 @@ a| <> | Send a request to D3 Security. +a| <> + +| Send a request to {gemini}. + a| <> | Send email from your server. diff --git a/docs/management/connectors/action-types/gemini.asciidoc b/docs/management/connectors/action-types/gemini.asciidoc new file mode 100644 index 0000000000000..d1693f0b5ec28 --- /dev/null +++ b/docs/management/connectors/action-types/gemini.asciidoc @@ -0,0 +1,74 @@ +[[gemini-action-type]] +== {gemini} connector and action +++++ +{gemini} +++++ +:frontmatter-description: Add a connector that can send requests to {gemini}. +:frontmatter-tags-products: [kibana] +:frontmatter-tags-content-type: [how-to] +:frontmatter-tags-user-goals: [configure] + + +The {gemini} connector uses https://github.com/axios/axios[axios] to send a POST request to {gemini}. The connector uses the <> to send the request. + +[float] +[[define-gemini-ui]] +=== Create connectors in {kib} + +You can create connectors in *{stack-manage-app} > {connectors-ui}*. For example: + +[role="screenshot"] +image::management/connectors/images/gemini-connector.png[{gemini} connector] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. + +[float] +[[gemini-connector-configuration]] +==== Connector configuration + +{gemini} connectors have the following configuration properties: + +Name:: The name of the connector. +API URL:: The {gemini} request URL. +PROJECT ID:: The project which has Vertex AI endpoint enabled. +Region:: The GCP region where the Vertex AI endpoint enabled. +Default model:: The GAI model for {gemini} to use. Current support is for the Google Gemini models, defaulting to gemini-1.5-pro-preview-0409. The model can be set on a per request basis by including a "model" parameter alongside the request body. +Credentials JSON:: The GCP service account JSON file for authentication. + +[float] +[[gemini-action-configuration]] +=== Test connectors + +You can test connectors with the <> or +as you're creating or editing the connector in {kib}. For example: + +[role="screenshot"] +image::management/connectors/images/gemini-params.png[{gemini} params test] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. + +The {gemini} actions have the following configuration properties. + +Body:: A stringified JSON payload sent to the {gemini} Invoke Model API URL. For example: ++ +[source,text] +-- + +{ + body: JSON.stringify({ + contents: [{ + role: user, + parts: [{ text: 'Write the first line of a story about a magic backpack.' }] + }], + generation_config: { + temperature: 0, + maxOutputTokens: 8192 + } + }) +} +-- +Model:: An optional string that will overwrite the connector's default model. For + +[float] +[[gemini-connector-networking-configuration]] +=== Connector networking configuration + +Use the <> to customize connector networking configurations, such as proxies, certificates, or TLS settings. You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations. diff --git a/docs/management/connectors/images/gemini-connector.png b/docs/management/connectors/images/gemini-connector.png new file mode 100644 index 0000000000000000000000000000000000000000..fdb3bb8144d6f30f26dd8b654459e2d97879c89b GIT binary patch literal 265115 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

2I=l@SoET~ANTp4-#zDh_uls(27@tJ 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±F0rP- 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%0DER}*(0lF4JbqX%GJ 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ⅇiL%V*+{)CS`Q2D&Vw<_!Ia)E!qNahk*Q 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 XlA4}5c;)pa;*W}=hC+q>+mHVbjGkVp literal 0 HcmV?d00001 diff --git a/docs/management/connectors/images/gemini-params.png b/docs/management/connectors/images/gemini-params.png new file mode 100644 index 0000000000000000000000000000000000000000..b08456f5bf3f03053e02f8c7d6b5027c84beb08c GIT binary patch literal 196522 zcmagF1z1$!w>L_62?#2n1Ck;j-8poZ(xB2gNOuYhpma!wq!Q9OG}7JO9Yc5A?fIYY zeCN4Wx$`_Td(Yl)?e(twt+j)d6{T>oo?#&%AmGYKi>o3apg|E3Q0pglU}YIF7^G|mF)_C?MnI4bj@3ZdRO=#1)rpD_G0Tv{gke%~`os`uZ&EZ%N+W$H zG!#=ViI+f~V1D%;tRX?n4{~bj&z$_lLP8wlSn^(DKFg=*y8C?ndcEKKp7%J7eWQQY z9Ub9oG(nDxruW`V+5!!qu@MN-KhY|+F!@}75L_N>P&1?W(62Djk%kyOd6)h&5K*jNIk4<; zwQL~!W0&GtS_WU#PuK{rEXc!n$Pi8$BXUVUm1P9Fy=Y?=OBKQJL8JJ1@8=gR0A&YN z`g2i1jjz7+zHlhL&q?6T>RK|w|In_xDnX+OdbDPrbCC? zBw2$UA*F2@n6lTyNL`B_B?`PqPG1P&EWI*V8ms7*OLnV=tu^m8F2qcZ((w$~_$+Lh z1-xvbANMu64ZbDkjb4IY;m9g~X=lj1;mH=XX&%6jJ|rQilM5k?H9U+Fs|G#3a*4}( z!z}ZNPCvOP7^>Fh&w{MtgX)J!A^o8bg-Dc{p!}5Uq=jEXiGC4*wG+)_G0O-|Dy!T5 z^Fbm;NOKy&p|6pdZbW@NehBE^5&Bj)MI^4iN?M2tUm&0wLEO*7g(Wte5YJT(Q3>?& zBFGu9K=%nmsG#)DdjP+5;VG?AX3Q6d!Iyf5gHcb!aA*UGz`zA@f0bej!go`Pd*I&WA>t8qt9n*42r^YCIn3C?2h zEbR~C6XE-$3W9o6e>3%9-O}wf_ALhGW|Y6Ii%=;Q;*GF6KbCexcMPX|tX1UQ8%{Oe zo8eIw=;n1ca7B47Fe!Ow70lFz_kQD-+9c{O{W!wrBxb=Q%l5FYgTZY#Dg!i+fE$KVXO8y@#0rnGOYO0?y;?2^!jHa%4t}ZgzNs9^=FI3#S0> z@%xvPNKQU;?}g0}q?#FQNpz7kns9ANi&B{nkWPG^7uo$l)Sp8J3BYYQC6eTiG(P)Y zyrh&Sj`GQ(d@9XFC7#vkVDwxyut4NhM4vQnDL(I)WHDyYUZ?dc<*Ic^61^b0mZ6TK?225K3ZeNV9gsyh%s0$Dj5+*Pm2}HLSJfc8|3$?ymQP{tQfpvsAZXr z@r;?W!|Vd>!jB~1z8w=A)8W*Ao6e`>Sh%e}cKieXt?&=?pS*b`qrZR1jK$?yYw+hg z>FnXg%2s5csgC3ajM9ug+cw`u-bQy!tS#fyNy!zGgQ>#wZ+~3L;g$wgps5+wOO{C1 z{6_rR^9+_~q(G(+M=NEYW0Jl8p%1Umiz#tjx=^zasjyv}zk=D!(K5Q+x*S~YI(=MG zWtKMXCEscm$3gN{E=g)emLI$`Ou0R|{maqLvD?9Er+n*V%VMW?CudV}sBly;XC^;r zYihIP^yoBhdvBsH|6FE4JS~4P>AC)UeQ90wxNqHh zJ&nnVDT--bd$*(-B2!|dX`)qBYE`*g##R)O8khJ7?nVfu5dHzA*FmQIOvDE0$h{|I1 ze2FK|hw5|NrGxDy3PlS=`CO`8?cAV#w|%2$ z@T<6$%7+F%di$>8NSY8mWTkJ96!t84izU z&f3Qg$6NL}!pY6aC9bq=?Di(duY0tPO&$C2l3<2-#)|XF3mdh)daUPr^`ou|#|rBM zsrMK0zYHwoM&;UQD6l<9t#qL*#ILP%Rx8csG9lUZ!=c8^#%sm~B=)2RH;${tmfjSa zQ59L%`5VKyJW$QJ zSy->|{dDXZ_ss9iuU2`gUX$BhZJ{!DeOiC2!Hr^*H)B>>VzrX1;HOZ<6=YphT$#_j zAU3O7zP2?UQ@G(}c=N8T&rD~kvUnz7hToZb*DU|=NB)#~y}db;He=!56sOZf>|Apl z*-r8{7kp?&t&(&%cHgss#c-kTHu5?N{|(+KMY)isBh)Fc{CR$w_QFKO$l%ns@kuY9 zWn24b$VkS^eyPeAoWk0!^5>JoD={m_;rPk)LPOrF4yEVnXZam{M2Ya!=bl$?avpLs z37za41A(c6o?)*0ZLW>SQY;s`JRXssN|vHFvajBSkAoZCZ@lvQ$_npFC)R#5&TAx2 zOI5sRd}ez(TCr$pT3l9aQ2WUK`>n}QpALl~KOf}K#&My)@pfBrC}qIebm8SJBdpl9 z@y7Sie_MF>esW}M%60d{LF>3waQME^x{%kQ_|dA|#7*vK?%F_a>X<{F(~CXKy_zGB z-s2+DOwu%Wxx3M;vhD1-9)EAtyRm8R+Txwqi?ODib_mXbmG{nFWsPvreRG|kbJ{|@ z*PEMPD=$}8YLxQRQaw{|0#1zgG_H#k7N{EM$mpLuA^6lrep!rw#+Vq3+O)HWpge+* z-hBMj_{;JQ9Sd~1_m$M5@Q3!ND*6J5dH(nCL)Za42iXUvvvi2PZTSTi6ow@d#Vs;7 z8@RowrQlT*^O#Bi-74fhQ7Z!TPC+G^*Bg4hLDH!{*F3P-h(Jl{p@|+1eG5bsA;y|A zCJG7&uYhw51Qf()2&ljrBJdSLB>SIpNkn=Ct)V_rphsqk|w7)t`y}=kuR+8oQYP-cA0Tvp*lCdEkfsKS$skvGADiGut5of(U|)xTv}d;_e)J@~Ajj$00iZ zE0RPIg=j63sujKFqsQ2KsE;2j|4_#+{-_~do0m7a6%uk1rfLP%q^Ej|BB6r#cxH}& zV3#(2*W`S^dS>P9LZX^Fx{LbKqf63ES(Bgt%gTNAn zKm-BtUq8OoB%Kr4QjjG4gwLHfr214Xl(@kdP;&Bd43G~3(m#Gg?65y0XDV|LPen`n zQ@Rn*oMW%=KYC~yXtCDgX-tHi!A)%{jtu z!-on`J`#jR-5VdHJh*-=6f|)@kU~-@vp)2k?I>br8DfZ$ z6d#$%3C&r-y=#%&{e}-r)g;OiK|)~8XXJ*R9U!iVPsRBWTH}8gjr31e25ziAMI<6P zEy-6lQ?F4L$$|w9yAf=a5fZE=aQFNF|4ddqlR^t(3l#>*9`=E=I-Y)1e60BpNBgdl zVqidTz&!zOM8N{=AEl3knUwx5Xn&RsLJ{}CcyLUA`6f~ViGIP=lpyGHar7xV{|;~%CyAQ$JuRQd5#U-6#ZQZKnl+8Go28uLMM^vxpug{VT0Km1-gjgFXrcZQ)> zR3zqvB@z7r(f`A_)rgUMqQrP#QYlzRd4nF54IdFg>^4lOm|#e+68|VUq6%T7u?@vT zf_nf6yPK&QUgqGS9Uojd#59k0uIf=F0fFo2r1-zd0O%G?5IMnASCG{kagmrdNVLv_ z^2Y`OI4j|cv>}zZNDNmmxgeA+UFPw>^y;4lgD_F3kTM57z$WUvWm(ocAbS*XnFFpG zi3d9&BhiAkDV`hjONwRi29QpMLv5micI z+WVvr&4fWB4TuNphsaBKO=PQ|PCD^JtwlijC>YSFZO2b#59*?E)Fa2ep_wpdQjRuV zfQ$R@a?n-Av&|778oZMR=@YOc0^%s*HLD7r$R3=53-bagb99t=#wsMiS=wQpvWyDU zO>3Sg`Vddq1&gSQtl|d9OA=#2<(KT0@Ox;gdaWPaI}9TUA0K)~x8%@=v=nuQ4;^Tj za_y$Id&r+2bAi6<%R|kxUcN`BO8G?3u|a^S!lzFz`OvDP^Z_fYs;0Kv`WaB?L;c{y zr>y8Ig!Rj(WL`vFbgCJ%hcdQRvs4eLY;rTe!n>W|8H=KbqhIOmo}W%YI1nRcps!;1 zZ5n45#UJ1;9v2igVuI{%2WBTDt@zJlsojSYjw@vYjyi}4Xr|m(oc`@v@F*i~p@~1k z%TD~XfdR!EWt6?IeMXSI-a{9!r_6TSJ^FxV^7YpT*@$E{M;s^l(4Tv~Gx_Ety#cD- z^;4}mr>$XsV8NZ7NJ~ES#3);OyuJ}#fnqa+e3BwDmh)PpU%z-9G9Jer$xP_{kfiwj z5YY*s#2`=zu}sVD{y8%{xHlNb`=Wrl-reTu11xN(4SEBTEtv}fbixRWp?C2FtPxEd zVEyYKswK0Zu4iyIDF1CvnnbAx9us6|eWP6K^*)R57tOj)-~_B{zf#-P*E-{BJXTXT z0!K@OuRiq74Yd1M|6GW#F3ln~wEh_H5y9GzbK+wYlir0_?Caj9?gX3-=~=q-c}Bgp zL9zy5w_)Kiw8G+Lv|5l|U8G0nx_s7hx}S3K${{dM`f7Z{+?sIX)m5l1yB2T zZpmaJ4&@tTQ@0x0hCiSMZ4pqG(Zu@{tc2oTy7x$PV9NZ$?E$&6QR0^mE+$RbYi zZ3&i42Nd3atD~l7MiG&iEO-Rq<1G`ux^t7cGMeRjV9Tks zK~8`Jx&Cr^v-u_yT_w{1ygofK4`#Q5XV|_mQVidf8NL4fN;UYyIvcv2^}nf$M~H}& zN$oMjzHTW}-Zx@T&j;eG*!?t|tCvmf!S|r#5i$YKV77!(zOXlMoRP8C0`A?4u&YE@ zalxYk5Yex(*>(v?nAOOM5AmN73E=(hHrYjW6WG@r!TLF1K{*5W%x?%vj~^urc49&S zR&KD~l89k6pym$vr+#lj1XKr~&&9R<*8XjL4PpclMuK^!)%#Txuwu>rIeTmGP^g)A z7BBk01-PCO5MWjLVoD;;&+C;L=qg3-JM0@Cr^#=2C25#xS zBbyCX985*>?`RcKh~Ud)i6CUmUOvDuMa&(E_+g(@&Hv@#dv-!kDZ3K$mBhBbX>mJ*n^)c|PZn2rs>?z|5+ zld(qSM^$wmAy|aJ`B{8PUt;Na-`X=oouS=B{8gLZKdIT&Obw`wp7}F&KKNkZg4F>L zZ%i^7js%KW2Cy^F5|Eb+uQXM_y$Oc%sp8ZAoAd8-SJ@D4{w=tOD1=M|i_jhp zMbJrrsS9^-gIbzZl|ic~^mY^LvnJ07Q{HmWy-2d8kzU+LbMC5j+@a>=eEaI{59$D{ z$MS=*X8(+IKw5y@;~gZGEk!)lW@g(g@m1nkJwy}9aLafuX^t3K26_IQ2q(aeFyW-* z_5PsUJOKmw8{Q61Y70eaBUsdF$HAlTtHHkh9#sofN=jSvg`ve?{%O2@{dIhNHW3=` zYo_h#$?=R$=xg#)C9iOn^u_0Wq+6-=mIJ}5A~HMN{AGC@+>OWEM^mPZ##^OpQ+F=8 zV|kRg&yu4H_Zs+51*d9H>zcS&%tiq?Fn^c-Y+VN;SG6zbY24rci_$;K_1H2+@81{@ zdJO{N5aJa=Zwic;9IrjquoEySANPl*#vNs=H^OmaTdpgsBC4DtxG#oGdzF2Nf81!M-cKU;0jmD+RjV`j{M)FCL zfPbn<^fVD5q|Rg~NZ|0}g%Vz>d^2sysL9!gz@x}bP;^)%+CE+RESBLz?-Y?G7~&xq zbh7>(DZ^HY%3gYAY^9cmG8*#!C>1NJ&2d$)A&Fto(~e`- zdgAg$3?)jzXTYr##`@QA88iea$6yk?s^X==(18Lh9GA>>Vp$dfHfxK{?}8ClJgaz2 zrdX%CupBbtY*Gw!&yD(n>4N$V?qUs1?eQKmSTL}da^szMH5XB|rOt5p6{c;xVYr~A zNuP^ScO277952~n0|$$4b%e*=REOf*aSZATgtXHvFV9(lzgQ>{BoqNel^X>w=d7FqMF?-u`@OqEaCJ39B;eMp@r>KJa$91<=_X#<~C#&5i;ko@;N`-yc6yyU^W*jZO>=_LUy7-k%!?jJ40H@10 zkE5;Jv$tcsD>yaB{Y9#^>iJC?9r5eFuZh=15ruYK53-M>|HgA#gwos~J3jzy>E(xL z-~W95<`~zyb2GwjNraXO6oT=&mub?6J~NfJlmPt9{c(7D+|o1vHz>1>WtH#@tt3QZ%`2K zQ|i7X12UJ_>;WF;sZW`E#S7te&GCvnnHe=?rZ+<(sIowhJ-V7ct+cnXt-@WO#u>0=Ke- zR>3kECQ+@G`1+h2=z4KD<6(DTR>)DO30GS#_`g6<~0r^r^%D<|{;416(#G`P9O! zY>TtpcAR$VVh>VD8cuX#)1>83J#I*xu*!zU<+Cc4Ig5kub8O z&*7FO6>4~YU4S2eDR=nmm4n3sht#duik5>lY@D7PuyodtEGzvzH+bWwyh6NDVw5UoaQdX9mYG zs7*iDxm%LTG>F?dnya)vnzn>Y?xnwQUKpFum_4{bQ-!&48fd+99xu?NgE!v$T3z3{ zUwX})m-gKV{q9Xtuh(Sd-O7s2QcRg1UYxb3_P)Eh_RNooA=YZR0bg3JZB%-C?x%TQ zX<;Sk8`8+dL=e&_#%XgZ#j_6-umq9YNe31Y4b)9lXviHdw_EXh-``ewZlrmh)mTl} zYdPIjkJN{*dB`sd0~Sb4z=s zy=uO3h8SwL_Sg^Ad{v2jo!l^Y1I63k0$^bL1a{}t&D*@CxIUd-+pPB9x>s*Yv(yV* zLUi4_+U;%*J4|z?@@lUd;+XZA(~7m%+zn8%NjTDiGwqJL+SlsQaI>8D5TzqPXX95Rrt(-^vH{uhItJhgyCD; z8lnRp(a18mPSRB^kK=BKs6Qo>Gcpw&{ZV`s8!T9xPDR=w9f|6;<$6s+Kl($fRJRiC zH)w?!OU_2>Q}afI0V@%XMc*KaG#0b1;hJck4+D#ot-AseqNl@*WGAaDXV}{(+u6># z8(c|O^Bk_1YZI%j;X;bVwSx1Nd#A(2N=m$kZA9$q28`zEhrcI3o$)1AS;?H&vt`Tm zC~#NA?i5?T>>#&yn7ulzUr1n^3gm()xJo^DIasQO>-uLsY7OetqD>B|Fw1kO zJ9q7#oR|Tg(4AASb%s+tW>lB1Dys5pC@wMV=#gV-eD&1TfbX?YZdg^9bya12D;|IE zOw63(s;S<_wJOoAhjCk$7p(TI%yI2;e6Hofrk|Yg9QT5_U^t1#*_PeZX-}~ocqYl{ z`iw%w(L~W(!(ue=`CG+*ZRICqs#`)0Z%b0bbx=qa_8#PNom5MJofvSBuEo!Yu}~RB zMOBOzR~DSz2m+9vTF*RHWu_sY=b?bSFdx0?mIo34cp;?J_#Q8< zm{MhD8r472PG!p%1A2G0!?HD2mnQFeJ%=MhZs|54|KvVU;B<6QzE6~x%1lMby(h0FXi z0&{q5$MY9Yj&C}V_3CDsolkd&w5-lYu%U`SRlwQ?6I=(g=`Dd9X>{My$YO0UayGUF zG^-YdIKhz)<|xG~=P8zG#^QS2 zRJWtx>NCJXP@o;J>+rSVP+&rlg!PH3{sIx9U=R?XrW<8R`)8b+S`kyIDk8_-V)+P& zhU3P!P=<3Olr~2MzR~7hGF95aF#iB`Zp@9~quPZpECHipGOF@%_zyv(`pznw(SzIN=_ zc5)(F;Oz>V5t~LaGI(pl+4hr~bQLfp65^ilRB@knB{edYqJc<||CuE0s{6@M>I+dh z0k{wh9z%zYi^<1iGd0PrA9*}rN${3VUu1NtQpaew`Y^$3e1EQ1+F;}*z8`l$1cv<-_-C?=*l|!K#6O38e^t7>YQHFxToQW}wiw29-(xzs&R}r<2Dl90?0T zrXDH6b!$PCS6=)MgnYr7?$o^YPt7$~P}t{{J8%O|c5;lB;KNc68ysow%H;kx#veb7(AccH%Ohk^Su> z9W+&U7no#Jk^rISkCVV&mkz+n73a(bU!;tre~4>A%T>XpSRY6+-Z=c!o$Ofe)0rPV zRe|Pzyxtq}GK{Ci*#fwv!5Yo~;&m#^T6Zk2fSkJsr{z4~fu;$zA*#W2|9~(&3Y)o> z!zBD$uddwfdVeaj)N|J?L8dwY%3sKL?b%_omt);YomkX$T{(?M-cSx9C1|&L;{il# zf|Ow||H6VifV~eBPd*)YZ0sD~A~WjYuCs!EbiX!>Fzi1>6M8y7FzBi{)9;vkTb{8# zj6^Y#&W$l_I^;<<`>n!x!73M3I>+zQcqid&)0N5|S~A>vLCqkv;+88njh-{)1r2A& zT9pL)kyO2pG+eH+vwv5$NLPzN?}z%RIbYX})<$wXlcA=Ipn2gTtrA8x_8)C?NwUCjG`; z9H`gz9yf3ClEl-iUZaz;(?S1px$7jz7dHo_OnO4BzX4E$Ab{79-@0QlrBpUQAG6lu zFbjT)kw8uT1Bjdq#1Ov{z1q^=AUuNe?*(?xr89WI(w#=|Kevd6S-0N2Y5vMQw4^Lv zqoZWWpAlKbIBCBV^+tuZ%iTkZ4ZgvcK&0dnM%0v{7nFx!z2bIwrQ^bMSMCvMW?qw_|hmq*V8(* z$#OG(mQllFl|PQ<=JMdN$$P0Fx1Z|SlCz0?M!LoNf>}Q>Daxz_;00etCn*t+mD+pke!+@xqsU@K~?ZKpcwaQ}vKW`K{qn zhb}RLgnb+`AyqV?E&PT0*y+TbS$AgxhW9O$dMC#m=0{0Kjn~hiPl>nKw{BfYPtE2t zzgE#()E!f#^a@D!i30$gZMGM_(21G4V6I5omjC%iouGZ`PFYc$e{cQ!5|Z0vHj7nT zz*1E1HJ2N9;JKdFkc!{;2Uiv792<{%h(E=JmQSoaU3VVJlvtfG@Q%hM>s?p>V0HfFGQ@Mpq22?~GWuWDHiP|X#qyxwplrJ(}V-Z!{Q zZ1@K2I`C8kgpx>+)Lmb-pU*j;vKC9K49A_%Coxk%;8E`ge#MUYbegLoXZ|cQ-`~9& zzX~`9Jl0*tnT3?9g@jirbq?XKZb{=zYlj`rBLPQZRKv7qywL8DM&V;1-n758doxcc znk?iC1$q(9Nx{kcRO|MfGd!1G7bS)_oGO`Pb{m1z%oY@b-NGiATt z-M7bo(Ou7Pn&OxvpUN|?W8^+*rj+CoiWi>e>+3vKZeFJAHuaeGwtW9LWa1*Qe54WH z&s!B~HDB636H_-g^V!AuY;%3zoqO3c74T1(`EC-Nx11+nM^|Jk^%4zx%}Tf&h!!Us z?6C94PsuI5AMP{32Hf0e-R^Xv={gy5W6tLqQ_lxm!@KOi8yv*CJ4*@*$`@IJ$o`|cVO$lv(sF(uNg-4C+zbLff8eV5YtbA*&|20ns%>1!%KNT-kp1E!C~He zxFs%2vw60i`6K_q6vR!rEmEuyRsK8bR2j%Xy)r(}eZf+-la4hYz_0z>YxOW4oJlz& zm_rxJe0{bTJz_cb^=aUr(1C5eeFJG`sO7B6;R`QE%KXZY*tBZ<8ME6Hq)cZ7AwBwQy?%eJ)b*Y>@33q3gOO;uA->?Yl0U_XL|r>Jh{%-&oInI zA_s1&#(Eiy&K0~KVX^g2TTO<6bBexlwp=$fN%qJ~a5rJXEj{TLOO{l4q)VC=FTTaW zmGED>dk#1{7!;dM4$%sI&Zm}?#@f>On5Wy*?ig0$j0Tea!D1q>h!PNJ85WB zg3CEl4DZ+OK)$%9MG86q!MrHUxE^;Ph2OxYp4UxNEVqCC>yA8z{kO6t8~n^MgTk1V zF#i5R_?$FL!RWl~v}KppGOFF})mfB{9zXwE%+=3R5GpaYV?!NW+J*+&Z5Y=j{+A17DlQodO7dEln!6mvyZ+Lnav98^oh9A7 z;+C!mD>DWH9bd;N2GI27h>~jAJ6O}kU`yvBjY+!$-lnctl_OLTXC_Wzp)(`sD(KfS z*Cl`*$Rya6_!p2GxV(F2;1=vI3pg^Z!5_eBb~}T;)3AX;&UM`y&TK=f+G@j6k4Mw#vK)U7CTnPU8XWFZZfd?m z%Dmq9R@Ns!wo@*v%vCkQPwx!b3ivS1U#Ohnw{L!kl<5L%pGBMeYqlJOjN}XCo01|D zGjFYWy{A)t-*orb6QJ@krI26+bG$CaTWV@U<6Kg1KOr}rN*yBHg zc`ASv0Os<=JRL1L|EM_XRL(P-3ZeM1pAW%0sdqX3J}pxhNJO6yRnDd0>1@F5z)eMJ z=adE-SH~Iah`E+6&U$_4T5NZ=Jpyj$0AbFcKNfSfOCEzLLMkH6GDl5E9IG zuNu73o;qw`v)9qWgf1tb^eH`dHQ0i|Yszv%@fJ2-1GLo8cN1l<-9*ZL_4mTpGXSHf zM|PO5GYh@EZT|9=i=ay#WE2%eOxA{i%S4Lh$nkpk7p?VXjjfMSf5nH$8Yw#EBQ)WR zh>p=A(*rb)944~6&jS;!ZVhS+bNKYm)6Oj~-NRDT&o>M9j$O{acaKC-QgkbA5L>7n zi!Vfca_jch{0~r93ezfGX-M_<`ho+X2u(R5q%5>)9_1VWU4H4Dr#d}hf+Uos0BYnK z&JsC3QQ>GKXhFf7tgRk^Ln6Ry2F0P^qWV>d<_&@IQUZMrwk>r!J6?EiGuc(acZU?* z&bOELJFua(4*S&33y%}Yx&Ycn>c5Xj@X1@>%IzvYpFb;q4ogS?id?3Lp0fmN+L(Js z3tTjLR&MRO7$nqm0NUVC{)9av?W;?V@cqq8;~tF=E#sTXi7Zin``HzMxapU%vqV#W zXH+5}(nx3;{sC8-h>$iqlrQ623bL8u4eaH!7AEdAlV3*R?`I`LbM0wu4%K1lZ_w}A zf*B%{D?rM7aUt@p`%atl9@p!?=D0T|kCTr**AD&C4lXObHfuAS>er^L6NEc^X&gZA zSW`(D7m;d+LqCgQl+FvsjXwMsxI-0Ar=-3e^#Oa3E&4yv1WC;dz>`cmcNrXzq2I9c z&aW=V8{*?%0dzeg5KmN2QjA!zxFmsl8=Ku*eQTQNPAb7aq^PlZ)FbEkYa} zg8VmpdWs%^WKnx1*txqhwUVsxDIo~NQ>~q(#O;_q<++hWXOoKz0mjs8`a%lp%39n&J1GbyEUl9!7qHk6qA))r!MK!o5 zfdVL%R@_|04XYRQ6Z@c&C&*NFeFYxiY;p=n)KE)75D|Y0R|p-`NXeX zKK8B%-`C42{?wvdKkUqa9a)H+bbeRr%ri~Jb{L!&p2h}H1J`2`>AEDF;HlC0pF*)j zN?&dpylxJqv|uLIixz`# zbfs9AvGY!tx3OH&@4d8yLs!0!+3gi%?M9L`i22!pn!5^)$MTTR%M8GxF_udLRT*xL zhi>Z}95C5=ms{gPlIk{Wujz6d2LDu#+0-hhIc~e=fOxdZi~!_)I7`*sGk%c}Zb(e( zi>VO?fDKt1j}m8R?!7!$^RkUY*V&8?n(~fr8KmK!bM8vQH7jS68Qq5A_%V@6=s{f5 z-=*BoT>dzn#f?JmuIAR+qe8ig!ew#6W2)Ww53Cy zqDm@q92Y(VlJcJ9lJ{S7^02gjZ6WNjH+Z?UqCG(T*$pe9V(#ng#DK58pu1nO*VpLq zxOWxU(=~x7Cq`O-SW-qNQrmPiK2088r`dC49Gb1(6{QkXaXv`%wKxKZTqP;&vFxZo z!2|D`p%l|LfUj)ea8{*KcR+$kz6=pa2A*f4hBb71wH!Ln)r!%RqKc!4!y?5>- zIJP`vS&Z^a8Kjje8dfbDH8pNHPq|hv8b!8Buf-!Ei~U&)G5R?cj#p;Ob9+`;s(FWC z2l40r(>VT)k?kt3=7>AR-!%FnS(Ht65T*Izj#tWyJjbSM$_q93b#TO|$HR;bY;Z*& zA7s>0J+T&})?L@$czc#K>vCLpbl8zrYb;7O^_ZYg_p(OUYmHMh{+BTvb{#kRYxQ?KsR8|fAiHXqz>)O%;DYx(Q;H4z6(5df!CH}*XO?CBjAsyFxU%qF*WUIS zwTCFfRTjWW6uA2O9!pw(T;o+rtxBsJ4v4FsdX3tftEt?zqaGG}C*uofZr`?sEEM|72%I zuGaB%fdB0Fd?wp9l#A70O7MQKidJT>*3>153Up-t_noBoZSpaL&kM3SufLut%hJ76 z%c@OaT)Q-tq~3mhJlc5S-T5n{q_G!Y zfLHedAh%2_HgoU{qwLR0vmtqlF#$aeayQ5{4jE6Ig$CF^Tv&HG$J_P7f4K(;t;hvTcehvm_o}aZ17lpj0t;tFE$=Ivt)%ING-Sle&)_+w&T{9-h~q4yB*Z+|V04ksYe>a@w1wfz-1K*(}_%_J-zQJ*>e@Dn!$J9kK|sm``&yT`cCM8?bYq6jzeiA)e(YmgzVctf%ggfB$wE>whL0Mh+*RqpH| zI8?u3x>i=?oeF8l2KUx{uAk`IJS)#v%gVtNe@TjzDgEf|Z#V-XB>@0WlZ*Eg*t-qA z3=>*&|h8d+*8oEw}A=&9ODQ@ zTH6Xa$JWzyLC;ceMBi-T#-VtPX@Cx2PfPYk(mdGpLsyrNG>i+vB}mM4Qa z)-*V${?;aNUnQuG|9p1Rz9eg+Gd(x3J0hcXr*-oCPWP7a z&`Des3vQ2}B{M?m@9fm^@e9-9k*Pcz;0-ghr24ZwCgGsM=%H-MuiI>{%RED=Qjwtz z#Uv)0e0#nzV-m<<+{}+mTDJx8n=LxtD$(y&tXng=xeoAgnuB*h4oi#vZ-uL!CV$lL z0KYd|bSaA+OO@gEJLjaYx1>)lmo-XlR&2PdO9Y|v_KFcJDQTUUA+z(~%2a)RChF3T zmW`dtbIpT6`*m&Yp_|gBh@w4n#X(}58TGt(%Vy^J;O@0ZTj>|FILr#PV!98 zt1yRZl1voSwv*y%OIaxt3oNTr*}R)uI>ArpCo)bY!=4b9b*Ss(Ly5PemELtSRXO$! zn!Y3{z}wOGgZ`<{%fzNp>GJD=BUf-_di+Z0Dt3*!A>{}*^6+HV5 zn8~11RgtrFajNt0dJUvZ5NG$_0OV2~kcmi4V$`d~`v#5iLamoN@+=rgnY-W9Y}^R@ zG=C|mworZrJcydlWW))!BFI!#9m*HqaDf=drZ^4i)4??G9<(}+U!gYl8H~@xl&#UN z)&nF?iIq2A4lm_@>>F5?XjtFQIhr)Ym%G0^-vHj)o6xVk0h>O&Jwp~v#-5QJBKq!UpyH!2;<-9nP3{1eAfcTW#)IPW-?h^hM72d zjC%t)maS=6Zf{am(~Lu4W!j6|FB~E@^GBnY1~gN&1Rn|6po1uylVu_31X5=(Si4gYX%m9NQ%^yOFQf*%HSl zs-;H3={X+8T8HD$*~ctK&nh-{H{Vzpc$N&4I`w|zm9v5EIpu~x3I!c-drJy@FEVQo4|M|F=#hF66(O8cNFJa+zFww>N zg17OXl-ABTd=>6}7e^E(tpBHq^G}_{GIL^ZoSLetQSMVGo1Jm%(w%rcyVXdkZW+21 z>TKCK`AI>Wg$A(G?j+@m^9|?^*xh)4rvoIsUrU6LM24*Q+}~W538BZGDNj{eC+%J= zp%3kB&2mqJrGp9>O;U@+g9#gyX^D)`-;M#`h8joP<%f>&Bma_K=T1r|<~%}LoMDl? zU#^g#Z>0sy{b@w->tU`?5{8e$q`B`3BGz_{CQS7d8b$`josOrbOXfVn@TzFrLsN*a zJRUQ~y~XSQ>&t_n8B`>otm5N75MstHcwI_#$FV?413iEuEX5ZV%E(k?gbBZB3(-}o z=^}|XQBZif5JGhJG5t{OAVN?LhTw=t^xyy zd!_mhU9DG%^SCD<*;$<=3$e`n(B5S6C6UgVX!=^Z2+Z)4ck+uXCumr>_@>yct%I&D zl!c}wdl^PM?&o_98E<}|3I-JrJ@6_h&l406M3s;PQ?ZdC1NngriR1MEKaB6TAy2za zyZ#^c-ZCu8u5BB>P!R+uDIX(dmb)+zdyczIvWG)TLI74E4MUl2`;TjR&Qt=# zhP0rTtHFLwsRY5H=>h;@fmswwTz|0tGQWHvNnkK7L{_ZkT-FZ*1JDT7E`EOtag0$l zg4&jqRQ?rg7xI#D;S^*= zMCZ_oh+qZ&EHQ(R(T374j}lx<%wa`6AhWUYY#`V&7b$xhn~lV{`Cu>v9$k0A8m;Yx2^CXC&XWZNrM#`- zgbNTiB{2&v>nPul+!AAqy#QJ(+4OL5lJ1P;^`E*C;0YZCwO-?cIEEx!h1JU;!&r@Q`IGTUn-^X=ck+f+yhyTY#qcXl;=i>A66 zJc2?!*;g~}(M8H1vGiw~$FjaMcD;U%J^oE+a&|n?rlRmKgNFguNlz9m4ZyY+0#NEWKe8H{zMNU)kXq}A00++l4E`1-Nps1VO*tcO;;gLl z?+)_oGz#GSug*I+G~b;aNv#hHfatmKSzZyPXIPF7`=dzyC_B5U9u};YE%*XFG;VF(19n!M_^;3AB7rUKeq^_*&p2!@H=SG`#&Y2f zy4RyqGNEiv@GN-LU$7sU3`%BZmG2{axZ&yf8D)T)#|tn7v*w+j&aI^iHFa=aKF9lA zxpWmkUlp-F9`kyO>|M?Vj6no08Gg^ZBwzk~O^5_wwbaTU)DjX7R7UNdtZXC9*&Co;W;A?TPix^av#|rTUWb&<6HAe@t-&*e+rn<+!TQ&Ig_rE(cR0 zKTNUv^0el>$|xr2`+v2VudjhGifLiS+@~s#0Mia$-v+=;h_pQg@LD7SMAy&TWo8Oh zz@a3m#U(%)_w&SSOpEIm-%k~@wWWKe{<}pmyMF@U<75eb!e;o#18)J95rKH}U=VpS zqulvtBLSGKU~(Hie8y zPmFcc$pH}mCE0&kiM+9u=(}Xt1~Olb@f988d8Gfp9UX&xV1KCiI)fa~ z%8ja?vnVBRU{ThAZx@c)LoQ|~U6S+t<$}5L?+3(c4lHS_`6}|e;ly!F1@wp) z$h;m2(VRIb`!gY6);!(j*CV@$S3_S$);qFAbzjtMx_gFu`sc68WCKhlN}jZf>rUh> zW>>;I{zz5*_aBcT0*(UnRdw$AzXv6mKVEkNtFTdsX!z%koMrSfjHgceB44cHzdsJ} zO#F9&85h8VI12~+pLP1m{CReA=N=eE>!}B{ttmWL4q=V}I3tNoO5aQ89Hb1hz=f@g z*@Jq@q$dG0W3kB&kaM5)j|=sBzzQLVTdpMM_#6tQQ?Hk8?QpK{MQa`~5v||;>27lF z_GSYoMaiamPDEf1lHt7poIxI6$i$O>^2xK#m68oO0}i9{vq(?>IXsUdVC}sA4<~P) zpgMT&uwo_SvZrB9W zEfXNlv>ayeqzbzveV`W^7idr9W(Vr-XUJ{0!6iS@{iU1%2TnYL`RCsP%l$Zwu|^x! zL3K&Y=Ec)?%RGj=JSj1=!XsK*bn{_-xjMH`=7-%2FduXh*O22r7mx7+MJ~NZKMk8T zh6x!1e=Cn!U+8+;5v#~>$EH0&_?w;4DU(O9NJrFQ=sv^^XfrUrTDoo_o-T&EciPc6 zZ0xNAdh__LJ04VacdQz#DGxCDFboI! z5q-M+rsxPhL_)KA%Ki!xAWE2eY{?_|y>~Q!p$w(sifN=b^0?8&sqt14TF|}0ZAfkV}p;5!seyu&ZyN~vi4oM zw+WMtjhnw!Jx+o`Em6M#4BK2~6Ir~s$P^29fyaH7l%8KHMFcrKCH+xEC4mbKJ~SDh zW+j($&#YMMkv>UCsa@TB^Mwt~SJ{N$jVv&WOOXDp&zb1iVNri@aOVij=AAH z*%oo@@$F>91U>(&PidYzW0(myr1DU){@Uks=_6Juc8w%}WjFSGn-{)KNyTt`MI8NX zststn3OkMXTRmyMiWxy5JMDhc0XXEHZz@T>i>S;XCAX#0>h6U1vlb9pGEvrvjp!hb z366{OEX>5#S!Z=b|9E`__>k~t2TQY>b16eWNaiyQ@-T*hOjW8@3gr zygh0rtK3Y!ijth#93a<6JmM>17n!^V-nQZ!&fMfje*k-YeF*?XK=w#(?yIbhlyLV* z;%lfmO-Bt8c0G&^Abn3Ge3u9U!_F8e=lTWlp`vqaZ>>6!-*ea*c%e%UcblShDxW>( zG%9|V25=m(u*c8%(k%jy^h3y)mIa@WNH%yqyrW03hbgJBZi~wU*rJ(j*A*G>=$Gil zmXtSq?~a(0oY`W}NbnClV$;oUoF%Ch>~$Q-Pb@3;&(E%-}T?g7?z39|PRn_WD%E$lFEW#fdjsko2p=c#c)sM6B)48*-ZD*XWg-Di`aO-?z*3&!6jn z^uQNR5v6Z4=vV?%>M{aR(li4_H@MsPNa;r#AQs-q_A=LBT9g?JLb&v~U@jmLvcbjg zVDh$x+q9>Yn!CQZd72zXyN`PUf}3sM5E$4#F1Fmv6>5`NvHt{^K1HElO`{~|mvWBo zG>M}%YBT8zes8thW(NS-wmt&%6#ket;$$Ik)KPU6wk2IB*Z%r}Xk+PCp3Z<@_bd;f zb5rHsXSp}}ZrlVKz`k#{1z<;G`fXIkdfW%N`5=dT*cK<29){GzZ??YfYh2UV&R0v{ zzXBAPwzbm9O4XZw$8Vhv_Q>}f@KT(9liIetpK|8E4@9Wqs@UZW@awA#PgId8PHw~$ z+jJ_{=MYoC5V(C^r)slL=kt#j{kxIz{?8M-&4e-VTFl7wNt+W^WOrOF?-hY4Oy#@i=pDw-$0_xHCsr7e&5=o}yogpq?@!V+h*ahN^vKI{6Hqio*{WG%puyXP#eI*V z0*~MC*+H7Iyk_8!%*$p_wUfz}OhvOdQqiALU>N;GM<|oOa}UY>i*8Z7wkrbGc~pg< z)g@n_sUc~uw4LF;O?;msWBZV-IS4JnJ#j!qafCoyEK97&8hs8h>{J~o(R<1WD@vjk zJuWO11EFMR4ced+csT&=5+%CwpdRW)TAyvcgx>bQcdK~h?mqfa0it?iqA_LC{dHiu zz~Zg5ah_E`rQLd0)b&tqd1{eY^S#pPkV_LS?r#$-p1!ff1@q4HZ+nXH^A-8p+c5q% zZ%Q5dF+-|@Mf1b>2w&=S2ETUrO`a7-lKuXA`3PHnhyGO8^iQO2x2R~VE)Dgl$q0Vy z)Eulfoc?4x$?u=kmG2YfvxU;l2AJdDumBze#K)~6Q}b+wr9NxD3t{!ydz)mZ2#sJH zm*oIhaIU+iKR`RyTs`(OHBKXZIgGHr2k2uLbK&*jug=XK~*evQQ}z!z1sW}{xN2EgY<9FBG^ zeWc+Z?%ZB!4;G5JN}vtWVK{3-(W*>vfhBq;{%uHW@AJD7Y?k0bd-p0N;3JQ@Z;N^F z;1XVp_wNM?JC81{H8_#7<~Is`BcsU+eoPQ+BHA6&U6$=xy5s?XPu8>?V?FOJKRlu| zh733ky05mZKHi?~PVfKKNYcL^Yfb-QH4`DM8eU647uj49^g#TY3hSr>Ho zh&)?k$XpRr9#CX)Qri2#W9!<%&NADG#faEux-U3xE~!U;@FM&3$3RSLbJK|3kOb{z zY&Ls~d^8s(AFoQg686%*Nh9Adoy>p9Y+K-IQGZdD_qy0LMT~LF!QxZ=-M9KY0}tu~ zjzCqQF1mxU0e(A9^Tv;UhclGZG4H!SH&%74$!urRE|lR(GFuxH#r>iy9%}{1leF%m z@vY^OfqPNuCS`?@E2h&ttH*0CRnHPn{B9d;L=p#EPt{FTfmYpI&88kLzss@Sxl7YA zy>MhPE-kodGAC4%fqKgekOh)#7Zd6x4*yez{Zk#CmYIK+B8*12y`2x=DQ8f|_89mr zkqIn_$9zi%7(R?bohg@PW?SHnp;7%AoawObFyfd-Nr)w(oQp9uA?mi9kSFarb$XBD zqQZMq!~~`c9WmpST8kld%ENNQaSQKS2UyKzwlUllZSW&BK0U|69r|ycJ7@F|X;){3T_aZ{bDI{HH+>rp0eF|kPW|Em z;?sz^oReYT^JsBt7MFj3#NE$fWFR|K5C_zs*H0wVT0E8@RzwRxcm`UB(u#Qumx=;O zVQ=L-RLg0uRU_yryBtSF&{yLikSklzjWVgsM8eQ3cNH04yt5Ay^!uUY>$v&ABApOx zH+J#|);4*sgRFXSY5MuTPqI(4h)=$rFoB-A89x<8*Pb(M8+1&?Bo8C$ zP=%Hhw_Xpu%|gfgA!F-sNB+o+vdQek`dc_^c0ME?CL z7CiE}-gC5kdS$xzvX;h-gU{{>0)fyLT^`A9@cekTaOqVVW@Ze<>H~Kmz1>U*le>H$ z@s@V9&o^|T^XgH=i-HDxhdIx|Y_xRlFfGns(qr4=D6r=6;wc{I0yxK>x%zkfyvI^j zs90C~*rH%0UBAmu_6|SKkJgGZgH<@3cGLV{lstiTi_sI@h{Y*Z-v4<7%3kA=oMVB- zM;Z=_ef|-G{R1@8X0bbS4q_4T5E+;#3C63;s`Aw}Yov>VcM{*n-xG&%v zp!dZuWKZtYyEE}#6=AuU9VzuDB=D3-h?oH0B^K}rfZ9_ zlDk;nV-8}D#>4rzDYud~yZdTP4H-c!SLIoOok8i;p9Rd#VL|p? zEBZRWMy(`k`JuFX6-PLdnIg1Y&+V5zaC{qg1!BW#av4rNNG}hD+oNgF{6LPx@4Tzz z7JJ|HfeDvE;jbhcMH%Wn!rGl@uL5JGFAb15@`ZhqJ(RoypfFed##wF%w2Y6!!BD@0 z^~+;bUM0>`4eAEvhZ2rUe3FJ>3Wtxs?vDW)iFG}}Sm(Acr@9DX%b1lbHHva{OXPOidW^}EYWJ-u{kMJ)@bMtu8UB5GRaPpb)mt_Pk&C5DOP zwT}A>40y%5M@_U`- z!Ei)XQQy*{LfgDL-NAU@orR4h zpd?M2BG6V*2~XgPzxinS=eE>#01E`5B|3)mV5c~tE?9@22dBM2WE~>BQv;Nj!5n?ddlbG3va>0WQiB0Wn15f zRP*#x>3;ot;sB8vWOWsxmH_M(3$%O#1i5aM$ zNMg6fUpo^^_PAV%ffj&iR5DTePrc%6C2|P*GNeypJwaWQ6)mNfAVT#o z2NHPG+W{Jj{QEN_{;o!)A53`5n1PVCLuv)QAgU1_XLQhBrvc?GMyX=|w`zTn7Bx+U5k(B+$fCue+FBnvW6Y_yVU% zomx2%la5(J+rovMQCPl@U)Ko&f8DGgiX}V9^ZY)C?Iffev?}^5GiIvNd)$QnNgM`{ zka^!`5R(qfd%3#MDFVtxZtJ;$9uT?R0fpyy1m|g#B2PPwQhmWR!f}Qc z0ewlEdDd-|h~J-r?3am1^3;<15ulN2_xSs!HKRP-f03GcH(CxP zF2nI8bV2|^4bkhuJ*@DJN;84G-2S(C>FdQe!4cNq-u%S06=W(9K1a0=sW$*H$#Vwq?6A}T>H5uu?E+h+k>`8=c ztcGo`(9#+6R7tK+eY&G`e7NVoZWi!!2qCJt{cGRLVhpr}c)24SMqBl0^W(ljkqWK+R&~L(T#Za6K@6bg%786b;2P7GN|z$zTxtfwwgbDSU;Wbx0fz4M4-`d+;2Ss>@F!VO z`+G~#SzE!SrfP?EE8z2VgMP$GwGY!TZEAmpmXp`Luy-g`8Li?VmfLa-H?BKeP=OQ& zF*EZqn_ZV{2xI=F7t0bxy?i^DD~sp?i@F%=9dvgyY|?Cp*Qd?Qqs<@h+q&M}-Mtau z{T2LW(xw!*EXKsx+qN!KZ2?Hr5|w(80?MRI_$!1hK>#TzaMV zebC1Eji>ky72lmPyH051ive4QseHIEkUulN8z|5iUc3N%wH4=g{8P@T=GA-sbkll| zc7&w(cGbs>gH~;;+CN$vLQ~cy?C={?5L-8BOaz3tP1h(R?!FPfYFCO-O-w_{+BjTM zie6M<169v0;);q1C1+}H?Flg|EDV1Ma$UcbvK6k|Dqtg0;C{BJ=G=bBMxX73v)@UKEwUgPvOO=!v12(?( z61!pLOHId{Dagn6fm{AKy@GB}VAsMyn5!6)%mps6y+hl3pX;!WH0=K3BOTn?n4C>O zaxV6R`>R)9gbDnd#_ByGT^WVyL)afX9kv7JIJWW>bW=^5Bv_-^pu%NbFt9k|VoxF; zH_aP9g@f-;^;1NA>I!EH1}O(1-5|DgML!&~7%eqxt>cJ5`tVBi(`TRFnUZ~8wW6iq zF{)An?L<{oIV<@uySfD=j$W2iH}@YXwhIPDO?Rg8&etwdPTYEwL*X<@__)zwE8?)hqg#Z?p%VSXV3LItH~irq z3C40LWx=K6h9WwLo1iZ<@R-eOMYz)0co4j+oryAjs;_f$@T-N1rei}AT(clm1J(7SU~G9&D=&|^w>PN;asZQ!c)@M1$1{(WjQYE5+DW8uVBpC8Jv_$k_@z@ryvC!pKW)V%S+-=n>qsR z3Mqe^t>1YeErsS5#dtu4tTPow(v+&q8r%&K!I-3no0ukgUwk`6=PKYF7sOpo%-Ne_ zdQBgjeD<#}yBek^-hH_7G((g0IsRY)7snz`4F6(RK~4(hHDHD= z?viAcMiUFW82bkd<;4xUTbi?$y#1FAlLwM-@n=xiskjZv{V+Q3_GFvGFMSvdtgUxR zxf#Bs5g%X&J5U#oToCuT=d9JzVo1*7#XB^x5^*&?n>4dvr%0X@Hav6WosDpZn%=+2 zqR$u~u_BrUqH`H*=$ce>2ISd&0ZLKXNbB>>0+3N>y2!L2Z!NH+MH%<_M%=7NRaLsM z*>9fMWg4mB-5Mw~ku>>O)@Dt+3oKq19Z40v0R>=_Da-einh|u4yuO$@P<@VF30L9t z)&)Z1)}@EqSekl%qF6^+QkzHHfp_O7M77}%z52fFar3HIS##a#9gQZW+#~tx;Bh}$ z@h+PkgF!!YU1Y|o5NVAen{on-jv_eNsp%PTR{sw$EWqK zx;sl)(w~De@BNakC&4|+$7{=_#g|V!HJL&*NcHVth4tZj(f7{QGM3Y5 zn($7R4$LYw2js-^Q(6>o_M8QzXzGD%L~pvVfBy3&y*f1qhiOFFkSR<4PUQE?9e0-0 zaKndH8e%WkEXN0>McnrFFGSoFg48+>4Lj}@EpqE8*r)~yqD9K6`Lx@){#ZVKOtbeT z&|<(9ySO}HH&<|j8+T_!ucydPB`Kj;pG&n!C$C1!&Z$P!%=seAQ18rLMVqfdj}1Hl zc|Tcy>6M%b#6b23eVIYT6pY_*v|wN8k&{)!FOqNHF!jR+ZQdJ&nE4Ln5#HNuy3LW8 z;fZ0{7wKZYYW=zI_dTB0=5?2Zh`rBD1 z_emFIML1Ge;uo~quC>Fq7#{(|XR@RKR&B`!CoK;$jl;Z;)7#7x8Tq@n>^xl{qw+N?KOklGCAVp83n zySfv~TLT=-#v;Gj+HeUtblE!GO>`f6zxN5t#LO=}cxx6ayuBn5Yl1s`SbLprM{fA` zl~~bL&5kxzsQS+Z%^TN-?x*XbDhvlFv8|0*WFpnLsl1~`ZaRBuXpR%c&wOuf%A;;* z>`dU_*D}BhX?TPL2X_F)-+Z`miz0s+^l{YM7@JAmA6xinI{wzS{JEX=iE#-@!?|YM zYMeF+tH*phn^CpY{MwAUA-XR|F^)@rdyjvCZ};&&j>+B&E?(y{40<*Pc2Ly+FRB96}R<@oD8?;+v5})2bVYiXVfhbfT>N$;TsTiMU7yoh5iMe}U%m zHcz3sjN?X@6O>8Wz-8mp;aGooAf|O@Da~PSX4bvlZ}#;&N6FMGI~AVtw29=MqO*8} zK|!%V2#zJTAtM~D1a~AIvD)=y#OoGlu1bDz26GjCo%@jAHUIVXTLYJLaV$i0+rF~F zLHNJBbpK!E#U?-C>-fOT?`J%AHm3M0;9E&UdHI@|8YzOVtTrl;IHbnqws!rJ`SIFS z121#`y!UE*plp5Gvj?hwwK6D9fTP}W%V6yu1w2glg4PRfZG!%lL}_K9nUW^?4)os> zjQ=6__3I9>9`bMZaJEB!kEg)fNkdM<&96$lRtDp?W))O-oX0FnRSD0i)c(P_Y&HV> zv-lx?n|6>v7K^apP>f`3KvaWya`gc@B z%*Rt)%fJ8z=%>u=W! zJh4?j5!>%e_{*k$T|Qk4#nmuVZ1!0NJSc&9ZjOM)} zUB^Hj*7%o2M{Ie>y7=>O%M@Wm1V|00?a1DSYw|c|ouknEb+~OMLOFqg=B9bpa@|P; z)4h?6ckNxU=y}9V;-5CkCBgDW{RIg@*Em_Nj8DD@{``DSJO~PsB|t_^ft~^)40bd; z6#O`b@ZJR$9fE#nb-t)GF!Bv?kbJ{y3TB45O2om)nXwuR~tMmn1p$y zTxCcVX+8>+QTN1a&?iNG;*jbTCHi-pKrsIrfx21n5QVQi%yk|2Fd=_mQ}v#Teg949 zjAX`_SDIw$FrMgI-(X5h<)SV_y}D-#oUtNiPtr0x&%xozP*O27du+;7IAKX#4zT&A zjXS-M%XTLcMVM>#{KX=yhZZ<3&jb`l|JU~a*T0yzfY*~&qNJ9nqAd#PO1rj|kxdg}m$W~Bp>gre7s_)2w2~kY z8-$}BkCP}w-FKqYi+o&@_!1r)8}zKF)3oUSdngVH8Uf;ykwl6E@^Z(wYABCNV_>am zR%HL)ydNqs%k<8_pTU(^9{|EnV6tX4yXm_+8o!b!zOdd(v{B`I7F22lZT*lXgY2%o?Pr z$Mw{sOM>UtxkRbf;lZJy9Z6*qbHBdHQZo1{zu_}a@LcRxwzn^|?nqMiSnOsK^_+`Q zxxuZJE>_E`nsopDj(NTNC5p|)ud^-Dc^XrfJr>lqkysKynge;%prDhdGQUSMbM4G^ zyowFdye#L#6w=0>L)N}d^xS-#W73C{c3`)o=VH6^{^0S3lOUtNpL_*mwXT+QcO3FG$ESfWAl;(` zF+*TBHpPVmgRVf>a-82$2Vn`nrb|s}h6zYyr@UThV-n7-UosTuG{O*SE##yJ$&w{n zKIxyvSnP%d2e(BV^96mL1%Of?nnHJ!hf6hm!$p*9Re`(E813RI}FNbbhb0B+v3^d4a$s_fOa5mpI*cz zNyurqy=b6dex^w=PQZ>#8=E*-Xx>#U+3^7=*?@_5Dk`9LzJt>5&QsT^1~yTTxtK;@ z?CH>GZXRM0cesZ!VqC!N?_p`I@fngH%Q|7EU);6PM!2QEyKOfqm>m(HfC~ha=G*y{ zK7Y*~7q{P}JoafegWgVNV0e3pa>G zP&$AplLNH**W-)1o&{vyc$1Asf6Wl8?^hWc!ebT!rCW-fmriQhR_x?6OU?CD9&oibHEg9q8ued6%W! z%zIdI{9-puEnQgFpxpGfr%jmx0BOrbE5h@%n=Z#m_-+(#omAWksznnHvFa zYi6VJJeSh2QxZo$-;$p*>vIfOxG_m;J#@s@ilE})U@JU+C#egWe33)3M>!qeLlxTf zt+LOnkRONY+_#M?-Sy3ba~aG7a!uhiZus&?pujA`~P42X{hmn!5*n3THP80MMCjHEHO)g!)vd@L@)8KDp zR#@UG_0W(haj445VA1;U=cz1&UncSw(S#*-XRrFPfn+QLp`3+g2FG-dh5aqEqRSsH zWCPiP>Z;E~2cUM=wfNFIPd0Ri|5KoawxlBi&-LrqG05kcW2AKqw@Y>;EsC=JMC_8R zTVuWz7qbIR@-hqc3@)qYD5w}jfWDZ$wR2fF*R;N>ThFJs8?b@xMXHHUSyrKVx!|Ov zCWaIZh5^Wdl|tY>bdB@uHcVS))gLqEQ_WgwuRXx|dwaPE-@KHq*V7o4-XJC<{c(Nk zbjb8MMZY<67@OxSE0cQ-nZa+S@PW|@Jf`7N(p%vK(eMUid=JFu2Gw=0{?nWKuQ181 zO$_X&pp8pqC+bz-EO{G0^FFRuh<3Y)6E4y>{`Syi5c(;0tY8$rWUxxzWK z5yWx-zG;IOdRedHj^fDvQKMU)K^I+A@uOPJU|AmHTCawY7`TE-t)HUasFk__>gzvR z0I)~<9u_zm;y}ucN@$u3*b!#=bJ2P%j*0XlXU_gkyTl%9G(#7j`Zn~ir*1UQ1qZH_ zSzU+l+YF|;T)j&{zoD+>kY}sk2}&eM){4Kt}Q z&!;wyZf(DV_b27@U2w}w9sV7l@^a0T-QdQ(W~XvSTm9*H^oRNPgAxXA!Y-~x)T>@X z)>(87y)~>aWdvXJThoefkPOWKSgsC4lIJPnUHis27koIzf9m{?-szwJjmf>_caPa| zZ~pln_ni3~iN<$iVd0A!>{xK3MhqA#>5y879$U}K0a4uV1ATb~dSNKD9T3Xzn{+Elk6~4D4(LJSre*D|MIjyUJs^f*RA-8_0LZb&@$rXA>dxe@#cpb=;@ln+J78qlo^# zb2brbF<>s|z6dDV#5@TmZf^>W-d^1p&&!co_EUr3)4ReygMG38IbRh8MF(vkS5{2@ zQSf3mgx`O~TG#6c3pj8&LhYTT7gmaG-0E}@%c_nyt`(Y-bM1bH7RJa1-_DmOmCwKF z<-bDWoAZC+7?7F#`;kl$rInhsOeXOLRc^@XZ)D`!a52TZ;tBClCZ1EPoq)Un0G zs%hV1Zn+@BP6i!#wi}E;LQ!YaweWBGB8zbfV zx^zO0pNOPZBnI+(A|L9FA$=4}!CF6Cz&R9%wB5u=dg*U#&ucJyyAQ|RUk|Z?ch<5O zm{T|BS&ep^SaOO%Mjbc1Y}P);E*$0KJuxE#*4rOnEO>MzLQx>y1OMubyRDd`$Ys$Z z-`|x(y%ELhz|AfugA{Q)H*w-pw%bZBh{DzftJ}!}{m2t`vgn7z->e#h2li$UZu6%@ zG|$Q*bGd&B5NIcAdUxdXvR}opQi(C2)-=v1YkQaKeJ0{>0)xH{WDR-*8odpmP1f(Y zPJ2@`eALJf0k8Jgzs*&O{jO(?TedHh7{c1j9M&%||G<1Tfx0SxF!ov}Q}tPEC1^_% zt=^-!u~WEbHVA30Q-#&JSpV3}s{4tVYojVME~`sJy5AX>(tq&c`zwd>?GN?`dNSK9 ztLiz4B^Pc`9KGm0hRj2FgO&1Vis=|ji1m9O;O2pWF)qP@-y;DBImic1HFzhzzPO(( zY__k5)ma~djcod-0*Q%an+3@;$6%tFZM?+Dm+*YONPJ?Gmw z4|dkV>NE-Eaun#1>|H2FE-J(WQ~_Q1vgp`lIT}9mxJ7Qm2yfE-3pXl@gZijDQ`*r} zu!^qG;qK>3HFhJyK!y!nj=5E#uCEs6)9UxS^nbldr>$P2)AWsNXPWcGDb(J(t-2NLwe?Z2FEk8)9t1o9^OiNLM%)tFPbiA1=5LPQ!$YPvcS3;>kPxl@|nX}cgr(Bay|3qiq= zmZJj|Jb5-=C0tcT(7*XUt*}J#Na(zLEs)Qkz^zrC9%gVF$B$LOt{C53U42NX+eh|* zLknIEC@_`PPYtd=k!6}7En$@M@W^v^`MuGaD53G3n!*Pyo}|HYqy&vDm~v zL(I#VoTQAHM|jXwqS(;P^rj|41jxnXnk(eU>C{KWf6WG99z(nH)k`$zP4i9VVMy6P z#uM4o0^Umv$YOO1x?-+p%6A1@d)*mtZm=+DukMkuGARWzHjvtiki8{P=94iB%82=_ zJVT+^(J^~ZjLvG_DS4bu);5){hOxvBL56&>iexR;KU}vf=02?atnJj6$pu|v*t0_B z0w})?2Qr379H*cecccJz!4wYCZI$yU?Zp92%dsy@cW! z$F;CA>%hI%NV{ysbIod~oCx1uCQo!*>=YVjV~@HW7fCBXx8Z4+MSP@@aV-uQF}H_j z8jiaR@0eQxVLw=wi?s^+h|Xgxha9YoHkVwxy;6r6MTj`sf9+9-`V79ED0W%u!b&)UI`Dq7W#Pv+#lpO6LsO3kS=I%!}ER0j2ybtJ@MY>phCJr{fEcg*?4qDu(+ z>UikO7P6{bsy#QB?dmc9KqzDyv9HKwqX&HaXJqPRr z&{z9>pmA+~&dO!CEsCsSRQr{|{RdjYE~a);Qu#rxKz5FmuRiOV-Wb-?uwN|gmuU*4 zN?|7F$pTXlS}WagA~IAu4f{noSv_=v73|fv8nu!?)+eGau;6}H>|Yq|1A1Y;n6^)v zxAouSq;izk)IY3`e%5V{I(Y&Ngx$EphYA3Ax5VBg)vsGqTBZxXwbzRn`AKMwIR@+k ztnjLVIas>HdO8YP(nQ-a*OO@JSo9)a&3*m~7&kL!5Ipc%*AS3}F53g~82;Tvg5D3u zf`EsOLM?JyXeJn1e3pKf)}XD}q*PqFT|uST$@q{^4z)>^%$IcIta!l6b{Y>l_{cjf z?%*lsX4qcJ=t=m9B~O>Ud@~7KSB817I`~|vpk&Jcq{_^!z+n^6+k|qC-PA%p;W;*w zyH_#uKPni2r$u}ZCTSa<7I}I*P&L&@sVlT~un>BsZ77%BMjrhR6{wJ?bzRN?cRL+%j@ z5wPz(9d)zZ%;C%a=2iBur$kHDMqvI28VsZDbc7k}GnmQwvMy$i=T)_j4*#T_L%C=czabMMXoTAw466f_QvxuI zv}35(2+#~vIXpa+JID$w_8Q0pfc8o|Yhzt4%|gs6Kp>|**@G4L+Wd;(GL>;^_T`&q9WgS3_Olfyh3~s`268m{BJb60)3CUsz6TkjBG5ZfDo|S zlq%t;wr-6}4w_9nKyd%3gSt8X8|FT+FrBBr>g}z$+Q}eMM^tjBK~M76bY6q!Aw{1VL_Gi?yLQuvXi84=%gBAbCWAyyUE>T+BOT!8SRSVUBLGoD zi*NSuk;(10Xq4lG-7!eyN@VlQS1UFyO^UjWf)L+mhrL{D3MHT4Yaf#H-(wtz<2KYd zMS$kMEV9c3?t|(N{L1dV*rsxyK-;fTL=vG2#lh>EhS;noh1SmG>Mp!>y^aBihharH@$i+f`(97a8qI`h{#VB+TGIqu zPbtQ1EVL=wmMogL2ciW1?1L1njGr>dr#n;bjaA!3Z0WFTq};b^@qZ4@(2maia#^k= zIy0sLM@O5Xi&GebdzP?jW=y&xxr32zV}Qy6!s(UL>%%>p`JN6|r{RKYcxYfneCdG~ zd`3$1k{sG+i3M3|25jtms%F)Je79R0SiLL|`ylLjjbNdLX1->s^KRs6gbjRrFk@|b zCG7VqeDC;x(AcfyvBD3~So;lC+_Vk&1_L1s=I#3a<|GjP<_d|DR>}%Mf8+s|y>1Tc zp=X(=O7roYYI^h0S_j$ru-=ie7O4=P^mD{oVEekE|F z_yDZHrh36kD73vguVdoqjhHY&tmC21CM{Of+3+ThISc$?yBbJM^*`3WXflRb6e`Ne zwHC;Rs%rIePMx;YQxq?^<&vrv91A*YY3e0&cMt({C`@L6u!MCVIaZz&Y*+J$_(bpM z2L;8?5wIsPyeZOJmcOe2@6>i{0PsBt5OY_1{3zD$ZH*|XRMr5f=82DNyV4w?l7_M$ zfevXLK>Qtbar;hVl{aRhPKp=bH`5|g%M>%B6Nzf@F|6p?$#s0CF4URdhv^H2=lbv+ z;Ge&|X7j&G$kP$gFW}~mclwJq$4N1-0voQOZ6YVm66{>7VVmiiS^j1{;hQ#IkKd;yW7YG*vBrOr+M8G7AA1g}g>5;$v8F6!^ z2{D#&2;A5VLf-|Cpvqn7X&?F(27Jt^k3u<38-yIWg}Gq&cPeM@+U!Rfg&gQTKM7z` z1`zr=>(Vcm$Q=gfaQ5^0Z}g3$*>LwGlK}F)p^B7Aw>`vsINwWkZ@Twe9KX$WhI2e3 zh2^wI23~vZFD~EJHP`-|gIVWW4sp6O&5crcUrjy3Blli!h%b1rO5PwVPb8q8DHE-J zI=4C4Nw;O1NE{ybWP0das6UDYG*?syY}SLcnf}wc!qV5|iT)SkpL37oTsB-47VUEVW+H|2t|EOGH_VFk4{Ts?_sJK* z$kM&B2e~g4WnS`gD8Y`G?!2A%@;UhwF<4|~f?4Rg>uCNFxCZ6@ikbUDr%{Ka!76=# z3AZKl1=ZQ@vPF@7(|I~eVjd#YYZd2z;{fdCN~cl|i(wWD;rmuj`# zhfKFuLywo-^Zk``UO>VD3z)T{${Fn>lb7d&l@t1SzsO>?qQ6Lc9fT$$1kb$PC;U-O z#|~F_=xj+@K8&oa*+OHZ_LI13m-_}9dG2$)#c0$ z4uHdqa@-wzE;`GKBJdwViR=+h_6vC$91hsu?+ALra46|aGH1ID#vdTq0I1Hs?Zipy zY?)ofQryhx#d3q_YKyznj&bEt0(IVM!iAP)1>DKhzM#L%fG{TUPwXoT-3;^b9bx?g80^Ye` zKXmv?3_eL6@XB@S-T;|#qU@^jM}WCBK-!2YJMkU&ksZ+!C$*WYcH^#qH&8~bt6Os7 zG1jhzt5MQtAxJF5p0{F7`SQ7kr0rKH?{g6ZA12bG=UcLiFURrX8S>gSQpy)fITB?1 zulUJ#mG0ahJ{7IbExET;jW==NE=FXf3g@mbpd%GrDwicZr$d#3vf48?r7pl78 z4yt?BTHb{7p~Yhd)745_cN9JcQd`S)Z&TTxFQ^Yo$sDJ7)n0X;$zMW&&WY)cd)Lhw z4Fw~yt)~B}=x;=P{RnHITJ|W)<#c5F!(ZKV2*f9f&01{dVy#^&%PJvY+#~fXK*?v+ z=l7?KrnK@ix$Fv&J0V%3I<(r3ExiDfCgOZ|*be72o@cMx{<)X28bDnT!^BfO9py(8* zS~9P}W~A$khEyQM?R*%QYu98{YG;=t2yj2Gwv;;-y>a<61H4kS5#A`PUkcWhYMx9; z0(DB$nOf=qRC3w4iuL9Xdq|&-D5J@Hn;-5>fK>IHZ;~_scjEfm%g%PGk&?ji*oIx3 z8FKRVVFx-aHnf{HnQ*;DI-U@JKQtq<9WRe;{S^kcxxN0FZlwYcBhezA!n zdi+jn5>UAM6Jy*^zue7{7k+D4ZxZ6XQ8S$=Q6X@r*E*Nl0R+wk4^?KvfLu=h=G_gP z;epRMaChBZDDaD!^u;y9U?u3Q-eo>~g;^N3H(9vH>o!qt_xEjX#t|TOaqZk*;4lGM zqUXwg2b*%n9&(18*o+oFzZcEE_dEsveYpf8^}(dlCIHBoC~E@l2sJk`M1fEa%FD5T zR#`u$$w$OetIhMuq|}LDl`7`H7sO(AYSb}vh87_f538}_0r&x9%_*nM)$YV>+-rAD z3VHl4ClUF&#&9*;N9GD(NLEkqCyU2Rttd_hQ*o87!@GUs2oFYs%wkP+*5L@7oDAVt zl7R?^7i++T7e)dIpV{ny8gTWp9cy=N7H~Dx9Q$DcSD;dqdws`!1cf)q~b{VmW*A*!xuqq>Uy6pbIq!If&?XbI8j#YF&j z6U=IZC|a%0#=~*4m1e`a7d$W@r0G$eL-OgP=q-gi9!drW0X#nXLx>4KKYwo$`!{_5 zjlKk>yD<(Y;irO;=Zumz3__f{Cg}1#b6)~+AR3LjfZg)q)pHj0MjXe9j^jFN;k&Ca z0OcX&tOjrPCr#%NZcmkHCH9iqNHiDOAKrd?cw{!~BLNKb*pu9s%o@nFCwBt5CDtVLVJ7`ZV0fc~K$sg6b=d~(#l#1CwyC>?$bslLd!<03E6qD%PVo&K4 z{ts-I&RZdlU+Y_Oz+3~Qje#En9CYsT4>-_#$K2J1qcTi2Mv})345cu?@REN=^NnJy z0N6CW|0<``pP!`N3SWGI?x#Grhu|?23aGzH*s=4lkOTX7Umy#70nr6R+;Kfs8ZGCc z%`mCzG+1(+=*%tWpn@yT?|+8h{QcCwe%9&?>A?qV2eR8OV_x5U_YSf`2y+&!6R%>A%vBjg*#?_D^|$RXNB@anb+JB*K1zP5zx4CQ3bk z+V_Kg>v+@bQE`?GKpREW!p>xuKUshR7T|R z(d#S=0N8Haq`h=fVm*nc<DD&*xTeAfHUv{F;hFv-YmAc)?v|NY`^^ZFES5 z9*81Y3P3tbE_~c=5e~)^zfGmK;pePlZ+vzTiVwN$+ zGur8}VCJ{L=LIt0t;qVQ>+t&{!OkQ*XP%r_!!PR{A2PIC!0JalZ{oWRB8A6t&gIFl z6v^X@u@t3Jiwkn}Ygtf0)Fm-g5rX!na=W?I8Cbta8vgfCwN?NNXq3ir%#jdBcp%BQ78G!o`-+Wo`5#+j%%6QKP$R@g+xLEfq&=2Q2?VUU*XsAv;Pd@PpX@w zPRXGWxiC@mJ2xa(^~9~;ZDkE$dz$4KYJ9^NsqkNC_|2=FfPgpYHYdh0MIb_a`8%m$ znC~>e)G{SlL67+Lu+m%pjsmg`oLC;~0bCLMSGlggdHM$p0P%0aG>yQ4kCsV*l<{yr z{uuLS;864BFCqW`&226`55@HT{1(WsN7divH&2i-2c`m%|HT&J83V)M@5bE!yosah zo&In@s^1d*-FN;;4hjt072Gh;PyAJO>F;sI1Jj^Q=5YAO7NPxM$lTw%;1_Oo<(ch( zhyw@;cC@nmj;2EgXl~TYY|XtG5d0@j!{4SF47?CN8y_&UY43#YcJm%6u|V@3X4$`6 z5P|>hY!ie`4%D$<4E1mO0rUNN@dndt2N|IwOJL@I^L7y<&qMKo0LJ`pXUy$iE<(b; zpRx0Qxd_bAk%2xI`2RiZ|BDL*{;LhppzIR{YF>sz2kbzLnDakW^OL@GXqfurmn4(_ z+Hv;h#lxDY<=i5yL^r_s%@a^Gfw}FF|I8W0^F{{zo2gx?1kP{2aVcIau1Kk?!tcJ5 zhaNaI21bDOcnkWi^)LbUVtlVQH}Ld-AiVs&EnEPt@1BmX^Z)yY>l-k$W)}p_2zdruY{J;}b{eSOE7@+@&-}Sc<9e!3BngQYeYhMC9eY!C}?C(|l#TH0? z7AY%dEX6)YD)qw2IjVQn@YY*5Qf0yQR>0kY;B-($Dy#NG2 z@Ns?nkG_bUfN}zvA!*0+NgVy+B=yv#5>MUK6qT!@$dXzNmUy6CKnP+O97F0 zY+0VncoHSh1h!baf~8c}{x@wGbOF}W#;SM+u82ZwDWu3=J`i$$eI2}J^o}qX(PZeC zERW~?xI+7W_&<#l^z%HwpR|WXOf5I${Yf6VqUb{XQ3aQm-Ca;PJrJxjZNq5S!q5zeU@!aRa*E2L{DV5cs z5Gd>oHx9o3MJeJhW3}{5!d}f2Ld>MlpZ~nmU}q+I_VfkBZNCA!Z?unn&PU$-QS+1& zZ<$mVPj@Hjc79;Aq$(&^6n88Epd^g}-IU6kE7~njKWO-fp%kv2d3M`{m_C(4tqa_} zshX-7ppY$>%4324N5M;)mzm>v!x9&X3c_6l_#%bmkroL+kK<6htAOT$Et%W(6}iE^j7 z7meZw-NBfNDQ(#B$O$#2$!QtbYQKeo;B!;w;i zs_Fft$3m1ST(^QH@!jDx>z^zQo0`ly3bjX9hgkriEeVuXvyJjf0g+eD zCT+Z|@EV;Zi%~H^#5)%guoOT+uP&zS{j5h&Vw%L{b7>g>B@i}g4;nb?FVpdIFsT{; zCMKl^dT^Yb_!%JlXQ$rJ5}rQUArL8*0O?i9$vp)yg6Fvb{qAB>V6k3{;9TvuWF?77 zUKjm3ATK!R2zs=b?>GNT4QDL>)XIM6TZdapR~Sy;c|mkZxDrlU7%nk@Po3_!0d#L> z08|$kSDe?~gYe<@ax}0+sbjie6Cm@L0HmJtPhP({--mxrsnB2NJKM5|Py$NGQbD-3 zAY&dd9fb6%1qJa11i89ATM#yz_pT*!fRIzB3O{``kfiJr_vDWY;HMeuSCLN>hQ0(M zee4r@%iY<1VU0@1dR=`qBwC%z=<}Uf@nya5AAr7r)8hXNRj*X2Z@FRskkcAkRp2T({*A)IJg z4rDSt*mg_mgm`H(-t}qg@|Uo{|6I6Q=bvNudw&oxG7bP~86Xthl1c@TC)fzGzr-tb z3>0iWAn0tw*C+@M94Adl17aNKo@!;fv6ifRAYpu^@@%K0KMS5s1-kMNE)O+o8~w0p z`yKPVu4f`&;0Y`~$z^?(z?-holGiu|OVwD`JOkBs$Lh0wD+l6I^{1Od;0?CdMLvyeapz7i?oUp?#1J@SKedy=q!|4{PBszBpB^^+ZUY?V0zK36gB6^2YmU` zrv>PzHMw6U?LQL~sgx<`#lvx}w3^32zVU!p>|Pu1fX_!~SxanXyX$97=qy zd%kB}_cA~$pq1MQpw)D{942XuXL~ipmjJM)dg(+qD+3kN21dXMSxl5St5m#B-($BX zil^7BpklX~aIY_YhJ!R)&=a}=aEcfzaB_WoRN=ixPH-iFWY0Cd{^xFSgbDz2+Vz?d z5ApTr@c+o0tTMaVfdSmxGaD3O3_s&Ti7)nBXe@0BvYxB$Oh;h)VmHVFw;U;6>L&M3 znCO>pY4hY#;w;9^`fiumK<+dJsUp#2UhnQMkK44=b{ZecJY0Uw(86Po?y zf<}P`HNeH1)^isn^S&_Q(SDKlcNp=%=ZIRH0NZeM5juqpxG!Q!$G>5!H9wAk?bQp^ zZ6(8TIg9&#S&sV8*Ag=RxeSz}&shk3TRtKpq35%gTGivo#cDU2WY=gqw}JYPalVfT z(4%N$wY&5As($$a{PcKN=6E!wlU79mG^Twn4OuMy2$(3;=;$!}T^^0+IhD())nxMj zAhz%J6FO)9Z;HeHI`p^cDHx9D==uP4y9uzkW9DVyw_ukL(&xUl@@9S~DAws6aM~KX8 zFE9teKYd(42sm`4{y#8Nqwz%|5d%K=!0E}+{fZvbBH(DObR}yqpBHE8zp;GuK@-;xMhGHtt^;AO`Y^PD6un&$iet)x4-B0;`nZ1~y+(7bpJDwQgZ9D12 znBMF;<`)RxoVSO{niHwuywy=kdPzfC;uq>2M5&!~SB@6lnVgp(G-?mb9`s`9by?)k zHW-f{3Wc)60-ul%g;S{$H7ZRdC=u}k`=^YiFO*c=$%;(Z7N2hKMNaTwn=f1G2H`rZ zB)Y08500F-5$sMq?vH8fT@T8=tY-D{sl0lldON&J`&tCOrOp8Q^h*8qqU*e5Gp*g} zg8N?XLL(|wfJ1I{X8qXik=8f8c<68KIm$kvQTqiGl8+iL6=Z#YM#=R7qTCiQC&e**>IBcuP-sE2(>k2)HAb9?j*pAW||J$K*-H%G$Hz zyKUDdYyEg{`|wHoD4CZQ*}x!*i!jNUMpMRqx|Cj{UromT>VTI0{N$GZ>{yTdKv(XI zZvd&yQKQpU74akFkuC@Mwzp>XQ}_a>yHr%39I-{^X2bw#YV3VkBjxVd*0+|BRT-F{ zet;?w4rtX4g7eVEI8IEG^d$NQJL02UeKI9LQ`hFNe9`}n14*MVjZA*H(SlXAF-}oQjLsatRu&V(&8IlQ1IsLNyBVUT{R{Z$f zV63=YrUuFY{pmc}B-J!$e1FM9L9L5Qg_5+$_&(G4aZQGKj|KcDYq{a=M!wL850}WZ z_6LcRo*K3Qyi1h|BkWBAZ9i|t5pC)oT=JqP*M6P))3i<$k*6E1Zj&~GC&rDlZ8Tow zaSQpID8r1o9YFw4Xc7ACE z%jqfg{!DR$pTgx4ToBb{&svY^q0831DA7`n?GV4Km#no^@H+N!vRPYAx-hTW+c=7N zkDy_p!9{Qa^Q2cXyPE6hv?R&?>5TLN^d=zKQjg7z?Lc+Aq4HC7_OPBnDsYeV()IdD zb3$@nQCy0A^VGtGPER@6qJst&{F>jz@9xyo?9(LLbR{NTajBDieYY6ul+d5b<3-|a z_oS1Q)GBYUT#(VSzm-zVf%d)HHWv4Kx!Y+!W@k=3xYp9nxups3zIi_StIkcqaZ4ns z64?yzb--6>pJT8@ z?S2}re;MsUyE&G=x__%<+8d<-K%Pll!CN0)rgJ}2n8i(0+P~j;>S2Hq*$gqaaSXdZ z>o6cb5NQ=?Wg?v8$V@brSf>X*SkHzwU;2?1KKx83(nO%z;|4K`*u9n`#eA!n^X#w= ze9kskV?}GTY(q+^cs*}3eg-!*ddydJm0$TLXzQYsP=5R3=q93(l~77TzF#1#&90%7 z--gRUAbUy$D+CO&v}SSJeqDoU-%oCbK5f^EhV;owS$%GbZslH9fq4jG>HI3sM1bYM z+ixQ$e(e$w@A8P3kk|cUGK@;aLryI8EzxdG`s`@?-L6FUh3C?W1v-)^qpb2b<^Iq4 zTlZ-qP+V~#dr;-gk{fsNExkC3rUDcE2=lkP4)vdi&Il-2mYmd&7YoCAt9INuFE`Db z5~!3~z%J%hMQYGDX2Wt19x7%-@ifCRqtiF5>V%ZgBHwJakxA!`kfH=tC*!)m0lpX94mBv)M==- zi$6FxZLY_f%%ZlM-9E<`K`iy}xe&g~=~~D+KWBogh*AbB*-?Gbq3fQ2$si$o5&3{A zDf`Cbx(9Z)(xxt%)48pX=!F7Fw=YzPaV1-IvL+wSX~9IH3a@>jUm6fs!e>>TWJ$Tn zDhVj-;6NOJFLQ8lQ_h|6xbDhiG#tcQD#*|sq)-p_BFLvquD^Nj3HuhjTgr8$qo#`a zI@}3tfsz10OD}vSffzOw`x{T=f#bY}(&>~J3V<}wM81YzOEn% zfx|-`IksNXfxCyOMZ7dSGqbC$q$}MFnU5tbL2;K9B9v?5tVIoiiU=%J_)Jwkm7zMW zkqCNj?S4X1eiS69F|hCzFyt&jnItkIn{jq=tBTt`KoZy`7;60osnYuf%Q#UDL8MQ2 ze8dmx6Q^Av0za_!GBJ;S2qt}7+CDr2Y;GTDfYHam3A)MRktK-`kUfAtoV6My(K$UP z%BzkTz)pMj5T-xHaq8%i7?4N)5DA-^sq~orozq?mS;QpXHa-7qiR_G!pSel}ZsQyz zRES~*W8Cr6w}Y#(!nL%oAf}LMi;$o^@~~Vuu<0p}{daO3=NM=4EbPQMrALExijSvb z;Za(h2HTBKB{(v|{uJ^ptLG{%$7~%|lPfv(d*(P zIW61vF#24K%Mpx_%x;zX)*Z%W#BJA~zd(`L09mt|5>JP{@IKgr?^k8Ij5ZD-{0(m{ z#!;(teWjP0Jla@a`yP?%!Ay4rd7k}{E@yjGH@HceMuPC%8mQ+pp z=gG_{nGQ1Xdw!TdA=)@id`YzB+cXT{`)}T;1O(O;I6rt5NQJkJ1xJpOH-wexxxn5TT|a&bb~~>C2_seP zj_2gUVU`6+n;0IUqAaVF_2S{K+t;Nza8FnGId(qID=)C)huKE?#h-&Gh^wC#j0!b) zI6oOS1hkMSKt{ScyQ2~#xG_KoPGKb09dd=~xcVrPpJ#ag&^S0uQp+U!A%arL;;mXI#Z3C_i|*J0Iy0|)u&uNH$bKJh zbN<*New%_!BI=hw_z}M?U2=C9qA{=JEca$y#&>53Xt4EwSi{K!biU0o5QgS}iq%+G zLKeaJKG;59kYq+aI*&9B=9}DjH@LiC=?V59fBt>_G@Kt?(*erwgtg2`+}x)oZJPpQkV_cDG6Kqgs! zBiRy>s^tufaLQ#x3Q2^~s4KlJ1S4Gt>g;{!+tC8EG=qgFq%jJ3qI3b}T5Z-Z@%%T} z*CV-M)U-Z6_n43hn~h%!ylp~i-|th3@3h`@PgHwYS}MGgB_#C-_qt!BP5FKqn%e9k zy^A8AeP0*MbT^vdg*{*b{%t)#Grdt#J@x}2jr54Q>l3=_984|rJ@b(~y2|*aPgg#)*NY}_K0<8FC77T=U;TKO{XPrP7$+HA?$;ifTxivB z58p3#SWRTGQ<%zIU{>+We%z6K=JU9h7zN$bfcWB4qA0dk0=m!r4PGmf>O}1%e_$-c z{eIWtS|;k_;c_~c`3YK)NKwQJf=Dw41}*vq%ASN?<5Buef6>)FrJ;YBI!>lSAEW{$ zRRg~dEQ_=NVb7cpxK?NV+Ef}V+O)3fApCVPF0%L81|>GX0Tr+7z5ku3`CN5I(Cc$^ zGQnz~)P~L2Zg|z`ekFG4b>cFs$G9is;qe{Lo zWc%S2+bk=G&}SxxPPKTZE0kC3fIb&X^5Qtaj#8+#Zl0)DniqKZO!&08$ZhVuJ*7G) zG_6XLktKX*uf)YrU?dNL&!742c)3EfB?yhu3Ae-eSg$3wjz0DDyF|qr$AaL4kHt(o z?zgAG{d2w*)*BKzF}~iYd5|q*u>@r04Ya9vst%7da^`Khmr3P3Tcjv%#mmPQm9o%Nnhu2!!%K5C!aUBa&!$DZt6{3 zPU%;=c$KF#od&jxE?XmuBWpKB4bpy9%8QqFwD$E! znDJ&|P4&vLH-(4)$;9`Mo>Ur{-xZjO%7GbX_RVKNEGl=x6b(jC($#K~(XvumH}Ji$ z==(_*9`;s1EuMC*tsQachI4#ppnCW?)p)ar0oA6%B{6I{He>qg$R5>+!6XlpBjM@f zsASNca%J_Uo7>}?CLtlGYV>k?TLJm?E>~U%pvt@yda^t0}f) zWb78YM!1!ja)4S=K+c3RJR0+JPMku*l;5~wt4vK{OHJ2!)61+6c}3h#&-cK5`>H%o z@O)MF4_-dk0pG(J-6mG#2XncjI$2j!}AH(nN&KE3hPqyGYCE|TN$;&U|TD?Ys z25j;5_{+@`zy}BHm|cXBI99>K*GXypPefuN2IJ%_FN8W%MMCkTJ@rH?Fm2F}df&#w z*>5MoJ;w8SmEX&`gEzj4LHz97kcJYIi3r)=js#7mQ)@c2L48MBDSQ=~H_R<#@QSC_ zL#^lG=Yy-`Jxm&PCaJvS=nRMRT%$1z&#@Si5kjl;c~OHi#jEku&{V3D4n7b4-2P=A z&tmio(8W`WF5V5R$48%yY3b~lkMQj9JL9hQVeY4ATdZ!M?%3{Vk&==)1L(6`2l(9- z^AvPT@ZQLSvVMYs5-Gmw$P9w~!scEq%gYa^Z92#nzez}W^z?VVgTI4^jO^yxiZH{R z;V{@V49(J8m|n@_)VP=1xJmxLd?GDzO<_dzgs}c1V<(L$NN9BMbzd$Ofe3~px}Y(4 zA7ACyqp8D&7@C3$-zcIW>k9io!a3Ko7dI)cKQTR|Ohbm@bRL%Rnq9QtISbjk4b_tE zN7O(ckDcUfvoHyT2PCjX(5wYE;gSyt2Dcs~R!f%)YsKw^{@l3~7Hc5$6r&x_3{dC+yk$9Pw70o|-hw>fz-Y1(0A zsVgE0e9aPDE-cxp^gf_bI1EAkb{IuAH6h=$kfEw?sB`3S_b{KX*?1=@`uIj1J(RL4 zpyBsp!Ts9-%-uO32krX==QuG)$xG`ciV)NXURxli$$ijEQj=Ma(ErgckpsnT_dbe4 zAzyGehKF1NHnePDAP@?-wSnjYhb0RTE49$bmBSLBtumV|#Y+K60(Hh(U$Jo9{-XWS zEM}D=&0d8`o}rHQaQ9$0@*By5@ry4&Tw{ujyw0|0AO92`j z@YV>QoQFU^9+?JbK6K{ly1!803B*z&Zfk&d8Cq}=)jEhDU*($<|3v} zC>iUNRO{JtMYmPU;5Z_5yo1HBwl=!-Q4tLMa+ z@;R$p35=>HZQ3za+kXT)K#v7Zfa&TkHp8q2%9QO&b0`DXd0YbuV@j0hgWvLg;S0W_ zm|vcBoqw5%#l<%O-;!#Ai zuhA1h(oV$bfuGWRx}bmz=`G=DX*$K?FJhQL2=SuoF4TlQDk%P&y0X@IUQn!RG!Uv@ zq9W$w5C@)zklwNl+>#>BL)kWkXp;q@Fbi$MkLSCbuZ1N~?ln>qM?B^^#Mn-)A+oeR zvU?CrLsk_kJNr02j@SG#eK{ry)th52gpB?Mhb;@uA(qff3Uq_l* zf}=aqSK(y!+}Dnh4W=M?nvv&Zc>7qR4r`EC2?rmKv_FrLRC>{K^{q=LTa%$}W&=gH zM-ca70ns2y5D&=Wl8j&ch+hP_EV@9gVx3-vKl|=8js=TrbK=7 z*UOyIsEky%E@`|V)LUp@;~+6wSB)vy9cHsZ4%sH8RrFNzqYs`XF?><)25$^EJz0_& zj&LXrT&`^cE|zJ|~>e@aIg%L4K^4nn;%u(MzMXxB6WpsT`>>qt2~+Ub_{rJMUy#vCn$P6+6B4w;u;!iBa0vv z+D4Tq3^EMu8FQ22WFK2!_fJ)j=iF2{>Gv*#d%Int9hxf>kK9`TVjRUbCA~(>Tl&hO zvea<&H$^7ycB2vALzY!iEvZ{ARt2;`5!ZmX$fsO zb$dkY(qCN89o9b^s%GPi@tB$R__JVnON^u4R0;DXbvl76n3G2GI+587pPtR29rApeU_7B-ay~^} z>>^PTNj8}yZ0o5eLX9~k0RcdafZJmg7EJ?sLz*&WLjA_9lh^nFD!UT{lscgiZsEnJ z*OC4N8L(5{Z5Fh}Y$5c+ERY$4uNV7BSO%YtOT%dg1b@`pCT;8B zO9O+G^9{xUk2X$xJ9!7_hP5HNwDj1>5@Gq^BxXc*8)x@ zU@-+0lC=ighlGOH97YJGcoms=ZJ#DkpEJohX(0L*+ycWnT>uQkS+(g#gn zfV_)GhUG~z?BK`@ut5diHF}d|iY%sbi{`jdzhW?ise&9?QJlBmfO6dl6Lj&a)*uc| z=IW8INogY9g{ypG(6cn2Lh)y*PA3Evad||i1~YmGB7-D<5XaLl!>l#!NPtHRnNaDD zmc0dPEZNt{Tosb5nl~b*WPE#u?dU)4&cSsm?oSOC*rudiyS{&5-p6?XW~ugj_r2_7 zQiZ`t+x7?(yPXK(R190_+Uv8cN(LTu$?h`fO9awQldm&QD(VFB&*D?cK4$Q>Pvm8Z z_mMz%xQ0_(!sZq< zDzjmqn94%dHa~w~!nFjxhnJ&h{C0vzbui6Fse1JiyZbB|>Io$+p6Rr=Yr&g$8XJKY ztk*ogkYY$}_ZWScm35vDgFm%133v8@B zP)UCeLawhT;gkW^%VljX=ce>wCZP&N=J~#=F~9oF*=DzM|GR~HBz|{b;8WHjKl_Al z`RL1#QwB50cF8I1p{08EoX4emP8dyeA%Sx15{+0r!-|C-dEx=;_Rtub$2!}}X50wB zoznuNL|0M3_SG|(bw69b$2vQv@%CfaNe0T=A`Lt*d}dFvKK7rPuoQLFQjL&oTbCOy z%)>g9|FMxoqu*GbiiBZbW8~~mDxp@3%TE)DlMqWP{`wdN00`JZCYXs|rvleRtE zk^?0m`C;Mp%jlh&f&q}9!g+5+$Ie(gzboyGd3+PN42|5K&h2Rroj9y^Jb^N;+bH$1 zqn>R%k4yv4*jFOFm3t;IGF2}CZuppg%Ov5T-Ccj&*`(%5a`lw?ra_(V<+em!v*O3Y zhntH7QOK&;3>7p%G|l7W-a{bIk0F3AxN+aA2pP$$3IKQ0Q=4wV0tX)52-oRoNZ6Yo zdGs0Iz&C~a(&+Z&m4zsB%`I5f;>4)6h&OY=Bi}#VkxpXQr)|IBJU8q1i1E3ZiG z8Dm)5{cZ_n_$JQ`x^DfGZ3$inj%k+SENYMB4v&^d;4w|mDA+c3W&@4}d-;cFpkl6s z+(`QyOGZCJ-(Cn1-RB)|!gmLUU^5R!F&b4B?QL=71X=fY^rhOFB{eOp@z~{ zsIj&i{Z_Xw$xCK@kJW7{1CaP#u|4#xYUT$Icd>-~3F`t)_)cD+vD@NGr7pOwf6clD z?p0l(2?9?vx?M#{y#x6`TWg*qT9K!P8!?V<8L}xXn}n>>L8!wIpvYJ#Q}0uoS8dJ+ z&Cch(#~pjZmzGz$pa?DRYq|%n;j_WOGfYNWlcuhkW*X=2yk^|0(q+aL2tfET`^35e zdd_0C-IJ_tpinr*4{CdmUwI|o!%yJIW3JSSX36HJ;Ptouac2rJ9$LJ>4}sTVDYoWp z%JN8?J9B|nD5o;E_b&xM-K5>{nCU}CHoMF=$^jLV6t{TLjof%$_o9_EZuUMb(ZTyG zoAF-DD-M|yn<6zGEdhG2PxzfCA@M@xJB=knb=bY8=V63Nq!7KzroFEQ8zU*Y2Z&)Z zRXS;oSqyGR7SD7@SwwhKLqE#5)QjMJh{0U1_?Wx1QE%^9p4JeOxA0yq)tOf?CTUQC zp@R&rr<0bI%1UtZK3t3U<2Pwnl0eT#_2rsiC~U(rry~ zcb2Pb=m8=^TW-!!W%o$XmsOM_?^Ehj*3d4R)v2=ZCsKhZnDWK7T#d{ByXuz`* zgeZ^&k6?ep5zi`c`0&aPD#)*;^6Dk39Z1?mnCChVh6u40PFf=th?5qTfjB8k6Imp! zg3IlkgE;VZbiG^Ng-|AEMcm?jur&m^@Yv3|8hL-XsAtNFEF|{@5~wLEMGH~C`Mv5< z%iwzY=}4pnB9^31?b~V)Ay+ePRjmUHWVx3aqYzYR+Dh=L`$)|q1|e>+{c@-@fX-a8EAHYeK_S%g7U z_4__s7{v@zK1XNJt!sQV#glVw7B1XlB=MIz_hk`HJB~y_q$ZDD`Efw)1>;;Qo=(v3 z)g^505pXGbOI+lJ$#!m*V>j}p<0^l;F`DP?oZXWnb-sLinaQ}_E#Bf6EcJA1pv-q- zX8cNiV$|=3Y|e25zvbr|2S#s4CP)xz721aZUd@<@nf@mR^o1{8*)YA%N}GjOey0;e z*K|~C7l)UJK&Z^Ccerp|^Rq+~;C{@Hk}9=$EDJRhz(Hr#SR2k^Ye;Z?VQ>u`ba#1H2y&x*z zohn2kcVoztGpo+6a(T_5O;uY`a~0UrFWY!H6;mn{M2RBk><1=ZUy9iqh)}TAgp6ny z>{+s5GN-SON2@}%UGxmIC5Ks@P^=zM$gdC&GMWw(Po;^$wnQo9-Da4>;AK1tV%^mH zFNt4fuF2R4^uzt>iQLzQa6R0{%uOq8FzA_>$5;AB$^#5e@3?9*-QAtezBl@bDU6N9 z!QcXTm2Y~);Y`WIS>A_WxAqdSJF z0FK)F*-^h$fvU1f^)C7u~3q;@|!>5KFASz5HVcI8mu5>NlvpTw1uW{E1}uY0m}yg zyI=zT>mE4Q3QV$v^ z=~H^OxK}JwL}V}q~V=lHa_mK7yGYvVR&YxU(m9w z=r1wozA*};55-zVMM-o#u`?sNPHl4z(_L|{)T3Ruqx95#c96*4znO+3k`#}If?kIi_Cqi$4v#j;hR81llyz!lP}v3y#?#lRTi{M zeCAMs+&!rRS@h+Dsy#Ts-LiRc=JOxpX)h3u$F)qkP|w!(Odty0z!tagMB+R#$QM)V zsWT^hamMM%2cm|LU{EQ>?htNci-XnR)%#hKq&K}x)xwv&u>~49eKYwvvS4Fhm{W=E z;1zZd!(qJOc9!f^rQhsOr3@Te?w(K;g)armGB4_UsRxoq>$BtXlR_2|!Q*nu^Snba zPp`3^4BeY5DbRu5gmt1f!ell^aj;C&+m3Ec_#u71kdcr-&tDm%>#k0{c7Cy~{B-qn z&AKP(DU?haBy}-YkWkB%M3~sHi7j~7jy`&)^&yTh%9E=#9>s%d7S$QU`#pwJdB+0i zgn+a!kUz|@`Lw`g$|Z(g2e;u$I{PX&iyU&aH##pr!T1TQp$U^te-8UJS<9at4%)S1 zS_Ab%J`Q(vg%S?Lvf7D{iTvwN73SZtEZE*|eheVAWW9j_%U;gpziluO+rmBs5@^V# zNFvv#mwIIgkkECN`p$-#M0yUWLZ>sfD<_e}{iAdB=6)C}KfgvMU>irn5~(?Lb1InR zORmufl0=`JAjWgn*Jvm^zI|MJH0HYwXAUD42Y$8Dmz+^Hya?seIGrfVA(L0iUqywI z*ciavnS(OGZlF+mLui>j0ydgb^39hRWl~j_Nj>LY{-BTkRtEFPgE+|9pIX*YB+g6! zF-X5sE<%n1b6I@Ek#+1RTjBKLsfF_Y$Jkp&)zx&_!U=(3AspQ8;O_43Zo%CWBuH=x z5?q73YjAgWw}jw+aCiSU&)fa=+jsOGxBqblM|SO9t7_F;bIzq<`2mgha1$~(_85OV z`Q+tI=DcN~b)Ry{O1@KY%+HLR zZm!|lqZ4+r*uga4D59?ra13*f%l0+15QJLG1mX6U!#NL`G?Xt@K^1MXEb?XEK7-FMvt+>W6;bH2)5>E*${AP8$GdYGPrS z^yFNciPAYdbv`+nKDNhv(Y6KFJnJBWHfya$KR52AWJmRLmxbY)PCC3tw0SfxjldHE zIP0k%qbiUcaqxS39?_TM7W$N}S!KKZ@l-gl)0@cYLc3Ox(^XTlNxJ=Rwt=+Y#>_ON zTs?dw!E1@{3$_)~xWpT5wT@Y(a=2>>8@F1zXP%p7K|>U{XNO$pJ4y+67-$0JY4gg* z2*PR+cclIj*|aK=+>AlyhM&;SdN5N2w>3|g4#8L%|KRt~)Lk<=ker)9_r0?Ld1oAfhq11pziK&5(v6isctx1FS zF|HmpPvM+=jD^Xwq00Of7u5Xh*s?z5Od70#+mti9iV8>tG~yIXlG@yI=1U#NT}@9637Zd0bJS zxoe9>^!;Pm(V_T7IP&qcRY+beV>*zcFjjipE{9=x&VAE>yd$-VXeN8O`%W=DQ&T8q zi6ssCT$r6q%<_<4;JdLN!W$L~ge!0AY#wEy9_gJQ(74=^GMEW{=?OB8Oezj?lK{Dm zTrfOzPo=uet~w?&F|rtOaAp=L`X5A-1((z5NexJTto@8B1)r3Ph(*o9=?3vRcprr< z;|GT!q_g+9WaVVCEc5F+7%|Dwe;YbU@f+FkXcujm>8AKbo3`zpc}t&Y&u7u!sC+9K zFGPy)U~~qw=k6OcNX}J!s8x!_^(fwgO>3eAmEWMOo!nPWS%At#Tn-1`k<0)G3z+;6 zKZuk|-Cg)Lg6MHydltw3>tqL7_$vkD*F7&pZk_bf-!*oo(k)@4lokBBfhNf3##aUN zt-i##9sA&?sw-SOqBNI9)^zess1AYioGc(VbIL5SY6Y@H%|2 zY;}#(c)go^sg|@G0gFZ`SK^5x$NzDcL70rUHYh5nbq{KexI2d)pfdGh_`zvgF-5@m z78k39A0o-AFlS1i_Ml?+(fLUk`v1VX#dSYj)%T0|YJ{fKdywAf?fH_SfiXdy1N8io zUTDgV1$G?VluA`#n}CkVMZ$#r>$#X>wFrOLB%@uDAQ%!)T|sK?D8X7U{cht3I%XI4 zaasuP?>U28R&oZ$S$PsVnw!YRF10Y(g6Hn3^5>a?+{V14#Xriu!6=rxbq?>MRhBMS$1AASW&+G6S-qYQY2oopdwJR{GhDCPnN zf{l`R9n|!aD5F=v5jf6l9q^!#)yqMnOR1x|H%=Z?8P0Q%!R%1&w^g(6m+NmffL zIVa#Lnq=*Lzn839n`@6G2Adqht>1Ww?CnZOco#*8|951p9o`Q?T1da^(y(@mIv@W} zAuz#GeM+Tr2yZW9IsXpj3$}cXTw_Ewo|sF;0itx6$^1SXS{A9H!6xVREc@-iXY;I6 z>0S{!QdD(i~f6%W8Skj2JLW!&U_d9(>XUp5R-{req^v_lb6C6NO7|5@F{c!>( zQFThGGSaDRZ>Y|3`;=wwZmvA%7e^6u=Eq#?n3ey|R}l4<9AyIuda8i*1}*@nH>T(7 zlzDD$1FG14efJ~2^AO@Hl&_V~-bK)C9dK!uyq;3{yyo-qO=cIkp{V55!3fj2Eznc5 z-x96f&%F0{D$nrsrb$T4Jb3Ya^iM!0v)Qn$jlN5SlhY*$e$T)sN_(xtRw;s5h5hM; zKcs=hz;GZgiWOJvdg1i>H*IsXC(3$I45-aAcVRaX>&Zw<64Ul9Xm(qQRk?^WdI%haDE)M@DeYYclW79kP z=-01nc%F|YcD@nYiNKptb%6usAPwe{d=?O46%Kd?HdQoNH+Lrs`{@sUyO(*)OGFq8 znLfLpApS++g?eXPKA*tBmxf#yW8^yk8Pft9rSdXxM~^}dC>Td(EgLD;&z8zCR_Luy zsXOCme?ADEWWGN30 zfsxyij8LN#!Oj_;LIf6C_uG~h^-KMD$Og(+Bpz-c=l1eLy(H9LHVUN5+qbMd_u^4m z#KG+rEe;ieu6>JFb`{-AQeG`NWp@1`*C;Q5+S*k>L=hhs(O2$ zh<&&aCRX?yYE|=TBA@5J7H01yso_*kmrAE0JwLd1x#saIkaoy?=-AH=RZ}v1+Y&7kklQpyUYgf&0nmWsN&U)nbG>pJ`-g9(sreTQK+m5e^~* z+<-O@WTgRxWjAD?(U6cl?i});mBxz*;?)YGFp6B;(b-adcx%GMx{6JSsNPlhNz4xC z)l95A0z8YhLr<*XZ_TU%+mG2#_}aN13mm_jySzTwn6Bn!%5ii@y#s0sLo0WhGEZLe z_Ez66Df|X2%=p`536bL98GpS$U;qwEd!fz`)5+qRUhBX<&BBp0l1=GMLxo z?9v5$?LF5pv3xKo2TDF0Bj3D!zWSoA%0qVgf!gEStYPB3QJ!f<1 z;Ao2WxvyZNkV{MOOYs3>?3e)$xQyVA_#B8IyZ!R+1wC}?gtGiVfYpnNc}p@mP0Rga zz)!aD4Oo)_*kHO8IZnTEVR8Vu6pfgGtOza#EjQ?^Jjtx@ssQthS!Z!PG@qvsUP=6x z(P@izij^sF0D-Krj^a+-ajUw;oF2VDACS6!oDLwwUmD0gN5&hF^VRus2=1oy+bv&p zURdor=S6}XG8GU@%OsE{y?mt2fy=3MpyWRcnkKG(Qv_`Nu>Ua3P{*UziOgmsOgzf! zo0brLP1b4Nxy<-m*tx!yNP#~kxZJGtO4*C1_YXyr`vo5pf)OD9z|Fa>@a0JvrrY>- z+K~_O@w)U#CjcCXOc~0QPW*EbonHo8-vFHw-;$HiN6L{RgWgOoWfDv&ZgOYldyOQA zC?1I&Nl`Z{{;3oT6&--xqBl$BeJtPCrFw^RBJ%oUu}V(edmBy_;$NtfI^Xkb{*t(y zi6yOd?tc{U1&oD7faa~)8uY2vS5ciVSh)(oeJHBB)k-r_|0tHq|BA-U} z93+8e8EV(yR_^pHoxXSshH5nmnT~!t|DIM}{`uzwkF1|B>Wq48;^Q5a<2iPKT_sV_@yv>N2Q!hASu!J! zc4wJJHaft=21 zU$B{wfFGby8WB=|X(>l%FeaP&FcbBf#BZj`A{UiP+u8~1XHpiGi;@a&(N8@5Q>qgQ zJjdp*hx8=;VjSY zQ|N1Ty!)_y$R3OXVvAN=eU3_Po|({5oJcPqKmwS7WK^Hx5F)Cgx%q@{CepcYe=qaa z7Q1Ve}9 zpPFI`uSJ1${@-HS?>!1zh@U^P$k922xo%I;8%%_azF@I|3V|9285>2?w_C_k#3V=~ zc{zSKo0Wa}$hFBwKLam}N&NTkRemgG)&+rV>))f)nuNNnX44y6Na3dQPDb_&7Plxu zHBzJ3R#08AlOYaf+Py!S@)KeZeg_MbWjaU?aShsU5;V$J)by1=VgPMEw~ChWoI|*# z7^Q~;d2#3oas=D#IhR>pt=D|N+*C22v(n&yGo6ctxq(cE^4Mo8ixEr6!g5M{Fo5f< z7!ZOJZB(-eGa(5WyF~1rV}xiSn-X!K^#oRD!tX1a- zLlGRaM4P-|X5-I$eIcAEVmkHKg$5qTYx1;O=U;GH8Y?W#qX_}z7Q+awGfMntj9nsVABwa!4s0(-4eb_7jcFOe*j`Muo6^!_fqa6tMt5RO$e$YJA(6B!#u zpX4s3Y3{m=R^d)lLF17pWnX9$DxGy8w$I*Q{seZA3bwk*GTP~qzNF4kJIXHVEt|K^ zl=5tJ^@Y(U-sWUbfdM7o=#q}rirvd%!!Aw_oqPljI{C8&cotZWu9lbE{I6YX=}QU% zeuSY((PZ{Y550`j*S~uL={;MtV-n3GMjWGxO)whd@$%BGvgA}vjAxQ0x%jQMPsnk_!_v{c{1 z!ig3fT(Qn>yo?)8MM5;sKdl!&Lw3k;VZd@U__V>t>ywb`4h@O^lQkAHt%0fN_Bd zc^;sQbU<71dmLYA=gluup0oW8oF1t@v_EBekwFU-Y(PfkiNj9rjas)!v zu2CG8(I=^a^2M*#>!MP?+GMxtlU4HW+R`+tNLB!sUdfoGX1wT~@AW$}Y&Ln+UIfAm z2SCXteRJ%kk53@r3BsV&{&XC<>2E|nj}@uPxSxafh25R7KVvem)F z&7)hO#vFsmJ{Uw!D|8IhAmR1R)5fkP1SA{U-5JXeBp45_TFw@1Xp){tnD# zy4g=Z+pua_Mq`Qm#O%`Se6;%-&_E-5wL)7oeZAyqa;vq@mBN#<4q$h zQaS>7IjYDn8L{UD52ZNeM6290y*W6C4@!)Hj$m?7$#V0lr#4wRgWul5bAfgw_7rGT zp?r1nMGK?K_Q)X=ht-l@#Y|B2D_zEZ3$8Yv5Y%m5Nrm1bt8V~w23^Jog>v066nAl> zcf)$%JJW~LV}c{g({~|1)N^yfM{8296j)0pmYI^|npiVwtb)?OoVnzGer!ka+;~m}9#Rw}r*LxIiN82|hQKn9}|Pr1!1@H{Yy< zZ-8>+LXO~DEyiG`+a~|Ji7b${E$?KRO_sPn-!P|TZG3-%GKJ=jVcc6VoMR!=jEx#Y zcXj=d4DrliNHR1^|3hF2d94R1i6f=Prv*DMejg(( zAspW7jtiWgufr+qc$0MpoUX_&$A5*^$*&+;ha9ysfb3(SPNg>oW536Cx?X)ox$aT= zGNp@S%$E_IM24~e2NvEB5STp*3ipJqgNu#IOzjJ!M6c?efzL2^TSb;a9!o~8!J(s12oN2+Ssj3Tj%+dU#HLlL!fY%h7e&?Fc z=*=6ppBpSTRcokR7lEpFQb0pJ%ke{MbbfayZ-T#qtngqh-t2$jNa>v=oaF8ASX(GC zw*t5cH4z2+oxkl%+-rhntKVZu0x_OmtY7AYzn#YD)K zD}sH7s;>R4XlKwq>-@5ybJ&T@lcdNskO8~?s1fH+>TFYJvfwh6eD_Y$Z#iqnTz)F8 zJ+$_gIqCi(lS=PM0-d`43Fa|Z)cp&YDnP$Wj<~wa2{sfg*Kdn_kBrlG@Pm8U+e`4I z0C~875Lc}2vnj=G?M!URr^CPs0!x^AG`dbjGe}c_B2&yqM>}>%ZXw1Zow8e}?a_SI z4(xb1x9DsHM}&b_45ln@2l(U3{c~OQU&}vW!hlZHYr?n8k8y28SAIxnWi*BPAEeV# zN3QOcn*ybW-XoUUth(CeKAv8 z^b+Bn%M9*w9DRuA(0ZiVo%!1$AmBi}Xw*KbUu)z_4xyzMVSAW(K6tp<-D)&)`cfmV zD#id!@$LL0zEQp#>43+*LhQ)-C4QJY7G!Koq3_D9i%ogl_K8aW*i(BpsKL(aTgcKQ zk8^^x?xs*!oPsG*HeDGnQwK9Z;A|+@$#ct4enuf+6RyUm>EV$AHrc`U zeMW}B33AkOV!_7Zl183KujnUubA8apI!h$(20iS&9!UD*Da=L>hZ3WLcHuYW$$b6f)H?p zm2I~*LQyANkNQg9a56mFt!_C|u%%x5xv`426~vW#Vzg)%IS>L15H};oxn7#!A_ONQ zky7xb3^F)}IowobOKyZlAlBjQ58Hf-+=0jWq?D0**VErtJ;KS&UZ7h9?v17Kqw2Nu zbzxhZz0+wWA)5C&EWR0wp5?{G94%9VR%Uuf*k9r=O+cqF3K`A7wf4q>4riKpKVx>A zok1h47P@Cr#!WoU&0{>kJlqK-$^)r*GZ2j$Ey|fR|0`%>^{XFZ3d_)j1XA1~>XBFP zxt_&c6`Y^AFkQ}%I6(b9vIrGXW*I}OL?fYrV-)mAW+LW{`!4sK z55C2IlcLQq3}U5Hm;+e(^6JF_dVXunBC!zT%f;wtg@zs-RO6}Zjpf9pC1Ot`ZeGk$ zTR}V(r;90CzmDop*6p3Qq5A<7j5UkC=W7j+>vY~Yu-iHD>QR}Upup{!C>$c^lxjit zsdCP4EZ4V)Wm|yHItl9>-s{aJ7LrLksrT*PZz>^iE_tZy`&=5xZys+xp;@4fQ-31u z3U(}wJCU=@b~$CXS-r;4sz44Df`sVGsBfm7%!s|05g9{V&i7@|<6`{_ zxm@%*;TD)tu= zqPbM8Zz3!ht#|*(oh???u?lO^fh1;}9ED+Bh9--75S@mmE}u*POzW1cvvXGJA4y%Y zniO(#yLj(2*Hf!M8xTTZ+Zz2~G|cT$*xKw81VzZdm7)W1y>m_(JY`d-1DVuN92Q6Ib?{%?O4PmIQ`m3q+*X8bVfoyJ1f+j5$BtEn;~n&6 z6N?y_lpE$@$r0Q$%>-SK`o4GL{M&k!VuW+LCg6oZ0%na#?p^PPk~}&y{RnYO4r!_A z{!wU2t@2~gj&%M6MNY-Mh={Ml4&Ugra~e2!RDvxop%7pc*a9y^_TF6oG_P2#OuoM% z>ef+h7+0Ka{^rPNmHatSgxC}%8h~;~U6i{65|$O<(I}kU&fbg7zkHs}1$q@;D3ob8 zC2jQARUm5r*&8=DVT*rb?a7 zVyH|)rKS0IO9!(VKg+vGqg<=L(BF>^Tftpwc~T@O`H={3e|#4aBFO?N!BIh@Lm|BN z!<QE$8ktue7w;bI!908l_<7{#S900n#p;61eWGg!L4yyg`x6pptvnB^W<`!Z%D zaZX>RHV^}qzwv(n6QhYa++e=2My39W?MdS{=-2bi(p(4m)}9XcDkC`6W(2 zz9*6zatK4y=fsc>OjmEy)@3M~PH5R)w^Azuw@l=tuXtF(^oa@O`FlBR!BD`44#PSE zz)yfmlrcs!aB3jM+_#l686t(iY*$H|Ho}Nz=U$Cw<~}Rx}M2331TOb zI)zog&#Z$c5;IZ;nAeymC3s#c0HJFVU3ja1OFeqG!U!QaT+tm94t#Q~P{{?wv+t=n-K`tG&@h3_p&Hv+8{qvF-1byvn38cbz z%C&LD)cWImaaH!Tp(#|-#7!bDwLrApJh7Ht$@mXK<%5Ie@Kj2O|Bq?@KfgRRh6e6% zA15VOY5@?plN!*f54qzmip53G@yi#d_JuhbNgY<9E|Lv#$6}tcNUpNt9 z5afRTx!w(yZg@l zI$nrvu?N9xj4T09aOGCH>2)#tf8H-*r&kA~$!{HgrFE}rGHqa%&Vy88X#ZIY|6d=+ z0zM38Y{ns(k9&RM`~OM2kru7yCedgBrr`&7^{W5XAfQQKCyzvBTNBM|fVcpI7|T_w zlmEAs`Tu@3qas2mV&)`({7+dRn2u8kD06xe|APG6AWr*8PoJMW&TnoSy1E7ig1Uo{ z?a&C--rB9SW`Fyq!wJ+@XywSRXB#j-qCmbm5+ONJ4twqZ z##-w%kC4ju!eAf;kJ{S+ule>ro*9S-bbGo^y6kiM9kn+~alO0gr5%BwO}$L*U)z*# zW#o5oaQ8idbG6TFl*a)Da(pJ5WRXrW=vR}Fw~B-psA!mUG6pc4$F^uK*`X?MuIx~D znS!~J15u|O60!+?IfXKtzmLAnHUdoB>47LBYU5fN$DQXrPvutsm80!qxxfou(W^hmN|@AkI^I=c!NO$PfG+%*=X{%dVnTsEdCf_O)>v2hl3V<>tXOAi<_+VScaeZk6A=2lBW*Vt{F=ZV`3kH9pFb5L{t&7p zu56Jfb$8u;Q}OFxwpCYsorYFLC1NC}@V>})P_I?R?qTtq9C9k%UMc;ku^!TwspCIL zZoD&qP_(_n>H3}n5HX{O(uSGuC{L*r6ig#(;7~lMK;6{aNdRET`Z9fk1Fd)n7GIt} zzvqM;j_l4$l0p^B-Sk`y)|qJ#>}3|-friS@pW9S`OWJky`6DwvOd)xd?8dS0bdOmu#NI|T-z7r_+^3^`KuOlk3`#@r9f44^njU0 zG{f>);jkN;@)CB}OOL{o6Xk*pC{!p@<6BVubbgj1C=Xo5nC`F7p)(aYkz8qI0-Q+uuW~a_L~HweDDnBd&X&fzws_*ubaK2`;_;0%NKAS}EvxmNB+P>1 zEix20tL>6$#`VMgs?yH*5!9FkW7l}P_iUL55#bS?a6s?PiC`AcPIsnEr@?I{U-mht zHw5j>(d9W?5D}9Bq9y7_d|$4lvVYYf*Xk_{deSAQXQxXaPCqW7HYIt8qHPZ>E&pQ890dNk%ac=OGO5OfuCdfSz5`0qZ=wALV-5vxlDsoMPw|b% z(eaEOB&{ktsBUh-Yyt&p)$k$|Ha{vp)}4A6F=^EU$NI`WfLL<~5Noy~aDV3pBJHd6 z21l~HzzF9-3@wy3_S)H?Tesah+RX*iGmKl$=)6}x#N~cL3I(yBCpvqm`E(G!Zg()t z){=VaK)CDz;W9;~Y>(iZB}`n3DhAjDlDy~~4sb92Of6jfYR1E88K@W>7wX|*v?8bP zvH+O5e_1Rinf|Cr19)`NTK>qWU6BEiQz<1OJPD+~qlU|gTYZ$`Zn<&9)s1GAOuj}o z1rBBCq=6nSoB%qhbkgM?w3k?qY186<^;sD(89_Nr0GO+44WPc8lM!8x6e5NlIyGyWI8p^LrWpg8`C%?>JqeM-NwmxLg{TF(@_5j&fa4=7@ZaugK#bd zJYav~F{|H1qf4?z|C*}k9E-sB7VdUziZc*1fO$?Rq4eJgV+6wEtPK`-?)i@+T1PzWfDqy z?O+~Jo|xxE+_@d?F0DjTh(G_Aryxr38xWL?2oco5$K`xLseTstqDI#wiP*21EHM=D z8>?x4)*wkkYZzJ}8yWQ57|A!Cl1OPl3)7+PwQkVvra(U)j~0!(si9{|0nt~2ng39Q`wzQ=YczN-> zHOjuQ8vj)OK&G{*VL{RBMJ*C1b@_O%$0Oj*+}7wEH9$d|8f5d~QGrZd@`q5;YeHkR z@7%nK^UC&12L~?^iP98`bn3k>Nem7&nIfHTuYdAsWK-wQ0UEQ~0~L*j42Ns%&TPJ= z4&LQY9ic4jUqo^6>YQ*_uJAZiU!Fx>?;{C(vWa}Yp1?LyLZi^Ul)K9}yG&H~xHPPq z7cN#PVgso%MuGI#C@XX)Bi`{ZOyIXFMI#*U6Krta7Kke19g{HBPfzeRbLOaG*<~js zZILKRb$c}O`d_9PVx{2+np$a{(Ps4byJ{0nZL-}K%V++^V^Mt*A-XTrIYlEo=PmYX z$t;$LI7x>Z3+MiXBBmfru#XB*&>Thp(}mSJD;j=&pIA-`&5DJ%N<;HsRnQ$`i~Gow z_#_4s`(nx)1JyFQ4CqisZ{GrG`HvP$5u#VnJ~)(^#fYgG+-?aCIBCf-+Ue(NHrT1= z{jH+@ypgvR%f{`6G2Y%|Lh84B)$?$9_^5S%yZ)}ve0-dAAnXLS+%7}FXq;TJ2DwRd zw8@m>+~_E)V$FNL9h%QujA*qZ7og`=*AFnu-DYqDYKRS-s4#Te$asy(MXU)oFL18G z$UP>SBVE?$#uYll&${=@0Yw7nB-)cHsBgS0PFC|1Im@R~2coEDy2W%C$z}Wka*`oL z$(klhf>OPf%%3_)r(#(t-FS`7M!N^zZLA3RNJJ^(_fhwaMu&J=^4iX{Xg+WGT=1O8 zHcG|J^UI3}45_Hx4vsJSNu*njz!qSD0QGig%AoO2*v;#nmIm~Ucs%BUE7%tRgN551 z`o|5dTQbC$ae?X4OX!W`clV4}$kK$>y@X9z05cpe2YFO?7|_*m6-@oi&%)kgsXjaT zo6x>Q;*#OQEjTX7;={^VVX%GF$qGY1O9&joSm*gmiBy?2u*E za2%~$Y%{YTQ5&Ktxsp4MNExv^i406LDE9Cs?4Gkl4wykZ=HZHJr~AhQ1#W|B1~qpy z68p8DAHT8r@Q8v!&LYmmee4O*!J~`?Wxu~yKTrSAv@bH?Y;H1QH?vtypZ-&H;8e#_ z1!RpTkb~^V8Mo~K2k!D)VpOx);+Z4{gQj7|e+o1`L0HNR1fnU#KkI%#3$x|Q6AmZ$ zyN}n*6;m>A(w0bFOsrKh>ozYDU0F`l1Jb;{qRpuF<9 zb)xjqM%m2_eNei2pCyF6Im{;0DJ$HRr;?I?0al7PJl%{e^kFre^Db|`=%7MQ$Sw9i zp;P-k*%7Td->t|t->qTv88zn1f#Ow|$KH6DcTDcIgzutNCtH2$bOAwY8# z+aFSKWD3}=cx462;dN#78hdr;w9@+ZeOW?YOJO(rAcL|xP@vz$7w-Qs3j2{vp*9$u z{Aa#E?E&C6DaU<7D--)SXqqe>GV2vHa((&O-=pbiorQ#r)yT-@qVc_}_+VleBDyp1 zXPNTtr7sfLO)fjlABzwzgBJwe`zhAoVW8jcEjgjzHj~0-^JJ#|turV7yM6W?s+bRI zU%fZwu!#<>6i>+Tv9h&ug)WLBw05}g`xTyv%Kg^fLGF!+AeRz@)A#~_+E&Ye!JkF>$aRs zKst6j%e!5mG7K!p$TDwSp5NByLkw5slA>wvEI4~83?4mb*O7k~Tan9L$s6@J(I}CC zQc!@ZfMvS}MZMlDOj!)Tl(6wM`(Yw$05RR^^9Ggs*RPrK9aX`pfO(XRc72XKK9s3n z(cjBECxFR1#+Ewxo#p(RNTCW_YfI|*XjvRkO-u*l#Blg2ve_cgc|8?450%uJAx`tY zBzoF60#2&nU%$_mN{5`B`^5+~3~!-j)JpR(eX?|Pnri@M5y4;SS8`Xm0XEN-8t+mOGONZOjEdhE?G}O&8m#f|HR8^x~4atQPOZy{ons z?Z{fe-?`XU(^FH~Pqj>GTgMl8gUa!HG;>5FCQxje$KdESRDrA$q+wcx*9#Wlv@4I>c(X~VF>ga_^e+9}Z zJVKK1rJ9UEKgHpSa1<^N+oAGz6V4`@*zsM{%e*DmP1UceCX)wFsWeCrl^t8AsV zi4W)r%&L?#*MhPiZgW)W>MI+4?}TugZ}D#u-+?7CxxSyA%DcCO?Mj9HxIHdyqr~RU zO9UrxPDQ)72f%Q8K&k2oM*N+~t=e5FG&jesJ*Dg7`*=?^5-c%aY|61XMo&ENt>c-H zdh~N<6W`0a2lH|Ys}0}mE=7SW582tZty1>wQASvRtn+GKwzcwf#w=s}Pw(QCas66# zu1ARv#?N8;OnxGmNihENEdX;82UVX}kv}hzHR_D6&1ZNNGdTCc-f5@mhbNku?^pcZ zW9jG1{#0i%9>u6nUkQ5T5}!6*V$nPu+&-b7^m_WMS={s*BK-MjZ0(fn=oh6x-W z8*XnYwOso6yuZn0Yj}?Gk9VU%<*Rq&aRXgvZBN7AyyGZ`-rjAAw@+rl@0aD6SXlRV zo3Hl2sv>t<@1xtCFMR19eyMu5oH+#GIQC;m;M4te^Z!}tmJgUVwz@_~?^>8c3j20( zVivOm6L;);<yFJ>@oW zCr~-y;W912NRg{p3Np*yhIsLp?{pP<$B_-(yS+?&O%q`z;2?~aW85?wCj@g=mmOHH zf7;n=Kp7LZhx6?2jGc4w8BDM!)%%?``hniZqS>9$&jIIoVf36)nTlpxN8w1C*4;-i zhRQ2wun6Zx%@|rd=0I|lHDFRAa zTN^D!Sf3-)3T*mTzzmVww*V%|35+J@ixFZ$M?^XvUR%TGwW7@F=}54<@+Z1AZqZx{ z_q_-Ro`@?4KbM&SO$?mgMmo3$-n76$bpaABkQwZQQ})Bd;~~3m&@uIhF#cNP6?$wr(77%v=0ZhaO@j-b_l8 zFTACoBTh&+SfA$fH}Da3c0NTY96-=V{|V>5kB^%X^E!}Y(7Z92jL~6x0u=NmY0z!^ zVx#@cl8v-196Bs+8Hjtzgsoa)OY^GqyKB!=L&ldTOasZFq4hFOa2fIcp;9XikXk%}o~ARQ@txx)+KC6fj#wwBzaskT`}^X_)TWE8l@0ay*|D36tiNCrB8bl%3N7$7 zmmes;H7EiHN@6Y$kVJgV!bjLwdWE^A0TkV^vV_7N1B$7wu3d$>On&cxJ%3j23z?!=TRrX5AWVaQxqQYuN1*Ww2k1TQedf%QvfkmtykUIgjy)0(?7J}J^qSvJ zO|s%VfNADkRJ*nhsoeaGE=^?N!LO%XolyCiZQ zj}inhB&dTq{dtkNSc{_#e=Rp3!qMc|>SKsZDJHg}+xDJCGL<~JiH^v&|A3Bk`uJ#m zC^uVJ)pnjjbPPIX^>=OtG1L@@UD=oikPa`eb_8L;mPI~_4yZH^D(}uVqFml?DHG}& z_KN-agQ^|xO@Cmuz%lt}cBd3g=M< zg({>=+Slydr`^mXqXo^OcdbQPGS~_ioni_ARo1Bw`oyH zE9FiqFmWyLYKTw>zmxyPskoXQS1O`@giCo12j=IFi?AZezcV2C)w<$szu7Neau&M{ z>l#0dQKVT>Zp%Ke>SsBbWmIc^^j`l)Fzh+cbm(XE??^zR=f&%a%$e=~(S(x8+1%vq zgy0&%Q_~f$QMN%aaB1Ld$ly~-{fB8M3*KI%KSzLjd1U(R5*rFFbeMhWd(2HpkXSO; zaF}jmf6gZIk68Ov>04WaUO432O%y0USj2$p&PU`?K6q59u+L+(LLM|MfZ=FbAak`S z=+o|MZKmVMe4V2kvpk|HB~v`?j11G1e>209xAe^7R=svsoL4aMNdrtQ(^#XDc=w-H%ji>qAYpxFo1z_>LBM)fIg%0rZ~_8DuU3m zK=`Ymy@9_-))nb}Br{wYB`9Xn_;2UqTBmL*$nxf~h}6Q+7-1p=loVW|3WniihlvQV zmunHRl<@toyVwB7nMgG~0v!YA4_`NYhkDUxmV_gUGuiw-D+1uf)=YnXGj#O{9B*#h zEQ0rOb#pJ99M0Oz*I7J8?9UcC=HOM>3KiNW>Z^CbUK&Zm%;*KsnsX+N`@$8lH=)Q9 z1ZoJ(#((ENa+G*%^jfjKFph|vJ6$g)u>Y!12HfLLTQ{46_)KqduC_=Y@g3J*=6Mls zsUjI81(%lf{AKN3WMpH&7*y!==)0NI8w&OfBCUIe_G$PY0{;anqUSuG6=E`Z_83cY_d-2uIldergw5%r&Fae zN+16+h*Wu9{DQa*_R;ao(#GpY8r|S5?tBc=u+}3@b#R_6paH?eqgHV$IIj;4uRh^* zr^Zx7^gxvqxQp6zdt9A;J7-TvouK!=-eW}iI$y9JZ_}F0g}$YCmi{Lq)3IemAZos) zq}KJi2vak__IFRy{&op$3?&S>&Fk4|+XZ)S^T13|ki(n9zPyLUO=XzL{qU%eXmgWQ z{FBs2UMxb)pC=F7`MkTA;V)a2p4zRn`sPUPC|6gqC@fCo)4jv*}H6-mCe<5a_T;fS+?Xy)H zt1Aa;*CkWL+<|mY{>QHt&FXs6bB~d-*Q?)o*ym9S%(n<@!NEbWyLz; zwl!FizvpESvGomZ7zsctSk`l_iiRL z+RP^%@#5uhVzAQSxoB+ zaEzT}yOmng75vt%?WdScqijFX)MUsO?SUN>P{CjnH|v+LK}0TEiRH853H`LX&>BO@ z4GR7=$xVyt=|ua|BPXLShe%qOxR+_}TeKA%(yMP-Qf1f=uCP6MuIZvsOrV79Y|