diff --git a/.eslintrc.js b/.eslintrc.js index dacfa2d470e05..de3adc0913fc9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -639,7 +639,7 @@ module.exports = { files: ['scripts/**/*.js', 'src/setup_node_env/**/*.js'], rules: { 'import/no-commonjs': 'off', - 'prefer-object-spread/prefer-object-spread': 'off', + 'prefer-object-spread': 'off', 'no-var': 'off', 'prefer-const': 'off', 'prefer-destructuring': 'off', @@ -672,7 +672,7 @@ module.exports = { '**/browser_exec_scripts/**/*.js', ], rules: { - 'prefer-object-spread/prefer-object-spread': 'off', + 'prefer-object-spread': 'off', 'no-var': 'off', 'prefer-const': 'off', 'prefer-destructuring': 'off', @@ -708,7 +708,7 @@ module.exports = { excludedFiles: ['**/integration_tests/**/*'], rules: { 'import/no-commonjs': 'off', - 'prefer-object-spread/prefer-object-spread': 'off', + 'prefer-object-spread': 'off', 'no-restricted-syntax': [ 'error', 'ImportDeclaration', diff --git a/.gitignore b/.gitignore index 86a789a1cfb5f..0107ffdef5e19 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ node_modules !/src/dev/npm/integration_tests/__fixtures__/fixture1/node_modules !/src/dev/notice/__fixtures__/node_modules !/packages/kbn-import-resolver/src/__fixtures__/node_modules +!/packages/kbn-import-resolver/src/__fixtures__/packages/box/node_modules trash /optimize /built_assets diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 6333988be22ef..65dfd6944e436 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-07-24 +date: 2023-07-25 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 58f029c9d474e..82e9bbb6bce14 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 3be55cd1d487b..8c386180e2864 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 4a5ed373058a6..a6d92e8e087c7 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -1401,192 +1401,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsFilter", - "type": "Interface", - "tags": [], - "label": "BulkEditOptionsFilter", - "description": [], - "signature": [ - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkEditOptionsFilter", - "text": "BulkEditOptionsFilter" - }, - "" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsFilter.filter", - "type": "CompoundType", - "tags": [], - "label": "filter", - "description": [], - "signature": [ - "string | ", - { - "pluginId": "@kbn/es-query", - "scope": "common", - "docId": "kibKbnEsQueryPluginApi", - "section": "def-common.KueryNode", - "text": "KueryNode" - }, - " | undefined" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsFilter.operations", - "type": "Array", - "tags": [], - "label": "operations", - "description": [], - "signature": [ - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkEditOperation", - "text": "BulkEditOperation" - }, - "[]" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsFilter.paramsModifier", - "type": "Function", - "tags": [], - "label": "paramsModifier", - "description": [], - "signature": [ - "RuleParamsModifier", - " | undefined" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsFilter.shouldIncrementRevision", - "type": "Function", - "tags": [], - "label": "shouldIncrementRevision", - "description": [], - "signature": [ - "ShouldIncrementRevision", - " | undefined" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsIds", - "type": "Interface", - "tags": [], - "label": "BulkEditOptionsIds", - "description": [], - "signature": [ - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkEditOptionsIds", - "text": "BulkEditOptionsIds" - }, - "" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsIds.ids", - "type": "Array", - "tags": [], - "label": "ids", - "description": [], - "signature": [ - "string[]" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsIds.operations", - "type": "Array", - "tags": [], - "label": "operations", - "description": [], - "signature": [ - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkEditOperation", - "text": "BulkEditOperation" - }, - "[]" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsIds.paramsModifier", - "type": "Function", - "tags": [], - "label": "paramsModifier", - "description": [], - "signature": [ - "RuleParamsModifier", - " | undefined" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptionsIds.shouldIncrementRevision", - "type": "Function", - "tags": [], - "label": "shouldIncrementRevision", - "description": [], - "signature": [ - "ShouldIncrementRevision", - " | undefined" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "alerting", "id": "def-server.BulkOperationError", @@ -2737,7 +2551,7 @@ "label": "snoozeSchedule", "description": [], "signature": [ - "Readonly<{ id?: string | undefined; skipRecurrences?: string[] | undefined; } & { duration: number; rRule: Readonly<{ count?: number | undefined; interval?: number | undefined; freq?: 0 | 2 | 6 | 5 | 4 | 3 | 1 | undefined; until?: string | undefined; wkst?: \"MO\" | \"TU\" | \"WE\" | \"TH\" | \"FR\" | \"SA\" | \"SU\" | undefined; byweekday?: (string | number)[] | undefined; bymonth?: number[] | undefined; bysetpos?: number[] | undefined; } & { dtstart: string; tzid: string; bymonthday: number[]; byyearday: number[]; byweekno: number[]; byhour: number[]; byminute: number[]; bysecond: number[]; }>; }>[] | undefined" + "Readonly<{ id?: string | undefined; skipRecurrences?: string[] | undefined; } & { duration: number; rRule: Readonly<{ count?: number | undefined; interval?: number | undefined; freq?: 0 | 2 | 6 | 5 | 4 | 3 | 1 | undefined; until?: string | undefined; byweekday?: (string | number)[] | undefined; bymonth?: number[] | undefined; wkst?: \"MO\" | \"TU\" | \"WE\" | \"TH\" | \"FR\" | \"SA\" | \"SU\" | undefined; bysetpos?: number[] | undefined; } & { dtstart: string; tzid: string; bymonthday: number[]; byyearday: number[]; byweekno: number[]; byhour: number[]; byminute: number[]; bysecond: number[]; }>; }>[] | undefined" ], "path": "x-pack/plugins/alerting/server/application/rule/types/rule.ts", "deprecated": false, @@ -4321,57 +4135,9 @@ "label": "BulkEditOperation", "description": [], "signature": [ - "{ operation: \"delete\" | \"add\" | \"set\"; field: \"tags\"; value: string[]; } | { operation: \"add\" | \"set\"; field: \"actions\"; value: ", - "NormalizedAlertAction", - "[]; } | { operation: \"set\"; field: \"schedule\"; value: ", - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.IntervalSchedule", - "text": "IntervalSchedule" - }, - "; } | { operation: \"set\"; field: \"throttle\"; value: string | null | undefined; } | { operation: \"set\"; field: \"notifyWhen\"; value: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\" | null | undefined; } | { operation: \"set\"; field: \"snoozeSchedule\"; value: ", - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.RuleSnoozeSchedule", - "text": "RuleSnoozeSchedule" - }, - "; } | { operation: \"delete\"; field: \"snoozeSchedule\"; value?: string[] | undefined; } | { operation: \"set\"; field: \"apiKey\"; value?: undefined; }" - ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.BulkEditOptions", - "type": "Type", - "tags": [], - "label": "BulkEditOptions", - "description": [], - "signature": [ - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkEditOptionsFilter", - "text": "BulkEditOptionsFilter" - }, - " | ", - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkEditOptionsIds", - "text": "BulkEditOptionsIds" - }, - "" + "Readonly<{} & { value: string[]; operation: \"delete\" | \"add\" | \"set\"; field: \"tags\"; }> | Readonly<{} & { value: Readonly<{ frequency?: Readonly<{} & { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; }> | undefined; uuid?: string | undefined; } & { id: string; params: Record; group: string; }>[]; operation: \"add\" | \"set\"; field: \"actions\"; }> | Readonly<{} & { value: Readonly<{} & { interval: string; }>; operation: \"set\"; field: \"schedule\"; }> | Readonly<{} & { value: string | null; operation: \"set\"; field: \"throttle\"; }> | Readonly<{} & { value: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; operation: \"set\"; field: \"notifyWhen\"; }> | Readonly<{} & { value: Readonly<{ id?: string | undefined; } & { duration: number; rRule: Readonly<{ count?: number | undefined; interval?: number | undefined; freq?: 0 | 2 | 3 | 1 | undefined; until?: string | undefined; byweekday?: string[] | undefined; bymonthday?: number[] | undefined; bymonth?: number[] | undefined; } & { dtstart: string; tzid: string; }>; }>; operation: \"set\"; field: \"snoozeSchedule\"; }> | Readonly<{ value?: string[] | undefined; } & { operation: \"delete\"; field: \"snoozeSchedule\"; }> | Readonly<{} & { operation: \"set\"; field: \"apiKey\"; }>" ], - "path": "x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts", + "path": "x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -4774,38 +4540,10 @@ "text": "RuleTypeParams" }, ">(options: ", - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkEditOptions", - "text": "BulkEditOptions" - }, - ") => Promise<{ rules: ", - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.SanitizedRule", - "text": "SanitizedRule" - }, - "[]; skipped: ", - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.BulkActionSkipResult", - "text": "BulkActionSkipResult" - }, - "[]; errors: ", - { - "pluginId": "alerting", - "scope": "server", - "docId": "kibAlertingPluginApi", - "section": "def-server.BulkOperationError", - "text": "BulkOperationError" - }, - "[]; total: number; }>; bulkEnableRules: (options: ", + "BulkEditOptions", + ") => Promise<", + "BulkEditResult", + ">; bulkEnableRules: (options: ", "BulkOptions", ") => Promise<{ errors: ", { @@ -10477,7 +10215,7 @@ "signature": [ "Omit<", "Options", - ", \"dtstart\" | \"until\" | \"wkst\" | \"byweekday\"> & { dtstart: string; byweekday?: (string | number)[] | undefined; wkst?: ", + ", \"dtstart\" | \"until\" | \"byweekday\" | \"wkst\"> & { dtstart: string; byweekday?: (string | number)[] | undefined; wkst?: ", { "pluginId": "@kbn/rrule", "scope": "common", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 8c2e3125e7885..814213ba42d8d 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 795 | 1 | 765 | 48 | +| 784 | 1 | 754 | 47 | ## Client diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 86ca9300c8707..8a6a35c85b2ce 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index d9d501df2425e..63066ed421111 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 451f7d6d33f80..d2862acf5a322 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-07-24 +date: 2023-07-25 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 aa0358f7e4210..83c1d5e7375fa 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-07-24 +date: 2023-07-25 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 9ecc55af7492f..0cb073d330240 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.devdocs.json b/api_docs/cases.devdocs.json index c66153d2d2fb2..d7975a35756fc 100644 --- a/api_docs/cases.devdocs.json +++ b/api_docs/cases.devdocs.json @@ -70,7 +70,7 @@ "section": "def-public.ICasesDeepLinkId", "text": "ICasesDeepLinkId" }, - ", Partial>> | undefined; }) => { id: \"cases\"; path: string; deepLinks: ({ id: \"cases_create\"; path: string; title: any; keywords?: T[\"keywords\"] | undefined; navLinkStatus?: T[\"navLinkStatus\"] | undefined; searchable?: T[\"searchable\"] | undefined; order?: T[\"order\"] | undefined; tooltip?: T[\"tooltip\"] | undefined; euiIconType?: T[\"euiIconType\"] | undefined; icon?: T[\"icon\"] | undefined; deepLinks?: T[\"deepLinks\"] | undefined; } | { id: \"cases_configure\"; path: string; title: any; keywords?: T[\"keywords\"] | undefined; navLinkStatus?: T[\"navLinkStatus\"] | undefined; searchable?: T[\"searchable\"] | undefined; order?: T[\"order\"] | undefined; tooltip?: T[\"tooltip\"] | undefined; euiIconType?: T[\"euiIconType\"] | undefined; icon?: T[\"icon\"] | undefined; deepLinks?: T[\"deepLinks\"] | undefined; })[]; title: any; keywords?: T[\"keywords\"] | undefined; navLinkStatus?: T[\"navLinkStatus\"] | undefined; searchable?: T[\"searchable\"] | undefined; order?: T[\"order\"] | undefined; tooltip?: T[\"tooltip\"] | undefined; euiIconType?: T[\"euiIconType\"] | undefined; icon?: T[\"icon\"] | undefined; }" + ", Partial>> | undefined; }) => { id: \"cases\"; path: string; deepLinks: ({ id: \"cases_create\"; path: string; title: any; keywords?: T[\"keywords\"] | undefined; navLinkStatus?: T[\"navLinkStatus\"] | undefined; searchable?: T[\"searchable\"] | undefined; category?: T[\"category\"] | undefined; order?: T[\"order\"] | undefined; tooltip?: T[\"tooltip\"] | undefined; euiIconType?: T[\"euiIconType\"] | undefined; icon?: T[\"icon\"] | undefined; deepLinks?: T[\"deepLinks\"] | undefined; } | { id: \"cases_configure\"; path: string; title: any; keywords?: T[\"keywords\"] | undefined; navLinkStatus?: T[\"navLinkStatus\"] | undefined; searchable?: T[\"searchable\"] | undefined; category?: T[\"category\"] | undefined; order?: T[\"order\"] | undefined; tooltip?: T[\"tooltip\"] | undefined; euiIconType?: T[\"euiIconType\"] | undefined; icon?: T[\"icon\"] | undefined; deepLinks?: T[\"deepLinks\"] | undefined; })[]; title: any; keywords?: T[\"keywords\"] | undefined; navLinkStatus?: T[\"navLinkStatus\"] | undefined; searchable?: T[\"searchable\"] | undefined; category?: T[\"category\"] | undefined; order?: T[\"order\"] | undefined; tooltip?: T[\"tooltip\"] | undefined; euiIconType?: T[\"euiIconType\"] | undefined; icon?: T[\"icon\"] | undefined; }" ], "path": "x-pack/plugins/cases/public/common/navigation/deep_links.ts", "deprecated": false, @@ -486,7 +486,7 @@ "section": "def-common.CaseSeverity", "text": "CaseSeverity" }, - " | undefined; assignees?: string | string[] | undefined; reporters?: string | string[] | undefined; defaultSearchOperator?: \"AND\" | \"OR\" | undefined; from?: string | undefined; search?: string | undefined; searchFields?: \"description\" | \"title\" | \"closed_by.username\" | \"closed_by.full_name\" | \"closed_by.email\" | \"closed_by.profile_uid\" | \"created_by.username\" | \"created_by.full_name\" | \"created_by.email\" | \"created_by.profile_uid\" | \"connector.name\" | \"connector.type\" | \"external_service.pushed_by.username\" | \"external_service.pushed_by.full_name\" | \"external_service.pushed_by.email\" | \"external_service.pushed_by.profile_uid\" | \"external_service.connector_name\" | \"external_service.external_id\" | \"external_service.external_title\" | \"external_service.external_url\" | \"title.keyword\" | \"updated_by.username\" | \"updated_by.full_name\" | \"updated_by.email\" | \"updated_by.profile_uid\" | (\"description\" | \"title\" | \"closed_by.username\" | \"closed_by.full_name\" | \"closed_by.email\" | \"closed_by.profile_uid\" | \"created_by.username\" | \"created_by.full_name\" | \"created_by.email\" | \"created_by.profile_uid\" | \"connector.name\" | \"connector.type\" | \"external_service.pushed_by.username\" | \"external_service.pushed_by.full_name\" | \"external_service.pushed_by.email\" | \"external_service.pushed_by.profile_uid\" | \"external_service.connector_name\" | \"external_service.external_id\" | \"external_service.external_title\" | \"external_service.external_url\" | \"title.keyword\" | \"updated_by.username\" | \"updated_by.full_name\" | \"updated_by.email\" | \"updated_by.profile_uid\")[] | undefined; rootSearchFields?: string[] | undefined; sortField?: string | undefined; sortOrder?: \"asc\" | \"desc\" | undefined; to?: string | undefined; owner?: string | string[] | undefined; category?: string | string[] | undefined; } & Partial<", + " | undefined; assignees?: string | string[] | undefined; reporters?: string | string[] | undefined; defaultSearchOperator?: \"AND\" | \"OR\" | undefined; from?: string | undefined; search?: string | undefined; searchFields?: \"description\" | \"title\" | (\"description\" | \"title\")[] | undefined; sortField?: \"category\" | \"title\" | \"createdAt\" | \"updatedAt\" | \"status\" | \"severity\" | \"closedAt\" | undefined; sortOrder?: \"asc\" | \"desc\" | undefined; to?: string | undefined; owner?: string | string[] | undefined; category?: string | string[] | undefined; } & Partial<", "Pagination", ">, signal?: AbortSignal | undefined) => Promise<", { diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 3fc3ec064c5b4..21ee529e0f3c2 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-07-24 +date: 2023-07-25 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 97418f8b31b1e..d06236554db48 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-07-24 +date: 2023-07-25 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 2f981770cdf03..99f4c5d9c6f47 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 517cde284ab29..c4da9ddbce376 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index 409ab5be424a3..8d35ac81834e4 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index aa8af27faaadb..4e4dc5a3f6e9f 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.devdocs.json b/api_docs/cloud_defend.devdocs.json index 77489db1f3f8c..fc3ac94a1e0fb 100644 --- a/api_docs/cloud_defend.devdocs.json +++ b/api_docs/cloud_defend.devdocs.json @@ -799,7 +799,7 @@ "label": "SelectorCondition", "description": [], "signature": [ - "\"containerImageFullName\" | \"containerImageName\" | \"containerImageTag\" | \"kubernetesClusterId\" | \"kubernetesClusterName\" | \"kubernetesNamespace\" | \"kubernetesPodLabel\" | \"kubernetesPodName\" | \"targetFilePath\" | \"ignoreVolumeFiles\" | \"ignoreVolumeMounts\" | \"operation\" | \"processExecutable\" | \"processName\" | \"sessionLeaderInteractive\"" + "\"operation\" | \"containerImageFullName\" | \"containerImageName\" | \"containerImageTag\" | \"kubernetesClusterId\" | \"kubernetesClusterName\" | \"kubernetesNamespace\" | \"kubernetesPodLabel\" | \"kubernetesPodName\" | \"targetFilePath\" | \"ignoreVolumeFiles\" | \"ignoreVolumeMounts\" | \"processExecutable\" | \"processName\" | \"sessionLeaderInteractive\"" ], "path": "x-pack/plugins/cloud_defend/common/v1.ts", "deprecated": false, diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index 09947d662e000..7069c066ef4d1 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-07-24 +date: 2023-07-25 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 99e80c5a18eeb..dd9d118c73927 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-07-24 +date: 2023-07-25 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 91914937b6696..2fd5276b58040 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-07-24 +date: 2023-07-25 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 dafec87bb8334..73ceda8f05d67 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-07-24 +date: 2023-07-25 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 431ca10b83250..25922a2d902c8 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index bb63d34537ff5..289f80d9d6e76 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 5bd5eba882521..56cd9401d41d5 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 3d96815cf9ddd..6ba76c6edfd66 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-07-24 +date: 2023-07-25 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 50764401c8008..b0da2f5d6bc7c 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-07-24 +date: 2023-07-25 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 343f0f187b932..0b5a251866599 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 8d44a06320c39..db40c196a7815 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index 1b61dd4313160..b4c44781b50fa 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -3121,11 +3121,11 @@ "section": "def-common.SavedObjectsPitParams", "text": "SavedObjectsPitParams" }, - " | undefined; defaultSearchOperator?: \"AND\" | \"OR\" | undefined; searchFields?: string[] | undefined; rootSearchFields?: string[] | undefined; sortOrder?: ", + " | undefined; defaultSearchOperator?: \"AND\" | \"OR\" | undefined; searchFields?: string[] | undefined; sortOrder?: ", "SortOrder", " | undefined; searchAfter?: ", "SortResults", - " | undefined; hasReference?: ", + " | undefined; rootSearchFields?: string[] | undefined; hasReference?: ", { "pluginId": "@kbn/core-saved-objects-api-server", "scope": "common", diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 1996434aace9f..aec5ad8ed96f1 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-07-24 +date: 2023-07-25 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 ac761b8e8f615..a98ff5cb434c4 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-07-24 +date: 2023-07-25 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 837fd82c62468..3861b8fdb5da8 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-07-24 +date: 2023-07-25 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 cff2990395d2a..e0cafbaff4fd4 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-07-24 +date: 2023-07-25 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 141aea0d162ec..135e38c86baa7 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-07-24 +date: 2023-07-25 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 8e7803cc99057..f3403ed2472e4 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 38ea388d075da..9f0050fdd5ed6 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -184,7 +184,6 @@ Safe to remove. | | expressions | | | expressions | | | expressions | -| | fleet | | | kibanaReact | | | kibanaReact | | | licensing | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 9f9232df19008..7aa14364008f8 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 33bfd8a2f4176..98bbc8853dd43 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 738dbceb6f3a4..8e195456848cd 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.devdocs.json b/api_docs/discover.devdocs.json index 152ac0c9a0f1d..4d259397fc193 100644 --- a/api_docs/discover.devdocs.json +++ b/api_docs/discover.devdocs.json @@ -24,6 +24,74 @@ } ], "interfaces": [ + { + "parentPluginId": "discover", + "id": "def-public.DiscoverProfileOptions", + "type": "Interface", + "tags": [], + "label": "DiscoverProfileOptions", + "description": [], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.DiscoverProfileOptions.customize", + "type": "Function", + "tags": [], + "label": "customize", + "description": [], + "signature": [ + "(options: ", + "CustomizationCallbackContext", + ") => void | (() => void) | Promise void)>" + ], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.DiscoverProfileOptions.customize.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "CustomizationCallbackContext" + ], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverProfileOptions.deepLinks", + "type": "Array", + "tags": [], + "label": "deepLinks", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-application-browser", + "scope": "common", + "docId": "kibKbnCoreApplicationBrowserPluginApi", + "section": "def-common.AppDeepLink", + "text": "AppDeepLink" + }, + "[] | undefined" + ], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "discover", "id": "def-public.DiscoverStateContainer", @@ -491,6 +559,78 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverProfileId", + "type": "Type", + "tags": [], + "label": "DiscoverProfileId", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "discover", + "id": "def-public.RegisterCustomizationProfile", + "type": "Type", + "tags": [], + "label": "RegisterCustomizationProfile", + "description": [], + "signature": [ + "(id: string, options: ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.DiscoverProfileOptions", + "text": "DiscoverProfileOptions" + }, + ") => void" + ], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.RegisterCustomizationProfile.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.RegisterCustomizationProfile.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.DiscoverProfileOptions", + "text": "DiscoverProfileOptions" + } + ], + "path": "src/plugins/discover/public/customizations/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "discover", "id": "def-public.SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER_ID", @@ -615,64 +755,59 @@ }, { "parentPluginId": "discover", - "id": "def-public.DiscoverStart.customize", + "id": "def-public.DiscoverStart.registerCustomizationProfile", "type": "Function", "tags": [], - "label": "customize", + "label": "registerCustomizationProfile", "description": [], "signature": [ - "(profileName: string, callback: ", + "(id: string, options: ", { "pluginId": "discover", "scope": "public", "docId": "kibDiscoverPluginApi", - "section": "def-public.CustomizationCallback", - "text": "CustomizationCallback" + "section": "def-public.DiscoverProfileOptions", + "text": "DiscoverProfileOptions" }, ") => void" ], "path": "src/plugins/discover/public/plugin.tsx", "deprecated": false, "trackAdoption": false, + "returnComment": [], "children": [ { "parentPluginId": "discover", - "id": "def-public.DiscoverStart.customize.$1", + "id": "def-public.DiscoverStart.registerCustomizationProfile.$1", "type": "string", "tags": [], - "label": "profileName", + "label": "id", "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/discover/public/plugin.tsx", + "path": "src/plugins/discover/public/customizations/types.ts", "deprecated": false, - "trackAdoption": false, - "isRequired": true + "trackAdoption": false }, { "parentPluginId": "discover", - "id": "def-public.DiscoverStart.customize.$2", - "type": "Function", + "id": "def-public.DiscoverStart.registerCustomizationProfile.$2", + "type": "Object", "tags": [], - "label": "callback", + "label": "options", "description": [], "signature": [ { "pluginId": "discover", "scope": "public", "docId": "kibDiscoverPluginApi", - "section": "def-public.CustomizationCallback", - "text": "CustomizationCallback" + "section": "def-public.DiscoverProfileOptions", + "text": "DiscoverProfileOptions" } ], - "path": "src/plugins/discover/public/plugin.tsx", + "path": "src/plugins/discover/public/customizations/types.ts", "deprecated": false, - "trackAdoption": false, - "isRequired": true + "trackAdoption": false } - ], - "returnComment": [] + ] } ], "lifecycle": "start", diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 64c8cd748110d..8d2cc98e4a88c 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.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 | |-------------------|-----------|------------------------|-----------------| -| 97 | 0 | 71 | 14 | +| 105 | 0 | 79 | 14 | ## Client diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index d60a57e9722c9..90fff3f162877 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 8447526758185..c93e982cb6832 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 5acc88dc59aab..592f551d3ca2f 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 0412623c4a93f..c973e87e3b0e7 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-07-24 +date: 2023-07-25 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 2f558fc52d0bf..5094563edf696 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-07-24 +date: 2023-07-25 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 16ec85e0318cb..af0f7e1c39035 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-07-24 +date: 2023-07-25 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 980a387be95df..a5ca53c5d0189 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 73bbec743d57e..934a7e2309fc5 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index c022d40d9ea43..dce8508554ef4 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-07-24 +date: 2023-07-25 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 4a3add6e01000..504e7a9aee5de 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-24 +date: 2023-07-25 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 cc43ea1a61146..a5c2c4fbfb5ad 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-07-24 +date: 2023-07-25 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 2d54c99194d86..631c775338e34 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-07-24 +date: 2023-07-25 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 589ffe8c7b85c..b912b7da77162 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-07-24 +date: 2023-07-25 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 a4bd3c4933ce9..c758aa1142bfd 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-07-24 +date: 2023-07-25 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 913858ae57e1b..e29f7e68a4099 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-07-24 +date: 2023-07-25 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 a8e1f1f327aac..f1bfd4f3130ba 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-07-24 +date: 2023-07-25 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 675f05388a1a5..cd27d26215030 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-07-24 +date: 2023-07-25 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 a65a9a8503d3e..aec273c13f524 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-07-24 +date: 2023-07-25 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 fef8a16f3bb93..7acdd2d8a8b24 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-07-24 +date: 2023-07-25 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 af09e4054950f..9601a85ef617e 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-07-24 +date: 2023-07-25 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 ed365ad68952e..92de9fec7759c 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-07-24 +date: 2023-07-25 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 26b51db8c893c..4f6635fc03a92 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-07-24 +date: 2023-07-25 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 4f482e4f89f20..dea1d4ba9e244 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-07-24 +date: 2023-07-25 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 9f4a52775fc68..f8115a00f4be0 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-07-24 +date: 2023-07-25 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 19a68028b0461..4889045ee5b0b 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.devdocs.json b/api_docs/field_formats.devdocs.json index d4f8c33a70b9e..066b2d29c4761 100644 --- a/api_docs/field_formats.devdocs.json +++ b/api_docs/field_formats.devdocs.json @@ -5534,6 +5534,36 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.DURATION_INPUT_FORMATS", + "type": "Array", + "tags": [], + "label": "DURATION_INPUT_FORMATS", + "description": [], + "signature": [ + "{ text: any; kind: string; }[]" + ], + "path": "src/plugins/field_formats/common/constants/duration_formats.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.DURATION_OUTPUT_FORMATS", + "type": "Array", + "tags": [], + "label": "DURATION_OUTPUT_FORMATS", + "description": [], + "signature": [ + "({ text: any; method: string; shortText?: undefined; } | { text: any; shortText: any; method: string; })[]" + ], + "path": "src/plugins/field_formats/common/constants/duration_formats.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "fieldFormats", "id": "def-common.FieldFormatConfig", @@ -6614,6 +6644,36 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.DEFAULT_DURATION_INPUT_FORMAT", + "type": "Object", + "tags": [], + "label": "DEFAULT_DURATION_INPUT_FORMAT", + "description": [], + "signature": [ + "{ text: any; kind: string; }" + ], + "path": "src/plugins/field_formats/common/constants/duration_formats.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.DEFAULT_DURATION_OUTPUT_FORMAT", + "type": "Object", + "tags": [], + "label": "DEFAULT_DURATION_OUTPUT_FORMAT", + "description": [], + "signature": [ + "{ text: any; method: string; }" + ], + "path": "src/plugins/field_formats/common/constants/duration_formats.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "fieldFormats", "id": "def-common.FORMATS_UI_SETTINGS", diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 40783989b462f..e3d32135949db 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.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 | |-------------------|-----------|------------------------|-----------------| -| 288 | 26 | 249 | 3 | +| 292 | 26 | 253 | 3 | ## Client diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index a32cb8088f74b..7bea0d1f5631a 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-07-24 +date: 2023-07-25 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 7dd92a6ceac8f..4079755e782d7 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-07-24 +date: 2023-07-25 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 faec2f609c3f8..17450218cccd9 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-07-24 +date: 2023-07-25 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 ee84d6deead3a..325cf806cd278 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -20654,9 +20654,7 @@ "parentPluginId": "fleet", "id": "def-common.ListWithKuery", "type": "Interface", - "tags": [ - "deprecated" - ], + "tags": [], "label": "ListWithKuery", "description": [], "signature": [ @@ -20677,9 +20675,8 @@ } ], "path": "x-pack/plugins/fleet/common/types/rest_spec/common.ts", - "deprecated": true, + "deprecated": false, "trackAdoption": false, - "references": [], "children": [ { "parentPluginId": "fleet", @@ -24224,6 +24221,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.FLEET_ENROLLMENT_API_PREFIX", + "type": "string", + "tags": [], + "label": "FLEET_ENROLLMENT_API_PREFIX", + "description": [], + "signature": [ + "\"fleet-enrollment-api-keys\"" + ], + "path": "x-pack/plugins/fleet/common/constants/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.FLEET_KUBERNETES_PACKAGE", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 7e418461e80ff..53db65c1636f1 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-07-24 +date: 2023-07-25 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 | |-------------------|-----------|------------------------|-----------------| -| 1182 | 3 | 1066 | 40 | +| 1183 | 3 | 1067 | 40 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 7949d49a5f9af..76c24bd3a7782 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-07-24 +date: 2023-07-25 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 d606445acda19..fd8f627e7adf5 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-07-24 +date: 2023-07-25 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 768929ebc71cb..0e167c6cecfc5 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-07-24 +date: 2023-07-25 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 7a77f5003154f..4a55f44829505 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-07-24 +date: 2023-07-25 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 177500b95c220..5a2f3285805ea 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-07-24 +date: 2023-07-25 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 99ef501f27afc..4bd841c7ef17b 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-07-24 +date: 2023-07-25 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 f6287d32f3f0f..82592787c8086 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 3d8cb6f02a71a..83bdbdfd6a393 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-07-24 +date: 2023-07-25 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 df917b1b0cfcf..d1d0a39d71155 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-07-24 +date: 2023-07-25 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 222a07588f4db..d20714010507f 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 8a3333614b6ef..ba6531a1001ca 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 422445121250a..df9e97256e3d7 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 52cf43b1ae491..3f9796c9cf7d0 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 3a1ba2203bf26..2f19ea35a0d00 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 d4b1105b4d77d..3cba26ec0dcfa 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-24 +date: 2023-07-25 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 f16c472439e3e..804eb4606ba39 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-07-24 +date: 2023-07-25 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 d5cec25b58f15..c2402dfa090df 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 8bc637e69fffc..57a58498176de 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 a41b2d2177c2d..f8ff06ca69983 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-07-24 +date: 2023-07-25 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 6e7d932ca330f..c19a67097741c 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-07-24 +date: 2023-07-25 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 70793ab646e94..710372c57c416 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 5e10bfcf1a73c..bd3819e110fdf 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index c09ab2c0e8c8e..e282a9244ac3e 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 77f8b1edd7b2a..f4d712b73fdb1 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-07-24 +date: 2023-07-25 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 973c9fe6f3ab4..a76a3feaa546b 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-07-24 +date: 2023-07-25 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 061092d33c8bd..21f3e7ec77e4d 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 bc26c5b37c8a9..dc06b9442c90c 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index cbf19ca053352..7e4331f65f653 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-07-24 +date: 2023-07-25 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 b50f54ae3a990..0cd1ac5b87cc9 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-24 +date: 2023-07-25 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 7272389786dcf..36cedd9869d5a 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-24 +date: 2023-07-25 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 d81652f3fa39e..ca86b16c5d09b 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-07-24 +date: 2023-07-25 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 4d255f01a5490..b85ba8d9a2cce 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-07-24 +date: 2023-07-25 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 74604cc561d35..ffc1a3bd95e75 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-07-24 +date: 2023-07-25 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 4ba1c89c5e8b2..fe9980d90db44 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-07-24 +date: 2023-07-25 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 7d0578f06ebd6..01dab9b1e695f 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-07-24 +date: 2023-07-25 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 335a47543144d..d5eb796a42a0f 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index bfc480bcfca3d..6bd479f1e6b4e 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 47482c822d82b..c6553274b25a2 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-07-24 +date: 2023-07-25 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 5d99cd7f045ad..af12011733c9b 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-07-24 +date: 2023-07-25 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 526ec1cea404e..7d18b57fee5a7 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 5133eaf9a6845..bd4f9dd4894db 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-07-24 +date: 2023-07-25 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 616332a5d8b12..4daaa199b7c21 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-07-24 +date: 2023-07-25 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 e87d120aaae42..0142304beba2c 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-24 +date: 2023-07-25 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 a8c5af21240b9..f933247d4c9e4 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 16896670faca3..10bb54573769e 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-24 +date: 2023-07-25 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 44895f72e439d..16a8f6811924a 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 4e74790ed5d97..b16d11ed8a92d 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 e1947a0c58e4c..122a916c09644 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 9e32e28afd06b..af3f4e23d7291 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 31b7d3b48edca..7e92093916001 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-07-24 +date: 2023-07-25 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 8c9136dd4cdf4..a6f3b9bde2c5a 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 c77371d96aec9..d61c7d20547af 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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.devdocs.json b/api_docs/kbn_core_application_browser.devdocs.json index 662fd133880ed..1882894950b1b 100644 --- a/api_docs/kbn_core_application_browser.devdocs.json +++ b/api_docs/kbn_core_application_browser.devdocs.json @@ -1777,7 +1777,15 @@ "section": "def-common.AppNavLinkStatus", "text": "AppNavLinkStatus" }, - " | undefined; searchable?: boolean | undefined; } & ", + " | undefined; searchable?: boolean | undefined; category?: ", + { + "pluginId": "@kbn/core-application-common", + "scope": "common", + "docId": "kibKbnCoreApplicationCommonPluginApi", + "section": "def-common.AppCategory", + "text": "AppCategory" + }, + " | undefined; } & ", { "pluginId": "@kbn/core-application-browser", "scope": "common", diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 673134a58cc46..0374b2c1f1aa4 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 d4bf4adf8a1ed..18cf0d771c6ad 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 47c9867e3d1a6..545dfe5c4a586 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 39027dc51ffe6..527734039a051 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-07-24 +date: 2023-07-25 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 a8288c3940bea..81683f4ac25ef 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 bd3cb06e6f273..03adef72907cd 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 d6b9f25679e90..0adcd136c3266 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 5196048f57d0d..dbcc023e85cc1 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 f012cd09f90b8..ae4d6a0623b9e 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-07-24 +date: 2023-07-25 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 a7b682fc33f76..8f2e82c11c54e 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 ed2e10213dbf9..160ddfb8938e2 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 7153e74b8529b..4c03359b8ebc2 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 d22463238fdef..cf991a63e09b4 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-07-24 +date: 2023-07-25 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 518e3324f6fd5..6c2da802fe21a 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-07-24 +date: 2023-07-25 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 56cd648966b69..168fb812354ab 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 5c96c0879691b..026729e31e79d 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 928c2bb1bf7d3..8c051b77f04b7 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 e9685a409f341..8ac5e13cbdb58 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 8afc006a6250c..240df5ad686cc 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 d4cb231964b60..3fb740938d136 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 762fc9a0f61a0..d3339d281cbca 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 d247bb210c013..1dcf1880d54ce 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-07-24 +date: 2023-07-25 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 4eb20cd2cfe5b..f10d139205af3 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-07-24 +date: 2023-07-25 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 bd7ff24467bb7..9998a2483f61c 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 7209cc81f330e..8e2489e9d2613 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 7ba6e00825e4f..a612e2b09900f 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 442459234ce07..b32eb354ea748 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 1fcf675347e7f..f120755e70060 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 9195f243e79f7..27a45cad10575 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-07-24 +date: 2023-07-25 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 66cb11863cbd2..17d6952016db9 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-07-24 +date: 2023-07-25 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 15e2e5600c5e7..1817cfb8c76f0 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 aaf847ed15a78..d1e1e67bef7a3 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 793de003dce57..b7e28a36c8f1a 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 8b4dd42a51173..5a8d317376efb 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 8f47c3a508fe5..a6014fd24a5db 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-07-24 +date: 2023-07-25 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 f371af9591a8a..2fdfdfbb56f20 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 386120ac648c8..9024c77a7a394 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 971339e709e7d..21ac86a9435f5 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 2dcdfbaa057d8..bdfed140b7f03 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-07-24 +date: 2023-07-25 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 1f18ac4128e48..1efade95ce978 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 232bf10090358..e27b488d0cf92 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 11568e4d2b4c2..8d626a2c44ae5 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 79adadc2266e4..6256fd6b00f34 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 acaa681b1d3b2..1e7ad4a542ece 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 6a2f27fdc60f0..a64e2b9ffae01 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 872f57fe08502..17625336a73b2 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 4da7de75fc7db..f9f66121a41b6 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-07-24 +date: 2023-07-25 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 2fdfc79cd21d0..92a485b3bab08 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-07-24 +date: 2023-07-25 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 1a6a207e5967d..dc8d473abedb8 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 7d9b9843d63c7..afc629954bb9e 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 4af935717eb12..5a8b5ecec85fe 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 934659604f454..a1365c26e95a3 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 843c9d557d115..bd1673ce43042 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 9a3153e749023..763bdd41ccdb0 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 ea5ded39f3fec..07530ed9dfd38 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 08d9c0f2e074b..db45ead3a1bdd 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-07-24 +date: 2023-07-25 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 9cab3ca810063..bb1e18af168b7 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 e4710571602e7..b5b46fe9558a0 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-07-24 +date: 2023-07-25 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 21ec4edea150e..264e3bec80c9c 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-07-24 +date: 2023-07-25 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 2d3e3e2016f42..1a5f2d99d1a40 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 3ab3971776658..701980bceb965 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 433c7d3916244..a8509fad61ec1 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 712d2b3121c53..4db8571f36129 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 e0de3c7a3ff08..bfea95fc28b2c 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -6319,7 +6319,7 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.ts" + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts" }, { "plugin": "alerting", @@ -6359,15 +6359,15 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/snooze_rule.ts" + "path": "x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts" }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/unsnooze_rule.ts" + "path": "x-pack/plugins/alerting/server/routes/snooze_rule.ts" }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/bulk_edit_rules.ts" + "path": "x-pack/plugins/alerting/server/routes/unsnooze_rule.ts" }, { "plugin": "alerting", @@ -7561,22 +7561,6 @@ "plugin": "actions", "path": "x-pack/plugins/actions/server/routes/get_oauth_access_token.test.ts" }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/bulk_edit_rules.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/bulk_edit_rules.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/bulk_edit_rules.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/bulk_edit_rules.test.ts" - }, { "plugin": "alerting", "path": "x-pack/plugins/alerting/server/routes/clone_rule.test.ts" @@ -7961,34 +7945,6 @@ "plugin": "remoteClusters", "path": "x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts" }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts" - }, { "plugin": "crossClusterReplication", "path": "x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts" @@ -8029,6 +7985,50 @@ "plugin": "spaces", "path": "x-pack/plugins/spaces/server/routes/api/external/update_objects_spaces.test.ts" }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts" + }, { "plugin": "home", "path": "src/plugins/home/server/plugin.test.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 925af45a6f16d..dee0c197b9760 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-07-24 +date: 2023-07-25 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 862ba1be9c131..3f5935720e4e1 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 f3f7ec6bca191..d590ef97f3146 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 df3a075fcfc29..61f1dce7ed209 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 8454ad662a246..1d5da759f274a 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 b0e32bef612b0..3429c4f096e47 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-07-24 +date: 2023-07-25 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 c902864ed3395..16adf76ed1c98 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 d37b3d3269051..9bfa4bfd73259 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 6538b19bd7d5e..5b908a45c0227 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 2f000f37789ec..7a05be32c4db4 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 aba5da86076de..1d3ea26d5201e 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 a9aa2d9986386..94a0c1e2db815 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 ff13480f58fe5..08d311894967e 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 ec0aa477669cc..5905f57c24b6b 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-07-24 +date: 2023-07-25 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 54507fa0b41b3..d4db2fb2779a2 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 291714ce0306b..6650efe5ccdec 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 8000a0cb185ad..3aeaf8da67007 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 a251a63d4f391..15b9ab447ffe7 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-07-24 +date: 2023-07-25 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 99ad310c9e6ed..942c6bc64ebde 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 ec7cb6718a3e6..ec049a41394fe 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 a76c9ca5d77f1..a7e03688bbaa7 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 168abc581731d..51c2fc4563e2c 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 8541b76234a3b..c02093fe7b4ab 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-07-24 +date: 2023-07-25 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 329058dec4023..dfe19d505f122 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 c4680b05b834a..18b346c1b57f3 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 0db445536b426..b08016de4b2a0 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 432d7af78412e..a8cd0dcee179b 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-07-24 +date: 2023-07-25 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 9221269456bf4..c96fc82d4b899 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 24583c8b89996..8ff8fa06607a7 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 24dd1efbd6c6c..e8460565c22d4 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 bc6ef00f60318..30cfb53e02b00 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 bcf5435a192ca..1105491444815 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 fc014bc71e721..4092ba097d2bb 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 1ba83503bded4..4917810b75e59 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 daded76064478..1e062986db2fc 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 25594e6959d67..197ed745642c6 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 b1d285d342cdf..1a93d4aafebf5 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 092b98e447d42..f9c3b1e84dd84 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-07-24 +date: 2023-07-25 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 1cc4b7be42a27..ef2c5d0345995 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 4afcbeec9148c..792cb9a637c5c 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-07-24 +date: 2023-07-25 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 770a6ab32a9f1..6b1f7fd37b69e 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 8310b6c022388..20cc17a311eb4 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 c13a33dbe17ba..dfe877ff38a98 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 b4920fe30722e..3db82c0b14f9f 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 a115ae3a3be60..180b17380daa1 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 75c7829fdb177..5313d490d7b29 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-07-24 +date: 2023-07-25 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.devdocs.json b/api_docs/kbn_core_saved_objects_api_server.devdocs.json index 31fbb9fb8cb39..16928f702204e 100644 --- a/api_docs/kbn_core_saved_objects_api_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_server.devdocs.json @@ -2720,11 +2720,11 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" + "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" + "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" }, { "plugin": "alerting", @@ -2740,11 +2740,11 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" + "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" + "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" }, { "plugin": "alerting", @@ -8213,9 +8213,9 @@ "signature": [ "{ type: string | string[]; search?: string | undefined; filter?: any; aggs?: Record | undefined; namespaces?: string[] | undefined; perPage?: number | undefined; fields?: string[] | undefined; sortField?: string | undefined; preference?: string | undefined; defaultSearchOperator?: \"AND\" | \"OR\" | undefined; searchFields?: string[] | undefined; rootSearchFields?: string[] | undefined; sortOrder?: ", + "> | undefined; namespaces?: string[] | undefined; perPage?: number | undefined; fields?: string[] | undefined; sortField?: string | undefined; preference?: string | undefined; defaultSearchOperator?: \"AND\" | \"OR\" | undefined; searchFields?: string[] | undefined; sortOrder?: ", "SortOrder", - " | undefined; hasReference?: ", + " | undefined; rootSearchFields?: string[] | undefined; hasReference?: ", { "pluginId": "@kbn/core-saved-objects-api-server", "scope": "common", diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 1200b03ff4d39..2b95dc8082bc2 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-07-24 +date: 2023-07-25 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 1de7325f058fc..6ad999a7d649b 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 311236e406346..00241eb5fd398 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 7aa35326b57ec..9132f7f5ec0a4 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 2ac196984e3a9..de93f0579e099 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 0ff1289a9d9df..e6c37906a631a 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 5a76e19599642..18086270c9e49 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 ff1452db113e5..d271f676e6e1d 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-07-24 +date: 2023-07-25 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 59b6972f2d810..e7bcdf73cc06a 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 674311fd10a83..367d5ec6f6623 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 42dd85d76ef4b..b9cc0b34bdd0e 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 c9086e3b1aee9..784ebfd38b329 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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.devdocs.json b/api_docs/kbn_core_saved_objects_server.devdocs.json index c8938d2d31144..706b7e0a90e51 100644 --- a/api_docs/kbn_core_saved_objects_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_server.devdocs.json @@ -6185,11 +6185,11 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" + "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" + "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" }, { "plugin": "alerting", @@ -6205,11 +6205,11 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" + "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" + "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" }, { "plugin": "alerting", diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 5075efffecaa0..163b412768ee8 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-07-24 +date: 2023-07-25 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 d034b7c1aa33d..ba24948eb708e 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 b06f1f14185e1..5c8d14a219551 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 7d3af63ef1cf3..3381e84f152a0 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 08c3e35a01118..5cf45c5f334b7 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-07-24 +date: 2023-07-25 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 741b39cfe85c3..33c9050a6f0fe 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 22e45ccd1b0be..decce22bb2309 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-07-24 +date: 2023-07-25 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 6c3e9ab7ab6ca..0558bc97f1681 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 375c05d882708..05a7e9530189f 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 1844b13afe917..df016f324e14f 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-07-24 +date: 2023-07-25 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 ff1117dba0b42..d0f199ee59552 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 60da99c5cc2a1..4c16264b94ee6 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 6a3ef6718a504..e77f1529b422e 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-07-24 +date: 2023-07-25 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 505e6abe4b8f9..fa4132098cc2b 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 e4f09b7084856..187071c3f052e 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index d148bee54a358..ff390281a0767 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 3e112d9c541fb..ffed699e165d0 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 e077409424ce6..d1a59928505aa 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 2b7d56fcb5a82..1b19d54096ac2 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 a1cbebbbc8164..a74c28410b2db 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 573c115c955d7..9bb2d64071320 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-07-24 +date: 2023-07-25 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 deb2a55c01a7d..11f25b3d7e1d6 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-07-24 +date: 2023-07-25 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 27a0ae49f655a..50ead83c43319 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 862f6ce589484..2b3513ab873d1 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 7a6cfcd02c2b8..1b433abb110e9 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-07-24 +date: 2023-07-25 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 ee9a12e4c6e7b..df6456e1d53e5 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 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 6bbdebdad51dd..50e5e07dcd5a7 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 89c34a0d12e61..857b76b0ceb75 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index ea4d32e7dd654..04881cb69ff27 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 0c0648aed5f88..5a5235ca50b67 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 50f290712bb47..7e18a4535eb4e 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-07-24 +date: 2023-07-25 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 4320150150645..6b7437ae11daa 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 554ad6d3f78d3..12249b11fe15c 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 6ebdefe566fa5..230da3d6bcd61 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 89c1af63db870..d93d484303efd 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-07-24 +date: 2023-07-25 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 a3ed9f7a36846..1a6164d808208 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-24 +date: 2023-07-25 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 1aa7f37ac7bd7..fefc3780a6941 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 89356fd2b5f6a..c533701f4d2f6 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-24 +date: 2023-07-25 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 c4cab9223d386..db17cb42f22d7 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.devdocs.json b/api_docs/kbn_deeplinks_observability.devdocs.json index 51a50d02fa1b1..dbcbc0da8d191 100644 --- a/api_docs/kbn_deeplinks_observability.devdocs.json +++ b/api_docs/kbn_deeplinks_observability.devdocs.json @@ -52,7 +52,7 @@ "section": "def-common.AppId", "text": "AppId" }, - " | \"logs:settings\" | \"logs:stream\" | \"logs:log-categories\" | \"logs:anomalies\" | \"observability-overview:cases\" | \"observability-overview:rules\" | \"observability-overview:alerts\" | \"observability-overview:cases_create\" | \"observability-overview:cases_configure\" | \"observability-overview:slos\" | \"metrics:settings\" | \"metrics:inventory\" | \"metrics:metrics-explorer\" | \"metrics:metrics-hosts\" | \"apm:traces\" | \"apm:dependencies\" | \"apm:service-map\" | \"apm:settings\" | \"apm:services\" | \"apm:service-groups-list\" | \"apm:storage-explorer\"" + " | \"discover:log-explorer\" | \"logs:settings\" | \"logs:stream\" | \"logs:log-categories\" | \"logs:anomalies\" | \"observability-overview:cases\" | \"observability-overview:rules\" | \"observability-overview:alerts\" | \"observability-overview:cases_create\" | \"observability-overview:cases_configure\" | \"observability-overview:slos\" | \"metrics:settings\" | \"metrics:inventory\" | \"metrics:metrics-explorer\" | \"metrics:metrics-hosts\" | \"apm:traces\" | \"apm:dependencies\" | \"apm:service-map\" | \"apm:settings\" | \"apm:services\" | \"apm:service-groups-list\" | \"apm:storage-explorer\"" ], "path": "packages/deeplinks/observability/deep_links.ts", "deprecated": false, diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index c14a1aa913226..3d2540bbfa773 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-24 +date: 2023-07-25 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 580392c198db3..d55882c96634a 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index ec67b9b7b084f..8b56232b719df 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-24 +date: 2023-07-25 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 bf8f2c8785645..4196d23767066 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-24 +date: 2023-07-25 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 f9b9cdc53c6a2..4b3aa89286d28 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-24 +date: 2023-07-25 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 36d515a238410..9441ed77ff824 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-24 +date: 2023-07-25 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 f6dac5b99ce0f..e71ea0e5e9db3 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-07-24 +date: 2023-07-25 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 ecdc362a9c24c..2e83993d4c556 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-07-24 +date: 2023-07-25 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 cb5184c1773cb..7b053a31a8f1c 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-07-24 +date: 2023-07-25 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 a8fc0c2cca792..9a735dfe01f6d 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 83823d5d9f080..5964e9b5fefb2 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: 2023-07-24 +date: 2023-07-25 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 9f1453f69bebd..8b67ec2a4f2cf 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-07-24 +date: 2023-07-25 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 223a3579adb6e..5cd1833c4d3c9 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 5206e9a808476..35f9dc33c83fe 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-24 +date: 2023-07-25 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 017d7b1671565..fcdc006b92732 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 84e11f57bd1b1..58ed67648361b 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 1b491c90aa120..4da00475ce45e 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index af6e5719aaeab..c4c217f6e20ee 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 63441d01696c4..9d99574fe0e56 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-07-24 +date: 2023-07-25 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 06d8e6ddf1fea..10183fda444de 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-07-24 +date: 2023-07-25 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 d5792a8fe7775..301192aa95f8d 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-07-24 +date: 2023-07-25 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 c1e74accd142d..a4039d8d7af8c 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index c01a05e931338..55fab7296a76c 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-07-24 +date: 2023-07-25 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 58b08a1ee77d5..94a9d23105349 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index c38c4b07a180c..1fe37b12194d8 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: 2023-07-24 +date: 2023-07-25 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 95dd3b25b665a..f36f483531513 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: 2023-07-24 +date: 2023-07-25 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.devdocs.json b/api_docs/kbn_expandable_flyout.devdocs.json index bff7c42b73719..de3d777b06560 100644 --- a/api_docs/kbn_expandable_flyout.devdocs.json +++ b/api_docs/kbn_expandable_flyout.devdocs.json @@ -184,24 +184,24 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, " | undefined; right?: ", { "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, " | undefined; preview?: ", { "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, " | undefined; }) => void" ], @@ -232,8 +232,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, " | undefined" ], @@ -253,8 +253,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, " | undefined" ], @@ -274,8 +274,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, " | undefined" ], @@ -303,8 +303,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, ") => void" ], @@ -324,8 +324,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" } ], "path": "packages/kbn-expandable-flyout/src/context.tsx", @@ -351,8 +351,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, ") => void" ], @@ -372,8 +372,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" } ], "path": "packages/kbn-expandable-flyout/src/context.tsx", @@ -399,8 +399,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" }, ") => void" ], @@ -420,8 +420,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "common", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-common.FlyoutPanel", - "text": "FlyoutPanel" + "section": "def-common.FlyoutPanelProps", + "text": "FlyoutPanelProps" } ], "path": "packages/kbn-expandable-flyout/src/context.tsx", @@ -588,10 +588,10 @@ }, { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-common.FlyoutPanel", + "id": "def-common.FlyoutPanelProps", "type": "Interface", "tags": [], - "label": "FlyoutPanel", + "label": "FlyoutPanelProps", "description": [], "path": "packages/kbn-expandable-flyout/src/types.ts", "deprecated": false, @@ -599,7 +599,7 @@ "children": [ { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-common.FlyoutPanel.id", + "id": "def-common.FlyoutPanelProps.id", "type": "string", "tags": [], "label": "id", @@ -612,7 +612,7 @@ }, { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-common.FlyoutPanel.params", + "id": "def-common.FlyoutPanelProps.params", "type": "Object", "tags": [], "label": "params", @@ -628,7 +628,7 @@ }, { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-common.FlyoutPanel.path", + "id": "def-common.FlyoutPanelProps.path", "type": "Array", "tags": [], "label": "path", @@ -644,7 +644,7 @@ }, { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-common.FlyoutPanel.state", + "id": "def-common.FlyoutPanelProps.state", "type": "Object", "tags": [], "label": "state", diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index bbb8e3238ba26..96a6c756988d3 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-24 +date: 2023-07-25 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 41816ad613c5f..01809fb3fbbd8 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index ed07b62d900b7..2d2be17d9845c 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index d2da3fadf63db..70887e0ced0e2 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index b2856531b8a76..1ff30da7dc991 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-07-24 +date: 2023-07-25 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 25113039bbddc..a9c14b887d20d 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-24 +date: 2023-07-25 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 35b5cebc9704e..5648d71ed13e9 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 8b029a35fcd8a..b2abf10ae7340 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 1e45fe0ae1396..e56aacd6d0527 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-07-24 +date: 2023-07-25 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 d841fbc69f8d3..ec517f431b606 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-07-24 +date: 2023-07-25 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 34c8ceaa80f3b..8f5e2ad5faf1d 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 f4cb554224891..bf1a360a20b00 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-07-24 +date: 2023-07-25 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 016b164e2c213..63c3bf3b580bf 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-07-24 +date: 2023-07-25 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 6756521827465..84a9d8eb79711 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-07-24 +date: 2023-07-25 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 a599ed90b39e9..bfd9be76b432a 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-07-24 +date: 2023-07-25 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 55be3a7bf153a..074b3fa79b622 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-07-24 +date: 2023-07-25 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 43343eaf6b115..b1cf84aa41512 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index f22d939806a0f..bc5837d6b21ab 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-24 +date: 2023-07-25 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 d058a7b6a344f..854a288b6e528 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 8651662103eb7..f18a2ad311a7c 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index d60ea406e5d5e..0be75367d5e34 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-07-24 +date: 2023-07-25 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 92926ac1e64e9..da4019dcb61c8 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-07-24 +date: 2023-07-25 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 279cccf564d0f..f84a3ac7ac771 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-07-24 +date: 2023-07-25 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 450781e6d2de8..4269bd9e71e59 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-07-24 +date: 2023-07-25 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 1ff7d20dd502a..f2cf653ff7162 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 6917138f57f3a..ac2c85c35be2b 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-07-24 +date: 2023-07-25 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 32d115174b674..790f585b4ac63 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 94cb51eecdb66..2dcde8b341ddd 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-07-24 +date: 2023-07-25 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 46216aabfbb56..8917fc079b028 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 09fd0a34a3a85..8c60f5c93e06a 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-24 +date: 2023-07-25 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 f0fb457ebb2e6..111cff557ba18 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-07-24 +date: 2023-07-25 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 9dc9b1bb25d1f..f187e644662de 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 bcee95273cb62..208e1d6d282dc 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 bd01fb905bf42..111c51eca18dd 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-24 +date: 2023-07-25 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_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index c3661be93c9b2..f1650993f602b 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: 2023-07-24 +date: 2023-07-25 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_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 4054fe202edcd..384d0caad02dc 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 355004bcb5a43..972f4df235ccf 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-24 +date: 2023-07-25 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 4c5d861ba11a6..8d8c1e736b6a1 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-07-24 +date: 2023-07-25 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 04594325e222d..e798ef7e38632 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 edc4a9229f23d..08d263734130d 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index d27b2b6664381..3241437c4a2a4 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-07-24 +date: 2023-07-25 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 b6331b01f9419..be815e8dba438 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-07-24 +date: 2023-07-25 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 f9aaa94a127c5..be98571561f4c 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-24 +date: 2023-07-25 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 37a6fa67fc0af..b68c3823a293d 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-07-24 +date: 2023-07-25 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 74f61d0ec2e0c..49d867252d8a9 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-07-24 +date: 2023-07-25 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 ec3c945fb65be..e72a6e903103a 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 4827e881a1895..0a7557b62342a 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 1afd33f0bff85..adf8fc8d12ec2 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 e2e308b7b32fb..7a5d89eefb986 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 f8d876f9822f7..3d5544147a923 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 dc978619a0c2a..76a30cc76a6ca 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index f65f1ed13ca94..f974b61fe9a2b 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 9c2c745ab3a6b..8178c6175a2b7 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index e01f819d5118f..318a6e683e1c6 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-07-24 +date: 2023-07-25 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 a708787c6a9f3..a25ca89783577 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-24 +date: 2023-07-25 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 6b012306a44ce..694b0a21e302c 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 484a424f656e3..17dc88492677c 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-07-24 +date: 2023-07-25 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 42ad7b809a2fb..bd4e31d36e20d 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-07-24 +date: 2023-07-25 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 29214c854803b..2fe2472615a59 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 1b960fd5b429c..a114c07a2ca3f 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 555978b1219aa..35aa8a6bf4530 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-07-24 +date: 2023-07-25 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 239aacbb159bf..8bf90403d056b 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 0699f01f31ff9..bbfe67f9b1f5b 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-24 +date: 2023-07-25 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 d0e9f49d3b663..0131d22c1fd34 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index ceebf1de2d458..22745d35ab9ea 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-07-24 +date: 2023-07-25 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 50e44778b9286..470b6859cbe0f 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-07-24 +date: 2023-07-25 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 172f31ad45843..c9a2335974255 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-07-24 +date: 2023-07-25 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 c40105eed3c2f..4cb34a12fa07a 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-07-24 +date: 2023-07-25 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 87d9210cc652d..d6ecccf53f02b 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 8bd74b0d95282..32204e355b6bd 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.devdocs.json b/api_docs/kbn_rrule.devdocs.json index 849f4cc2f8ff7..a2359c9a4e56a 100644 --- a/api_docs/kbn_rrule.devdocs.json +++ b/api_docs/kbn_rrule.devdocs.json @@ -245,7 +245,7 @@ "label": "ConstructorOptions", "description": [], "signature": [ - "Omit & { byweekday?: (string | number)[] | null | undefined; wkst?: number | \"MO\" | \"TU\" | \"WE\" | \"TH\" | \"FR\" | \"SA\" | \"SU\" | null | undefined; }" + "Omit & { byweekday?: (string | number)[] | null | undefined; wkst?: number | \"MO\" | \"TU\" | \"WE\" | \"TH\" | \"FR\" | \"SA\" | \"SU\" | null | undefined; }" ], "path": "packages/kbn-rrule/rrule.ts", "deprecated": false, diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index d51cf807f3d5e..10ac52ad6edb6 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-07-24 +date: 2023-07-25 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 aaa346f1947d8..93a2b0ff6dbd7 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 ecaa3aa381d5e..112c155672699 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 4a43ce7834efb..362e81d3b5584 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-24 +date: 2023-07-25 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 3134f87f4277a..e0c6c56ff9c7f 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-24 +date: 2023-07-25 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 71a56ad44186b..07d5c06940fd2 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-07-24 +date: 2023-07-25 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 8628b9249bc34..db1190923d0da 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-24 +date: 2023-07-25 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 c1afc18c019ca..451a5f2bf7f42 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-24 +date: 2023-07-25 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 fa517d8e70218..eda86e138f443 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 845f99b4dfe37..9e597377db20f 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 9eaf7fa671103..fc9f071bd9298 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 5206d20c74999..d799dbf789b5f 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 062cd1b77120e..326b20ed158f9 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-07-24 +date: 2023-07-25 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 108d73572c086..eceeed07bbfcb 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-07-24 +date: 2023-07-25 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 2f91a2397144a..2f12fcfc1e642 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-07-24 +date: 2023-07-25 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 fa4c1af425971..2b3b132b2ffa4 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 5648433675c5e..c4ed7d84d64cb 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-07-24 +date: 2023-07-25 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 8ad5da9a30f14..5e22f25f73a6f 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-07-24 +date: 2023-07-25 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 e84823d3b4f9f..631fa41b83d00 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-07-24 +date: 2023-07-25 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 d41f3a1646b59..3f2ea0c467eba 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 322e16ad9aa22..630f9ae5ba45d 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-07-24 +date: 2023-07-25 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 d14aa96f3afd9..8cebc141fcfe6 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-07-24 +date: 2023-07-25 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 3b2525a9ad369..2376b3f9833cc 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-07-24 +date: 2023-07-25 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 0e74307b287b1..6adc75c259b69 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-07-24 +date: 2023-07-25 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 711232cfe5fb9..c081c1bbced55 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 8ef7302f94240..3119fabc5f376 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 1e96537369f4f..d5edbd94b2c2d 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-24 +date: 2023-07-25 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 d597eab6040d8..2f9c46a12ce4b 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-07-24 +date: 2023-07-25 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 bc74060ed5772..e4a8b366fd822 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 788080974bd51..03b2a7c0d59da 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index cc08902fb5188..67eda864aecef 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 368c6bc4c4e17..812e5819dbf02 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 18c5537e517cb..456ee4d75797e 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-07-24 +date: 2023-07-25 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 be055d3421f94..142fcef93a7cb 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-07-24 +date: 2023-07-25 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 e37546fd380ac..2047124ddc76e 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 d67e37722eefa..8b9a47457e0b1 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 1085838afc408..a06b76a37e11f 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-07-24 +date: 2023-07-25 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 6a588b79f9757..cecb6cc1e3823 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-07-24 +date: 2023-07-25 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 147dc8c0f2a59..1c8f445dfa98a 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 fe87156b5c668..f41972b2e8740 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 844b5f816f9d1..c93fbc0edd3d6 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-07-24 +date: 2023-07-25 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 dec2bf4ad963e..280fc2e531e3e 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-24 +date: 2023-07-25 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 8898a25ac0bcf..b203ed4e1244f 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-07-24 +date: 2023-07-25 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 98f0aa3db8f4d..3c9bac9a68248 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-07-24 +date: 2023-07-25 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 9f27424fe732c..0c2bb1703a4d2 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-07-24 +date: 2023-07-25 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 d030876c628bf..cfeeca687deef 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 aa55ccbb1748d..df1e89d8b8c7b 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-07-24 +date: 2023-07-25 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 32c47e205cad3..ebc71a327ec40 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 4000cf70ef354..fa8261051cd9a 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-07-24 +date: 2023-07-25 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 02b900ed46c8f..aee085c84fdd6 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 23bb27798320a..f02671b9269d8 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-07-24 +date: 2023-07-25 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 63b8babc853b5..77854ae4b9b3d 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 b2662c15b8971..094f9b582de05 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-07-24 +date: 2023-07-25 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 1dc02e10800b9..6aa158c5b6a54 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 42e61d8181d68..82c1f6a35c393 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-07-24 +date: 2023-07-25 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 8c56651fbebb1..90f871b5755ba 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-07-24 +date: 2023-07-25 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 7f7bd24ba0c25..4457d0a4d179e 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 de515f8c7f8ad..61e81f47ad0be 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 5fb82f50bdb08..fe7fa0727fca8 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-07-24 +date: 2023-07-25 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 4f9980a966eaa..c993e6381ab25 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-07-24 +date: 2023-07-25 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 c475f49c8e299..1e1e1e685cd3e 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 aefc79053ce57..0c13e41ba0bf5 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-07-24 +date: 2023-07-25 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 51ca5027e580f..9e8c59914f535 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-07-24 +date: 2023-07-25 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 3704d558f29ba..c160a35aec585 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-07-24 +date: 2023-07-25 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 29c200e6c7b10..4f9c85545b9ba 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-07-24 +date: 2023-07-25 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 2d20766bc69c0..612558fb61743 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index b7b0adca99294..8dcf122a7d633 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-07-24 +date: 2023-07-25 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 5cd13609582bb..3c15a08af87d2 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-07-24 +date: 2023-07-25 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 4d5d4e3923720..d1fd0830a12f5 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 8b477009cdb95..4dfdaf49b4dc4 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-07-24 +date: 2023-07-25 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 1d2b050251a5b..4ba102596dbe9 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-07-24 +date: 2023-07-25 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 204e28eee4555..42fa2371f4e51 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-07-24 +date: 2023-07-25 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 bef09fb754efb..fc4b614ef54ec 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-07-24 +date: 2023-07-25 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 60315edc317c3..36d5c0a90442d 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index b82b7d5c7b4d7..575b628869013 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-07-24 +date: 2023-07-25 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 717ee86e55c7e..cb2f6ebbdf1b2 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-07-24 +date: 2023-07-25 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 a7c169ff83d11..3d675643fdaf0 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 4930f203b4d31..5123769327962 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index be7858f7141b0..39edf10ab8107 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-07-24 +date: 2023-07-25 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 a8cd1d2b12ee8..59075e448c06a 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-07-24 +date: 2023-07-25 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 05c0c903a94cf..1d773e8d1edc2 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-24 +date: 2023-07-25 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 1b3e7230e7a47..e24befea2df1a 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-07-24 +date: 2023-07-25 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 ca7bf03727b1d..bc94d89b1efa3 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 6c35510c6fcbe..6604cd812cd12 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index acc55a2c58ef2..39f2cfa259539 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index e4655b902d7c4..46de6d9ffeb86 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-07-24 +date: 2023-07-25 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 e5cc721c591cd..92c5de9de30c0 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-07-24 +date: 2023-07-25 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 623c696c32523..7ac642761b208 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-07-24 +date: 2023-07-25 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 d455351d12fbd..0997949b707e3 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-07-24 +date: 2023-07-25 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 2bd8d140a4b69..e2e37c0b21a84 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: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 8d84d15c0c9e5..e17f416fbedea 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index cb864282cc482..215212639177b 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-07-24 +date: 2023-07-25 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 da6598826e036..da1fafbd3e4bb 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-07-24 +date: 2023-07-25 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 3d5f466074404..df5e2daa1f4a2 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-07-24 +date: 2023-07-25 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 62accaa41e2d3..a69c1085f643e 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 37d08523a04f1..bd702fd9bc1d7 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-07-24 +date: 2023-07-25 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 6e73c1caea6a2..44ace296ea335 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-07-24 +date: 2023-07-25 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 c2e3dcfdc3a0b..293f264fe09c3 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-07-24 +date: 2023-07-25 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 63400fb38d552..753533566c382 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 77f47a39755ba..6f269f9cb6fe8 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index dcd379357d65f..88a33810a955e 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: 2023-07-24 +date: 2023-07-25 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 4da020544e63c..e1f6c924637d0 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 42a5da260f7d0..ba3d8c90182d9 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-07-24 +date: 2023-07-25 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 b11c3748f9462..e6bbb14d0e356 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index fa19420f6451e..365cc1b00e0fb 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 935a87328d287..3473d0afa2ba7 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-07-24 +date: 2023-07-25 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 cbd80bf72635b..28a5aef69fb73 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-07-24 +date: 2023-07-25 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 589829b4862ff..e6037075f87e6 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-07-24 +date: 2023-07-25 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 3e382d21354d0..30cd99faa9284 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 014a586b294ce..8e05854a0c5f4 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 09393b66217b2..68ccd5d5fe025 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -12545,7 +12545,7 @@ "label": "value", "description": [], "signature": [ - "false" + "true" ], "path": "x-pack/plugins/observability/server/ui_settings.ts", "deprecated": false, diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 6d70def76e096..19984f812269d 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 7bd14321e9e98..dea3d730f616b 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-24 +date: 2023-07-25 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 8e0ddc97770ec..e25df5eeadfba 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-24 +date: 2023-07-25 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 0c0b447657dae..6539dc2c66994 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 13e73af3a2016..3ad1ec4aa0172 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 71603 | 555 | 61304 | 1462 | +| 71609 | 555 | 61310 | 1463 | ## Plugin Directory @@ -30,7 +30,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 275 | 10 | 269 | 27 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 36 | 1 | 32 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 44 | 0 | 27 | 1 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 795 | 1 | 765 | 48 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 784 | 1 | 754 | 47 | | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 48 | 0 | 48 | 113 | | | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | Asset manager plugin for entity assets (inventory, topology, etc) | 3 | 0 | 3 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 9 | 0 | 9 | 0 | @@ -63,7 +63,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1009 | 0 | 243 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 12 | 0 | 10 | 3 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 97 | 0 | 71 | 14 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 105 | 0 | 79 | 14 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | discoverLogExplorer | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | This plugin exposes and registers Logs+ features. | 0 | 0 | 0 | 0 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | @@ -90,11 +90,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 175 | 0 | 165 | 13 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Adds expression runtime to Kibana | 2205 | 74 | 1746 | 5 | | | [@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 | 288 | 26 | 249 | 3 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Index pattern fields and ambiguous values formatters | 292 | 26 | 253 | 3 | | | [@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. | 62 | 0 | 62 | 2 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 239 | 0 | 24 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Simple UI for managing files in Kibana | 2 | 1 | 2 | 0 | -| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1182 | 3 | 1066 | 40 | +| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1183 | 3 | 1067 | 40 | | 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) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 0 | 0 | 0 | 0 | @@ -140,7 +140,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 218 | 8 | 164 | 11 | | | [@elastic/profiling-ui](https://github.com/orgs/elastic/teams/profiling-ui) | - | 19 | 2 | 19 | 3 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 38 | 0 | 18 | 3 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 42 | 0 | 22 | 5 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Currently PDF, PNG or CSV export types for the reporting plugin | 4 | 0 | 4 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 21 | 0 | 21 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 266 | 0 | 237 | 14 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index c1582106748f0..d7487e26c3ef3 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-07-24 +date: 2023-07-25 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 114469c3f7a09..39ebcf98f5189 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 03932a0cfa431..5058ca53474ef 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-07-24 +date: 2023-07-25 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 dc999b0fd3f02..186cf1f65edae 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 38 | 0 | 18 | 3 | +| 42 | 0 | 22 | 5 | ## Client diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index f9657b69a490c..40cd784270a8a 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 00638cf519637..c43e648694e12 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-07-24 +date: 2023-07-25 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 491d7df29127f..561b036bd533f 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-07-24 +date: 2023-07-25 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 98716dc4eeda7..9e82bedd4b1b8 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-07-24 +date: 2023-07-25 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 ce889dfd15a7e..7a79df35cfb41 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-07-24 +date: 2023-07-25 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 3a1c48f52f499..3905714212cf7 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.devdocs.json b/api_docs/saved_objects_management.devdocs.json index e1a1f39f71718..44279045cfc47 100644 --- a/api_docs/saved_objects_management.devdocs.json +++ b/api_docs/saved_objects_management.devdocs.json @@ -298,9 +298,7 @@ "Interpolation", "<", "Theme", - ">; abbr?: string | undefined; footer?: string | React.ReactElement> | ((props: ", - "EuiTableFooterProps", - "<", + ">; field: (string & {}) | keyof ", { "pluginId": "savedObjectsManagement", "scope": "public", @@ -308,7 +306,9 @@ "section": "def-public.SavedObjectsManagementRecord", "text": "SavedObjectsManagementRecord" }, - ">) => React.ReactNode) | undefined; field: (string & {}) | keyof ", + "; abbr?: string | undefined; footer?: string | React.ReactElement> | ((props: ", + "EuiTableFooterProps", + "<", { "pluginId": "savedObjectsManagement", "scope": "public", @@ -316,7 +316,7 @@ "section": "def-public.SavedObjectsManagementRecord", "text": "SavedObjectsManagementRecord" }, - "; width?: string | undefined; headers?: string | undefined; height?: string | number | undefined; readOnly?: boolean | undefined; dataType?: ", + ">) => React.ReactNode) | undefined; width?: string | undefined; headers?: string | undefined; height?: string | number | undefined; readOnly?: boolean | undefined; dataType?: ", "EuiTableDataType", " | undefined; render?: ((value: any, record: ", { diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index f749001f888fa..2236cf4edc9bb 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-07-24 +date: 2023-07-25 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 62e4df6d2d9f7..594e2cd375994 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-07-24 +date: 2023-07-25 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 8e700f8fa36b8..38d4d20d8e711 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-07-24 +date: 2023-07-25 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 f5e8b8d17e3ba..62543715c4942 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-07-24 +date: 2023-07-25 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 6123c29017cf5..c2b507833d8cb 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-07-24 +date: 2023-07-25 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 1dda98e525030..adc58346c0d24 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index d6b61f6cc79a9..464640a25f6bc 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index c9a7ac2fef781..85c5cab596135 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-07-24 +date: 2023-07-25 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 c39c09e736d3c..1a8a6e5a552f5 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: 2023-07-24 +date: 2023-07-25 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 b4c6f48e87652..b3fd92cbf519a 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: 2023-07-24 +date: 2023-07-25 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 871e51d766211..a5e3a97f49a99 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-24 +date: 2023-07-25 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 f43b43ed995d7..b0a63e4a8bd37 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-24 +date: 2023-07-25 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 c8934f3c83ef0..93954a49230cf 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-24 +date: 2023-07-25 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 9b5ef8b7f64a1..accb598d9da62 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-07-24 +date: 2023-07-25 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 46bc7a7c9d58b..ab1bdfa33da94 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 124ae47a1a120..74a2c4e199aaf 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-07-24 +date: 2023-07-25 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 d9e873ba9b8cc..bba2c2f667b68 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-07-24 +date: 2023-07-25 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 a35981ac30f75..2805925b996fc 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-07-24 +date: 2023-07-25 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 2e5e6b05314f3..5aa3c839e35e1 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-07-24 +date: 2023-07-25 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 ddaa0de4d4785..67a51883d95ee 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-07-24 +date: 2023-07-25 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 5dc14d03266e5..ac42be59aaa79 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-07-24 +date: 2023-07-25 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 7e6d3244a3c6d..bc53bfc853546 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-07-24 +date: 2023-07-25 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 1967e48e0d35f..335cd4bfb06f9 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-07-24 +date: 2023-07-25 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 6cc30c6dceec1..abe8ddb1f33f7 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-07-24 +date: 2023-07-25 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 fc979b78d4ed3..501d3beb4db87 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-24 +date: 2023-07-25 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 bcb463932cc81..0f014215df2a0 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-07-24 +date: 2023-07-25 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 b915dd667c37d..a7d69e47be024 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-07-24 +date: 2023-07-25 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 b58f892e2ec8a..619a2d3285f26 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-07-24 +date: 2023-07-25 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 ccfc51a8dbf06..0c2c5cc3a3db7 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-07-24 +date: 2023-07-25 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 079af58f8da48..6b9a3a9567cc3 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-07-24 +date: 2023-07-25 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 17c83c55907f8..48c8b6265b8b6 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index ef0673dbcd20f..0cad6de177c52 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-07-24 +date: 2023-07-25 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 db680b850215e..9c42d4c6eb9b6 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-07-24 +date: 2023-07-25 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 e96c63cc88fe9..78ea5e1ad11ec 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 5de3964976395..9e3b41f51c897 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-07-24 +date: 2023-07-25 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 8885eebcea481..18749c1c1c0f6 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-07-24 +date: 2023-07-25 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 e9c715cf33ee3..7b1ec547c57b2 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-07-24 +date: 2023-07-25 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 8fe3367060064..4a7996e9a52ea 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-07-24 +date: 2023-07-25 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 163fbb637a01c..77578960aa910 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-07-24 +date: 2023-07-25 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 32e853193b01d..1fbdf47c1c739 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-07-24 +date: 2023-07-25 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 045b070a466d9..3642a985532d2 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-07-24 +date: 2023-07-25 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 63a9238b25336..40d9ff4a68637 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-07-24 +date: 2023-07-25 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 1fb4112154caa..dd3b54b9461cd 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-07-24 +date: 2023-07-25 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 5a6c6d4c0ecb4..7037e0c9d6771 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-07-24 +date: 2023-07-25 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 cefad2d823224..fdbd9f01ca9b0 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-07-24 +date: 2023-07-25 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 fea43ea730237..bbb2f9ca74435 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-07-24 +date: 2023-07-25 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 6ccfd5f614314..aa2dcf3a23dd5 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-07-24 +date: 2023-07-25 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 82860f6c86936..a669c0296354b 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-24 +date: 2023-07-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/config/serverless.security.yml b/config/serverless.security.yml index bad71f38f24af..ede91b167dd05 100644 --- a/config/serverless.security.yml +++ b/config/serverless.security.yml @@ -22,3 +22,8 @@ xpack.serverless.plugin.developer.projectSwitcher.currentType: 'security' # Specify in telemetry the project type telemetry.labels.serverless: security + +# Serverless security specific options +xpack.securitySolution.enableExperimental: + - discoverInTimeline + diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 584f38cf92738..4fb85157bfaa4 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -647,7 +647,6 @@ For the second scenario, refreshing the case fixes the issue. Breaking changes can prevent your application from optimal operation and performance. Before you upgrade to 8.8.0, review the breaking changes, then mitigate the impact to your application. -// tag::notable-breaking-changes[] [discrete] [[breaking-155470]] .Removes legacy project monitor API @@ -671,7 +670,6 @@ The privileges for attaching alerts to cases has changed. For more information, *Impact* + To attach alerts to cases, you must have `Read` access to an {observability} or Security feature that has alerts and `All` access to the **Cases** feature. For detailed information, check link:https://www.elastic.co/guide/en/kibana/current/kibana-privileges.html[{kib} privileges] and link:https://www.elastic.co/guide/en/kibana/current/setup-cases.html[Configure access to cases]. ==== -// end::notable-breaking-changes[] To review the breaking changes in previous versions, refer to the following: diff --git a/docs/maps/index.asciidoc b/docs/maps/index.asciidoc index e6446a2a30075..f924e60cce9e6 100644 --- a/docs/maps/index.asciidoc +++ b/docs/maps/index.asciidoc @@ -13,22 +13,6 @@ Create beautiful maps from your geographical data. With **Maps**, you can: * Symbolize features using data values. * Focus on only the data that’s important to you. -*Ready to get started?* Watch the https://videos.elastic.co/watch/BYzRDtH4u7RSD8wKhuEW1b[video], and then start your tour of **Maps** with the <>. - -++++ - - -
-++++ - [float] === Build maps with multiple layers and indices Use multiple layers and indices to show all your data in a single map. Show how data sits relative to physical features like weather patterns, human-made features like international borders, and business-specific features like sales regions. Plot individual documents or use aggregations to plot any data set, no matter how large. diff --git a/docs/user/dashboard/make-dashboards-interactive.asciidoc b/docs/user/dashboard/make-dashboards-interactive.asciidoc index 1ebcc2ca2402f..aee1d37507f19 100644 --- a/docs/user/dashboard/make-dashboards-interactive.asciidoc +++ b/docs/user/dashboard/make-dashboards-interactive.asciidoc @@ -9,6 +9,9 @@ Add interactive capabilities to your dashboard, such as interactive filter controls, and drilldowns that allow you to navigate to *Discover*, other dashboards, and external websites. +// Video is slightly outdated. Left in at request of dev team. +// See https://github.com/elastic/kibana/pull/161090#issuecomment-1620410065 + ++++ diff --git a/package.json b/package.json index e5295bc888c3b..819c6b28a6fdd 100644 --- a/package.json +++ b/package.json @@ -1423,7 +1423,6 @@ "eslint-plugin-mocha": "^10.0.5", "eslint-plugin-no-unsanitized": "^3.1.5", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prefer-object-spread": "^1.2.1", "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.26.1", "eslint-plugin-react-hooks": "^4.2.0", diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/find.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/find.ts index 4fa0068313b51..3346e6552646a 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/find.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/find.ts @@ -239,11 +239,13 @@ export const performFind = async ( total: body.hits.total, saved_objects: body.hits.hits.map( (hit: estypes.SearchHit): SavedObjectsFindResult => { - const savedObject = migrationHelper.migrateStorageDocument( - serializerHelper.rawToSavedObject(hit as SavedObjectsRawDoc, { - migrationVersionCompatibility, - }) - ) as SavedObject; + let savedObject = serializerHelper.rawToSavedObject(hit as SavedObjectsRawDoc, { + migrationVersionCompatibility, + }); + // can't migrate a document with partial attributes + if (!fields) { + savedObject = migrationHelper.migrateStorageDocument(savedObject) as SavedObject; + } return { ...savedObject, score: hit._score!, diff --git a/packages/core/saved-objects/core-saved-objects-api-server/src/apis/find.ts b/packages/core/saved-objects/core-saved-objects-api-server/src/apis/find.ts index af8a265673f4d..e0e035abea34b 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server/src/apis/find.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server/src/apis/find.ts @@ -56,9 +56,25 @@ export interface SavedObjectsFindOptions { /** sort order, ascending or descending */ sortOrder?: SortOrder; /** - * An array of fields to include in the results + * An array of attributes to fetch and include in the results. If unspecified, all attributes will be fetched. + * + * The main purpose of this option is to avoid fetching unnecessary heavy fields (e.g blobs) when searching for + * savedObjects, for performance purposes. + * + * Defaults to `undefined` (fetching all fields). + * * @example - * SavedObjects.find({type: 'dashboard', fields: ['attributes.name', 'attributes.location']}) + * ```ts + * SavedObjects.find({type: 'dashboard', fields: ['name', 'description']}) + * ``` + * + * @remarks When this option is specified, the savedObjects returned from the API will not + * go through the migration process (as we can't migrate partial documents). + * For this reason, all fields provided to this option should already be present + * in the prior model version of the document's SO type. + * Otherwise, it may lead to inconsistencies during hybrid version cohabitation + * (e.g during an upgrade in serverless) where newly introduced / backfilled fields + * may not necessarily appear in the documents returned from the API when the option is used. */ fields?: string[]; /** Search documents using the Elasticsearch Simple Query String syntax. See Elasticsearch Simple Query String `query` argument for more information */ diff --git a/packages/core/saved-objects/core-saved-objects-server/docs/model_versions.md b/packages/core/saved-objects/core-saved-objects-server/docs/model_versions.md index ca70bfcbd0c78..ba04303fbd0c8 100644 --- a/packages/core/saved-objects/core-saved-objects-server/docs/model_versions.md +++ b/packages/core/saved-objects/core-saved-objects-server/docs/model_versions.md @@ -13,6 +13,8 @@ - [Adding an indexed field without default value](#adding-an-indexed-field-without-default-value) - [Adding an indexed field with a default value](#adding-an-indexed-field-with-a-default-value) - [Removing an existing field](#removing-an-existing-field) +- [Particularities of the serverless environment](#particularities-of-the-serverless-environment) + - [Using the fields option of the find api](#using-the-fields-option-of-the-find-savedobjects-api) ## Introduction @@ -866,4 +868,26 @@ const myType: SavedObjectsType = { }, }, }; -``` \ No newline at end of file +``` + +## Particularities of the serverless environment + +The serverless environment, and the fact that upgrade in such environments are performed in a way +where, at some point, the old and new version of the application are living in cohabitation, leads +to some particularities regarding the way the SO APIs works, and to some limitations / edge case +that we need to document + +### Using the `fields` option of the `find` savedObjects API + +By default, the `find` API (as any other SO API returning documents) will migrate all documents before +returning them, to ensure that documents can be used by both versions during a cohabitation (e.g an old +node searching for documents already migrated, or a new node searching for documents not yet migrated). + +However, when using the `fields` option of the `find` API, the documents can't be migrated, as some +model version changes can't be applied against a partial set of attributes. For this reason, when the +`fields` option is provided, the documents returned from `find` will **not** be migrated. + +Which is why, when using this option, the API consumer needs to make sure that *all* the fields passed +to the `fields` option **were already present in the prior model version**. Otherwise, it may lead to inconsistencies +during upgrades, where newly introduced or backfilled fields may not necessarily appear in the documents returned +from the `search` API when the option is used. diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client.test.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client.test.ts index 2612c8778898b..b00517d259a48 100644 --- a/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client.test.ts +++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client.test.ts @@ -64,7 +64,12 @@ describe('ui settings', () => { await uiSettings.setMany({ one: 'value' }); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.update).toHaveBeenCalledWith(TYPE, ID, { one: 'value' }); + expect(savedObjectsClient.update).toHaveBeenCalledWith( + TYPE, + ID, + { one: 'value' }, + { refresh: false } + ); }); it('updates several values in one operation', async () => { @@ -72,10 +77,15 @@ describe('ui settings', () => { await uiSettings.setMany({ one: 'value', another: 'val' }); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.update).toHaveBeenCalledWith(TYPE, ID, { - one: 'value', - another: 'val', - }); + expect(savedObjectsClient.update).toHaveBeenCalledWith( + TYPE, + ID, + { + one: 'value', + another: 'val', + }, + { refresh: false } + ); }); it('automatically creates the savedConfig if it is missing', async () => { @@ -159,9 +169,14 @@ describe('ui settings', () => { await uiSettings.set('one', 'value'); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.update).toHaveBeenCalledWith(TYPE, ID, { - one: 'value', - }); + expect(savedObjectsClient.update).toHaveBeenCalledWith( + TYPE, + ID, + { + one: 'value', + }, + { refresh: false } + ); }); it('validates value if a schema presents', async () => { @@ -202,7 +217,12 @@ describe('ui settings', () => { await uiSettings.remove('one'); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.update).toHaveBeenCalledWith(TYPE, ID, { one: null }); + expect(savedObjectsClient.update).toHaveBeenCalledWith( + TYPE, + ID, + { one: null }, + { refresh: false } + ); }); it('does not fail validation', async () => { @@ -246,7 +266,12 @@ describe('ui settings', () => { await uiSettings.removeMany(['one']); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.update).toHaveBeenCalledWith(TYPE, ID, { one: null }); + expect(savedObjectsClient.update).toHaveBeenCalledWith( + TYPE, + ID, + { one: null }, + { refresh: false } + ); }); it('updates several values in one operation', async () => { @@ -254,11 +279,16 @@ describe('ui settings', () => { await uiSettings.removeMany(['one', 'two', 'three']); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.update).toHaveBeenCalledWith(TYPE, ID, { - one: null, - two: null, - three: null, - }); + expect(savedObjectsClient.update).toHaveBeenCalledWith( + TYPE, + ID, + { + one: null, + two: null, + three: null, + }, + { refresh: false } + ); }); it('does not fail validation', async () => { diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client_common.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client_common.ts index 992a851db99fd..d52644a0e8bfe 100644 --- a/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client_common.ts +++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_client_common.ts @@ -129,7 +129,7 @@ export abstract class UiSettingsClientCommon extends BaseUiSettingsClient { autoCreateOrUpgradeIfMissing?: boolean; }) { try { - await this.savedObjectsClient.update(this.type, this.id, changes); + await this.savedObjectsClient.update(this.type, this.id, changes, { refresh: false }); } catch (error) { if (!SavedObjectsErrorHelpers.isNotFoundError(error) || !autoCreateOrUpgradeIfMissing) { throw error; diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_global_client.test.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_global_client.test.ts index 2e4988f20c9df..56c3d53e2109f 100644 --- a/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_global_client.test.ts +++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/clients/ui_settings_global_client.test.ts @@ -86,9 +86,14 @@ describe('ui settings global client', () => { const { uiSettingsClient, savedObjectsClient } = setup(); await uiSettingsClient.set('settingA', 'cde'); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.update).toHaveBeenCalledWith(TYPE, ID, { - settingA: 'cde', - }); + expect(savedObjectsClient.update).toHaveBeenCalledWith( + TYPE, + ID, + { + settingA: 'cde', + }, + { refresh: false } + ); }); }); diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts index 63a80e673a487..9f74929aaf2cc 100644 --- a/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts +++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts @@ -79,6 +79,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () { }, { id: version, + refresh: false, } ); }); @@ -110,6 +111,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () { }, { id: version, + refresh: false, } ); }); @@ -140,7 +142,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () { defaultIndex: 'another-index', isDefaultIndexMigrated: true, }, - { id: version } + { id: version, refresh: false } ); }); @@ -282,6 +284,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () { }, { id: version, + refresh: false, } ); }); @@ -313,6 +316,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () { }, { id: version, + refresh: false, } ); }); diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts index d6e0fffa05868..53ec0b78d3f89 100644 --- a/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts +++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts @@ -63,7 +63,7 @@ export async function createOrUpgradeSavedConfig( try { // create the new SavedConfig - await savedObjectsClient.create(type, attributes, { id: version }); + await savedObjectsClient.create(type, attributes, { id: version, refresh: false }); } catch (error) { if (handleWriteErrors) { if (SavedObjectsErrorHelpers.isConflictError(error)) { diff --git a/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts b/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts index 2f02b51be5501..2c23eec3ca2aa 100644 --- a/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts +++ b/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts @@ -26,6 +26,7 @@ export async function emptyKibanaIndexAction({ await cleanSavedObjectIndices({ client, stats, log }); await migrateSavedObjectIndices(kbnClient); + await client.indices.refresh({ index: ALL_SAVED_OBJECT_INDICES }); ALL_SAVED_OBJECT_INDICES.forEach((indexPattern) => stats.createdIndex(indexPattern)); return stats.toJSON(); } diff --git a/packages/kbn-eslint-config/javascript.js b/packages/kbn-eslint-config/javascript.js index d048d9a93bdda..31f918546c126 100644 --- a/packages/kbn-eslint-config/javascript.js +++ b/packages/kbn-eslint-config/javascript.js @@ -15,7 +15,6 @@ module.exports = { '@babel', 'import', 'no-unsanitized', - 'prefer-object-spread', ], env: { @@ -94,7 +93,7 @@ module.exports = { 'import/no-duplicates': 'error', 'import/no-dynamic-require': 'error', - 'prefer-object-spread/prefer-object-spread': 'error', + 'prefer-object-spread': 'error', } }, ] diff --git a/packages/kbn-eslint-config/typescript.js b/packages/kbn-eslint-config/typescript.js index 04e847224df58..d62314c97d547 100644 --- a/packages/kbn-eslint-config/typescript.js +++ b/packages/kbn-eslint-config/typescript.js @@ -20,7 +20,6 @@ module.exports = { '@typescript-eslint', 'ban', 'import', - 'prefer-object-spread', 'eslint-comments' ], diff --git a/packages/kbn-eslint-plugin-disable/src/helpers/regex.ts b/packages/kbn-eslint-plugin-disable/src/helpers/regex.ts index b2627654c1b65..4cf9f776ff45b 100644 --- a/packages/kbn-eslint-plugin-disable/src/helpers/regex.ts +++ b/packages/kbn-eslint-plugin-disable/src/helpers/regex.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type Eslint from 'eslint'; +import type { AST } from 'eslint'; const ESLINT_DISABLE_RE = /^eslint-disable(?:-next-line|-line)?(?.*)/; @@ -17,16 +17,16 @@ export enum ESLINT_DISABLE_VALUE { } export interface ParsedEslintDisableComment { - type: Eslint.AST.Program['comments'][0]['type']; - range: Eslint.AST.Program['comments'][0]['range']; - loc: Eslint.AST.Program['comments'][0]['loc']; - value: Eslint.AST.Program['comments'][0]['value']; + type: AST.Program['comments'][0]['type']; + range: AST.Program['comments'][0]['range']; + loc: AST.Program['comments'][0]['loc']; + value: AST.Program['comments'][0]['value']; disableValueType: ESLINT_DISABLE_VALUE; rules: string[]; } export function parseEslintDisableComment( - comment: Eslint.AST.Program['comments'][0] + comment: AST.Program['comments'][0] ): ParsedEslintDisableComment | undefined { const commentVal = comment.value.trim(); const nakedESLintRegexResult = commentVal.match(ESLINT_DISABLE_RE); diff --git a/packages/kbn-eslint-plugin-disable/src/helpers/report.ts b/packages/kbn-eslint-plugin-disable/src/helpers/report.ts index a497cefb9d148..03d196dc53186 100644 --- a/packages/kbn-eslint-plugin-disable/src/helpers/report.ts +++ b/packages/kbn-eslint-plugin-disable/src/helpers/report.ts @@ -6,12 +6,12 @@ * Side Public License, v 1. */ -import type Eslint from 'eslint'; +import type { AST } from 'eslint'; import { ESLINT_DISABLE_VALUE, ParsedEslintDisableComment } from './regex'; export function getReportLocFromComment( comment: ParsedEslintDisableComment -): Eslint.AST.SourceLocation | undefined { +): AST.SourceLocation | undefined { const cStart = comment?.loc?.start; const cEnd = comment?.loc?.end; const cStartLine = comment?.loc?.start?.line; diff --git a/packages/kbn-eslint-plugin-disable/src/rules/no_naked_eslint_disable.ts b/packages/kbn-eslint-plugin-disable/src/rules/no_naked_eslint_disable.ts index 45660dbf20a6d..84ca09088b7e4 100644 --- a/packages/kbn-eslint-plugin-disable/src/rules/no_naked_eslint_disable.ts +++ b/packages/kbn-eslint-plugin-disable/src/rules/no_naked_eslint_disable.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import Eslint from 'eslint'; +import type { Rule, AST } from 'eslint'; import { getReportLocFromComment, parseEslintDisableComment } from '../helpers'; export const NAKED_DISABLE_MSG_ID = 'no-naked-eslint-disable'; @@ -15,7 +15,7 @@ const messages = { 'Using a naked eslint disable is not allowed. Please specify the specific rules to disable.', }; -const meta: Eslint.Rule.RuleMetaData = { +const meta: Rule.RuleMetaData = { type: 'problem', fixable: 'code', docs: { @@ -25,7 +25,7 @@ const meta: Eslint.Rule.RuleMetaData = { messages, }; -const create = (context: Eslint.Rule.RuleContext): Eslint.Rule.RuleListener => { +const create = (context: Rule.RuleContext): Rule.RuleListener => { return { Program(node) { const nodeComments = node.comments || []; @@ -56,7 +56,7 @@ const create = (context: Eslint.Rule.RuleContext): Eslint.Rule.RuleListener => { loc: reportLoc, messageId: NAKED_DISABLE_MSG_ID, fix(fixer) { - return fixer.removeRange(parsedEslintDisable.range as Eslint.AST.Range); + return fixer.removeRange(parsedEslintDisable.range as AST.Range); }, }); }); @@ -64,7 +64,7 @@ const create = (context: Eslint.Rule.RuleContext): Eslint.Rule.RuleListener => { }; }; -export const NoNakedESLintDisableRule: Eslint.Rule.RuleModule = { +export const NoNakedESLintDisableRule: Rule.RuleModule = { meta, create, }; diff --git a/packages/kbn-eslint-plugin-disable/src/rules/no_protected_eslint_disable.ts b/packages/kbn-eslint-plugin-disable/src/rules/no_protected_eslint_disable.ts index bffcd5c2febc0..93e86f2423d8a 100644 --- a/packages/kbn-eslint-plugin-disable/src/rules/no_protected_eslint_disable.ts +++ b/packages/kbn-eslint-plugin-disable/src/rules/no_protected_eslint_disable.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import Eslint from 'eslint'; +import type { Rule, AST } from 'eslint'; import { PROTECTED_RULES, getReportLocFromComment, parseEslintDisableComment } from '../helpers'; export const PROTECTED_DISABLE_MSG_ID = 'no-protected-eslint-disable'; @@ -15,7 +15,7 @@ const messages = { "The rule '{{ disabledRuleName }}' is protected and disabling it is not allowed. Please remove it from the statement.", }; -const meta: Eslint.Rule.RuleMetaData = { +const meta: Rule.RuleMetaData = { type: 'problem', fixable: 'code', docs: { @@ -24,7 +24,7 @@ const meta: Eslint.Rule.RuleMetaData = { messages, }; -const create = (context: Eslint.Rule.RuleContext): Eslint.Rule.RuleListener => { +const create = (context: Rule.RuleContext): Rule.RuleListener => { return { Program(node) { const nodeComments = node.comments || []; @@ -68,7 +68,7 @@ const create = (context: Eslint.Rule.RuleContext): Eslint.Rule.RuleListener => { fix(fixer) { // if we only have a single disabled rule and that is protected, we can remove the entire comment if (disabledRules.length === 1) { - return fixer.removeRange(parsedEslintDisable.range as Eslint.AST.Range); + return fixer.removeRange(parsedEslintDisable.range as AST.Range); } // it's impossible to fix as we don't have a range @@ -80,7 +80,7 @@ const create = (context: Eslint.Rule.RuleContext): Eslint.Rule.RuleListener => { const fixedComment = ` ${parsedEslintDisable.disableValueType} ${remainingRules.join( ', ' )}${parsedEslintDisable.type === 'Block' ? ' ' : ''}`; - const rangeToFix: Eslint.AST.Range = + const rangeToFix: AST.Range = parsedEslintDisable.type === 'Line' ? [parsedEslintDisable.range[0] + 2, parsedEslintDisable.range[1]] : [parsedEslintDisable.range[0] + 2, parsedEslintDisable.range[1] - 2]; @@ -93,7 +93,7 @@ const create = (context: Eslint.Rule.RuleContext): Eslint.Rule.RuleListener => { }; }; -export const NoProtectedESLintDisableRule: Eslint.Rule.RuleModule = { +export const NoProtectedESLintDisableRule: Rule.RuleModule = { meta, create, }; diff --git a/packages/kbn-eslint-plugin-imports/src/get_import_resolver.ts b/packages/kbn-eslint-plugin-imports/src/get_import_resolver.ts index 8679dd73b0223..6a05298f4ab42 100644 --- a/packages/kbn-eslint-plugin-imports/src/get_import_resolver.ts +++ b/packages/kbn-eslint-plugin-imports/src/get_import_resolver.ts @@ -8,7 +8,7 @@ import { ImportResolver } from '@kbn/import-resolver'; import { REPO_ROOT } from '@kbn/repo-info'; -import { Rule } from 'eslint'; +import type { Rule } from 'eslint'; import { RUNNING_IN_EDITOR } from './helpers/running_in_editor'; let importResolverCache: ImportResolver | undefined; diff --git a/packages/kbn-eslint-plugin-imports/src/helpers/report.ts b/packages/kbn-eslint-plugin-imports/src/helpers/report.ts index bfcd9956018cc..4ac96a208ce06 100644 --- a/packages/kbn-eslint-plugin-imports/src/helpers/report.ts +++ b/packages/kbn-eslint-plugin-imports/src/helpers/report.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import Eslint from 'eslint'; +import type { Rule } from 'eslint'; import { SomeNode } from './visit_all_import_statements'; interface ReportOptions { @@ -18,7 +18,7 @@ interface ReportOptions { /** * Simple wrapper around context.report so that the types work better with typescript-estree */ -export function report(context: Eslint.Rule.RuleContext, options: ReportOptions) { +export function report(context: Rule.RuleContext, options: ReportOptions) { context.report({ node: options.node as any, message: options.message, diff --git a/packages/kbn-eslint-plugin-imports/src/helpers/source.ts b/packages/kbn-eslint-plugin-imports/src/helpers/source.ts index 8bb98832f3118..eba1300b7cbbe 100644 --- a/packages/kbn-eslint-plugin-imports/src/helpers/source.ts +++ b/packages/kbn-eslint-plugin-imports/src/helpers/source.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { Rule } from 'eslint'; +import type { Rule } from 'eslint'; /** * Get the path of the sourcefile being linted diff --git a/packages/kbn-eslint-plugin-imports/src/helpers/visit_all_import_statements.ts b/packages/kbn-eslint-plugin-imports/src/helpers/visit_all_import_statements.ts index 6f549d93ef26e..4e71191cb6efd 100644 --- a/packages/kbn-eslint-plugin-imports/src/helpers/visit_all_import_statements.ts +++ b/packages/kbn-eslint-plugin-imports/src/helpers/visit_all_import_statements.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { Rule } from 'eslint'; +import type { Rule } from 'eslint'; import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import * as T from '@babel/types'; import { ImportType } from '@kbn/import-resolver'; diff --git a/packages/kbn-eslint-plugin-imports/src/rules/exports_moved_packages.ts b/packages/kbn-eslint-plugin-imports/src/rules/exports_moved_packages.ts index eb2bc90f2ba4f..19b4111a8caad 100644 --- a/packages/kbn-eslint-plugin-imports/src/rules/exports_moved_packages.ts +++ b/packages/kbn-eslint-plugin-imports/src/rules/exports_moved_packages.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { Rule, AST } from 'eslint'; +import type { Rule, AST } from 'eslint'; import * as T from '@babel/types'; import { TSESTree } from '@typescript-eslint/typescript-estree'; diff --git a/packages/kbn-eslint-plugin-imports/src/rules/no_boundary_crossing.ts b/packages/kbn-eslint-plugin-imports/src/rules/no_boundary_crossing.ts index db4be34ba0109..2513922e9c9a8 100644 --- a/packages/kbn-eslint-plugin-imports/src/rules/no_boundary_crossing.ts +++ b/packages/kbn-eslint-plugin-imports/src/rules/no_boundary_crossing.ts @@ -10,7 +10,7 @@ import Path from 'path'; import { TSESTree } from '@typescript-eslint/typescript-estree'; import * as Bt from '@babel/types'; -import { Rule } from 'eslint'; +import type { Rule } from 'eslint'; import ESTree from 'estree'; import { ModuleType } from '@kbn/repo-source-classifier'; diff --git a/packages/kbn-eslint-plugin-imports/src/rules/no_unresolvable_imports.ts b/packages/kbn-eslint-plugin-imports/src/rules/no_unresolvable_imports.ts index 9990ec38530e5..1edafe27affb3 100644 --- a/packages/kbn-eslint-plugin-imports/src/rules/no_unresolvable_imports.ts +++ b/packages/kbn-eslint-plugin-imports/src/rules/no_unresolvable_imports.ts @@ -7,7 +7,7 @@ */ import Path from 'path'; -import { Rule } from 'eslint'; +import type { Rule } from 'eslint'; import { report } from '../helpers/report'; import { getSourcePath } from '../helpers/source'; diff --git a/packages/kbn-eslint-plugin-imports/src/rules/no_unused_imports.ts b/packages/kbn-eslint-plugin-imports/src/rules/no_unused_imports.ts index e3c196c5d560e..f12e149af9f66 100644 --- a/packages/kbn-eslint-plugin-imports/src/rules/no_unused_imports.ts +++ b/packages/kbn-eslint-plugin-imports/src/rules/no_unused_imports.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { Rule, Scope, AST } from 'eslint'; +import type { Rule, Scope, AST } from 'eslint'; import type { Comment } from 'estree'; import * as T from '@babel/types'; import { TSESTree } from '@typescript-eslint/typescript-estree'; diff --git a/packages/kbn-eslint-plugin-imports/src/rules/uniform_imports.ts b/packages/kbn-eslint-plugin-imports/src/rules/uniform_imports.ts index 6855a1359f43e..4cf4a5e0f1f33 100644 --- a/packages/kbn-eslint-plugin-imports/src/rules/uniform_imports.ts +++ b/packages/kbn-eslint-plugin-imports/src/rules/uniform_imports.ts @@ -8,7 +8,7 @@ import Path from 'path'; -import Eslint from 'eslint'; +import type { Rule } from 'eslint'; import { getRelativeImportReq, getPackageRelativeImportReq } from '@kbn/import-resolver'; import { report } from '../helpers/report'; @@ -16,7 +16,7 @@ import { visitAllImportStatements } from '../helpers/visit_all_import_statements import { getSourcePath } from '../helpers/source'; import { getImportResolver } from '../get_import_resolver'; -export const UniformImportsRule: Eslint.Rule.RuleModule = { +export const UniformImportsRule: Rule.RuleModule = { meta: { fixable: 'code', docs: { diff --git a/packages/kbn-import-resolver/src/__fixtures__/packages/box/node_modules/bar/index.js b/packages/kbn-import-resolver/src/__fixtures__/packages/box/node_modules/bar/index.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/kbn-import-resolver/src/import_resolver.ts b/packages/kbn-import-resolver/src/import_resolver.ts index 2ad76e9b5a7eb..ee1f168d693a1 100644 --- a/packages/kbn-import-resolver/src/import_resolver.ts +++ b/packages/kbn-import-resolver/src/import_resolver.ts @@ -86,7 +86,7 @@ export class ImportResolver { getPackageIdForPath(path: string) { const relative = Path.relative(this.cwd, path); - if (relative.startsWith('..')) { + if (relative.startsWith('..') || path.includes(NODE_MODULE_SEG)) { return null; } diff --git a/packages/kbn-import-resolver/src/integration_tests/import_resolver.test.ts b/packages/kbn-import-resolver/src/integration_tests/import_resolver.test.ts index e26e37e1495e5..f286848700495 100644 --- a/packages/kbn-import-resolver/src/integration_tests/import_resolver.test.ts +++ b/packages/kbn-import-resolver/src/integration_tests/import_resolver.test.ts @@ -42,6 +42,17 @@ describe('#resolve()', () => { `); }); + it('resolves nested node_module imports', () => { + expect(resolver.resolve('bar', Path.join(FIXTURES_DIR, 'packages', 'box'))) + .toMatchInlineSnapshot(` + Object { + "absolute": /packages/kbn-import-resolver/src/__fixtures__/packages/box/node_modules/bar/index.js, + "nodeModule": "bar", + "type": "file", + } + `); + }); + it('resolves requests to src/', () => { expect(resolver.resolve('src/core/public', FIXTURES_DIR)).toMatchInlineSnapshot(` Object { diff --git a/packages/kbn-tinymath/src/index.js b/packages/kbn-tinymath/src/index.js index 5bc7d80faff9e..be4b42ca93be1 100644 --- a/packages/kbn-tinymath/src/index.js +++ b/packages/kbn-tinymath/src/index.js @@ -35,7 +35,7 @@ function evaluate(expression, scope = {}, injectedFunctions = {}) { } function interpret(node, scope, injectedFunctions) { - const functions = Object.assign({}, includedFunctions, injectedFunctions); // eslint-disable-line prefer-object-spread/prefer-object-spread + const functions = Object.assign({}, includedFunctions, injectedFunctions); // eslint-disable-line prefer-object-spread return exec(node); function exec(node) { diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts index c1cfca07017bc..2a60484107362 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts @@ -106,7 +106,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ingest-agent-policies": "f11cc19275f4c3e4ee7c5cd6423b6706b21b989d", "ingest-download-sources": "d7edc5e588d9afa61c4b831604582891c54ef1c7", "ingest-outputs": "bffa0fd93dfdde904d7f5aff77df72d1c35938d9", - "ingest-package-policies": "7d0e8d288e193e0a8a153bb420c6056bc862c4c3", + "ingest-package-policies": "55816507db0134b8efbe0509e311a91ce7e1c6cc", "ingest_manager_settings": "418311b03c8eda53f5d2ea6f54c1356afaa65511", "inventory-view": "b8683c8e352a286b4aca1ab21003115a4800af83", "kql-telemetry": "93c1d16c1a0dfca9c8842062cf5ef8f62ae401ad", diff --git a/src/core/server/integration_tests/ui_settings/doc_missing.ts b/src/core/server/integration_tests/ui_settings/doc_missing.ts index b31514d4d11c8..4e04b0ecbd149 100644 --- a/src/core/server/integration_tests/ui_settings/doc_missing.ts +++ b/src/core/server/integration_tests/ui_settings/doc_missing.ts @@ -13,6 +13,8 @@ export const docMissingSuite = (savedObjectsIndex: string) => () => { beforeEach(async () => { const { esClient } = getServices(); + await esClient.indices.refresh({ index: savedObjectsIndex }); + // delete all docs from kibana index to ensure savedConfig is not found await esClient.deleteByQuery({ index: savedObjectsIndex, diff --git a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx index ada23ff7f8f55..9f16c7e77bfa4 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.test.tsx @@ -19,6 +19,7 @@ import { DiscoverMainProvider } from '../../services/discover_state_provider'; import type { SearchBarCustomization, TopNavCustomization } from '../../../../customizations'; import type { DiscoverCustomizationId } from '../../../../customizations/customization_service'; +import { useDiscoverCustomization } from '../../../../customizations'; setHeaderActionMenuMounter(jest.fn()); jest.mock('@kbn/kibana-react-plugin/public', () => ({ @@ -28,6 +29,9 @@ jest.mock('@kbn/kibana-react-plugin/public', () => ({ }), })); +const MockCustomSearchBar: typeof mockDiscoverService.navigation.ui.AggregateQueryTopNavMenu = + () =>
; + const mockTopNavCustomization: TopNavCustomization = { id: 'top_nav', }; @@ -37,24 +41,16 @@ const mockSearchBarCustomization: SearchBarCustomization = { CustomDataViewPicker: jest.fn(() =>
), }; +const mockSearchBarCustomizationWithCustomSearchBar: SearchBarCustomization = { + id: 'search_bar', + CustomSearchBar: MockCustomSearchBar, +}; + let mockUseCustomizations = false; jest.mock('../../../../customizations', () => ({ ...jest.requireActual('../../../../customizations'), - useDiscoverCustomization: jest.fn((id: DiscoverCustomizationId) => { - if (!mockUseCustomizations) { - return undefined; - } - - switch (id) { - case 'top_nav': - return mockTopNavCustomization; - case 'search_bar': - return mockSearchBarCustomization; - default: - throw new Error(`Unknown customization id: ${id}`); - } - }), + useDiscoverCustomization: jest.fn(), })); function getProps(savePermissions = true): DiscoverTopNavProps { @@ -79,6 +75,23 @@ describe('Discover topnav component', () => { mockTopNavCustomization.getMenuItems = undefined; mockUseCustomizations = false; jest.clearAllMocks(); + + (useDiscoverCustomization as jest.Mock).mockImplementation( + jest.fn((id: DiscoverCustomizationId) => { + if (!mockUseCustomizations) { + return undefined; + } + + switch (id) { + case 'top_nav': + return mockTopNavCustomization; + case 'search_bar': + return mockSearchBarCustomization; + default: + throw new Error(`Unknown customization id: ${id}`); + } + }) + ); }); test('generated config of TopNavMenu config is correct when discover save permissions are assigned', () => { @@ -175,6 +188,23 @@ describe('Discover topnav component', () => { }); describe('search bar customization', () => { + it('should render custom Search Bar', () => { + (useDiscoverCustomization as jest.Mock).mockImplementation((id: DiscoverCustomizationId) => { + if (id === 'search_bar') { + return mockSearchBarCustomizationWithCustomSearchBar; + } + }); + + const props = getProps(); + const component = mountWithIntl( + + + + ); + + expect(component.find({ 'data-test-subj': 'custom-search-bar' })).toHaveLength(1); + }); + it('should render CustomDataViewPicker', () => { mockUseCustomizations = true; const props = getProps(); diff --git a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx index 528343ab8c260..d54e6490da4d1 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx @@ -201,8 +201,13 @@ export const DiscoverTopNav = ({ const searchBarCustomization = useDiscoverCustomization('search_bar'); + const SearchBar = useMemo( + () => searchBarCustomization?.CustomSearchBar ?? AggregateQueryTopNavMenu, + [searchBarCustomization?.CustomSearchBar, AggregateQueryTopNavMenu] + ); + return ( - { - const pageTitleSuffix = savedSearch.id && savedSearch.title ? `: ${savedSearch.title}` : ''; - chrome.docTitle.change(`Discover${pageTitleSuffix}`); - setBreadcrumbsTitle({ title: savedSearch.title, services }); - }, [chrome.docTitle, savedSearch.id, savedSearch.title, services]); + if (mode === 'standalone') { + const pageTitleSuffix = savedSearch.id && savedSearch.title ? `: ${savedSearch.title}` : ''; + chrome.docTitle.change(`Discover${pageTitleSuffix}`); + setBreadcrumbsTitle({ title: savedSearch.title, services }); + } + }, [mode, chrome.docTitle, savedSearch.id, savedSearch.title, services]); useEffect(() => { addHelpMenuToAppChrome(chrome, docLinks); diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index ae90d0b3dc736..39726044a2502 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -34,6 +34,7 @@ import { DiscoverCustomizationProvider, useDiscoverCustomizationService, } from '../../customizations'; +import type { DiscoverDisplayMode } from '../types'; const DiscoverMainAppMemoized = memo(DiscoverMainApp); @@ -44,9 +45,14 @@ interface DiscoverLandingParams { export interface MainRouteProps { customizationCallbacks: CustomizationCallback[]; isDev: boolean; + mode?: DiscoverDisplayMode; } -export function DiscoverMainRoute({ customizationCallbacks, isDev }: MainRouteProps) { +export function DiscoverMainRoute({ + customizationCallbacks, + isDev, + mode = 'standalone', +}: MainRouteProps) { const history = useHistory(); const services = useDiscoverServices(); const { @@ -146,21 +152,21 @@ export function DiscoverMainRoute({ customizationCallbacks, isDev }: MainRoutePr dataView: nextDataView, dataViewSpec: historyLocationState?.dataViewSpec, }); + if (mode === 'standalone') { + if (currentSavedSearch?.id) { + chrome.recentlyAccessed.add( + getSavedSearchFullPathUrl(currentSavedSearch.id), + currentSavedSearch.title ?? '', + currentSavedSearch.id + ); + } - if (currentSavedSearch?.id) { - chrome.recentlyAccessed.add( - getSavedSearchFullPathUrl(currentSavedSearch.id), - currentSavedSearch.title ?? '', - currentSavedSearch.id + chrome.setBreadcrumbs( + currentSavedSearch && currentSavedSearch.title + ? getSavedSearchBreadcrumbs({ id: currentSavedSearch.title, services }) + : getRootBreadcrumbs({ services }) ); } - - chrome.setBreadcrumbs( - currentSavedSearch && currentSavedSearch.title - ? getSavedSearchBreadcrumbs({ id: currentSavedSearch.title, services }) - : getRootBreadcrumbs({ services }) - ); - setLoading(false); if (services.analytics) { const loadSavedSearchDuration = window.performance.now() - loadSavedSearchStartTime; @@ -205,6 +211,7 @@ export function DiscoverMainRoute({ customizationCallbacks, isDev }: MainRoutePr core.theme, basePath, toastNotifications, + mode, ] ); @@ -278,8 +285,10 @@ export function DiscoverMainRoute({ customizationCallbacks, isDev }: MainRoutePr return ( - + ); } +// eslint-disable-next-line import/no-default-export +export default DiscoverMainRoute; diff --git a/src/plugins/discover/public/application/types.ts b/src/plugins/discover/public/application/types.ts index 798e0f350cc5f..588ca00f89825 100644 --- a/src/plugins/discover/public/application/types.ts +++ b/src/plugins/discover/public/application/types.ts @@ -13,3 +13,5 @@ export enum FetchStatus { COMPLETE = 'complete', ERROR = 'error', } + +export type DiscoverDisplayMode = 'embedded' | 'standalone'; diff --git a/src/plugins/discover/public/components/discover_container/discover_container.test.tsx b/src/plugins/discover/public/components/discover_container/discover_container.test.tsx new file mode 100644 index 0000000000000..3fb0e5d6bb435 --- /dev/null +++ b/src/plugins/discover/public/components/discover_container/discover_container.test.tsx @@ -0,0 +1,93 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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, waitFor } from '@testing-library/react'; +import { DiscoverServices } from '../../build_services'; +import DiscoverContainerInternal, { DiscoverContainerInternalProps } from './discover_container'; +import { ScopedHistory } from '@kbn/core-application-browser'; +import { discoverServiceMock } from '../../__mocks__/services'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; + +const mockOverrideService = {}; +const getDiscoverServicesMock = jest.fn( + () => new Promise((resolve) => resolve(discoverServiceMock)) +); + +jest.mock('../../application/main', () => { + return { + DiscoverMainRoute: () => <>, + }; +}); + +jest.mock('@kbn/kibana-react-plugin/public'); + +const { history } = discoverServiceMock; + +const customizeMock = jest.fn(); + +const TestComponent = (props: Partial) => { + return ( + )} + getDiscoverServices={getDiscoverServicesMock} + /> + ); +}; + +const TEST_IDS = { + DISCOVER_CONTAINER_INTERNAL: 'data-container-internal-wrapper', +}; + +describe('DiscoverContainerInternal should render properly', () => { + beforeAll(() => { + (KibanaContextProvider as jest.Mock).mockImplementation(() => <>); + }); + + afterEach(() => jest.clearAllMocks()); + + it('should render', async () => { + const { getByTestId, queryByTestId } = render(); + expect(queryByTestId(TEST_IDS.DISCOVER_CONTAINER_INTERNAL)).not.toBeInTheDocument(); + + expect(getDiscoverServicesMock).toHaveBeenCalledTimes(1); + + await waitFor(() => { + expect(getByTestId(TEST_IDS.DISCOVER_CONTAINER_INTERNAL)).toBeInTheDocument(); + }); + }); + + it('should render with overrideServices', async () => { + const overrideServices: Partial = { + data: { + ...dataPluginMock.createStartContract(), + // @ts-expect-error + _name: 'custom', + }, + }; + render(); + + await waitFor(() => { + expect(KibanaContextProvider as jest.Mock).toHaveBeenNthCalledWith( + 1, + expect.objectContaining({ + services: expect.objectContaining({ + data: expect.objectContaining({ + _name: 'custom', + }), + }), + }), + {} + ); + }); + }); +}); diff --git a/src/plugins/discover/public/components/discover_container/discover_container.tsx b/src/plugins/discover/public/components/discover_container/discover_container.tsx new file mode 100644 index 0000000000000..23afbd7965bc7 --- /dev/null +++ b/src/plugins/discover/public/components/discover_container/discover_container.tsx @@ -0,0 +1,95 @@ +/* + * Copyright 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 { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import type { ScopedHistory } from '@kbn/core/public'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import React, { useEffect, useMemo, useState } from 'react'; +import { DiscoverMainRoute } from '../../application/main'; +import type { DiscoverServices } from '../../build_services'; +import type { CustomizationCallback } from '../../customizations'; +import { setHeaderActionMenuMounter, setScopedHistory } from '../../kibana_services'; +import { LoadingIndicator } from '../common/loading_indicator'; + +export interface DiscoverContainerInternalProps { + /* + * Any override that user of this hook + * wants discover to use. Need to keep in mind that this + * param is only for overrides for the services that Discover + * already consumes. + */ + overrideServices: Partial; + getDiscoverServices: () => Promise; + scopedHistory: ScopedHistory; + customize: CustomizationCallback; + isDev: boolean; +} + +const DiscoverContainerWrapper = euiStyled(EuiFlexGroup)` + width: 100%; + height: 100%; + + // override the embedded discover page height + // to fit in the container + .dscPage { + height: 100% +} +`; + +export const DiscoverContainerInternal = ({ + overrideServices, + scopedHistory, + customize, + isDev, + getDiscoverServices, +}: DiscoverContainerInternalProps) => { + const [discoverServices, setDiscoverServices] = useState(); + const customizationCallbacks = useMemo(() => [customize], [customize]); + const [initialized, setInitialized] = useState(false); + + useEffect(() => { + getDiscoverServices().then((svcs) => setDiscoverServices(svcs)); + }, [getDiscoverServices]); + + useEffect(() => { + setScopedHistory(scopedHistory); + setHeaderActionMenuMounter(() => {}); + setInitialized(true); + }, [scopedHistory]); + + const services = useMemo(() => { + if (!discoverServices) return; + return { ...discoverServices, ...overrideServices }; + }, [discoverServices, overrideServices]); + + if (!initialized || !services) { + return ( + + + + ); + } + + return ( + + + + + + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export default DiscoverContainerInternal; diff --git a/src/plugins/discover/public/components/discover_container/index.ts b/src/plugins/discover/public/components/discover_container/index.ts new file mode 100644 index 0000000000000..0cc48d01dfafb --- /dev/null +++ b/src/plugins/discover/public/components/discover_container/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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'; +import type { DiscoverContainerInternalProps } from './discover_container'; + +export type DiscoverContainerProps = Omit< + DiscoverContainerInternalProps, + 'isDev' | 'getDiscoverServices' +>; + +export const DiscoverContainerInternal = withSuspense(lazy(() => import('./discover_container'))); diff --git a/src/plugins/discover/public/customizations/customization_types/search_bar_customization.ts b/src/plugins/discover/public/customizations/customization_types/search_bar_customization.ts index 8117781a95c93..4395d310aa997 100644 --- a/src/plugins/discover/public/customizations/customization_types/search_bar_customization.ts +++ b/src/plugins/discover/public/customizations/customization_types/search_bar_customization.ts @@ -6,9 +6,12 @@ * Side Public License, v 1. */ -import type { ComponentType } from 'react'; +import type { AggregateQuery } from '@kbn/es-query'; +import type { TopNavMenuProps } from '@kbn/navigation-plugin/public'; +import type { ComponentType, ReactElement } from 'react'; export interface SearchBarCustomization { id: 'search_bar'; CustomDataViewPicker?: ComponentType; + CustomSearchBar?: (props: TopNavMenuProps) => ReactElement; } diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index dba5a81bee1e3..f567380276354 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -16,6 +16,7 @@ export function plugin(initializerContext: PluginInitializerContext) { export type { ISearchEmbeddable, SearchInput } from './embeddable'; export type { DiscoverStateContainer } from './application/main/services/discover_state'; +export type { DiscoverContainerProps } from './components/discover_container'; export type { CustomizationCallback, DiscoverProfileId, diff --git a/src/plugins/discover/public/mocks.ts b/src/plugins/discover/public/mocks.tsx similarity index 91% rename from src/plugins/discover/public/mocks.ts rename to src/plugins/discover/public/mocks.tsx index 93d4202ff3f3e..e733e9d32dbee 100644 --- a/src/plugins/discover/public/mocks.ts +++ b/src/plugins/discover/public/mocks.tsx @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import React from 'react'; import { sharePluginMock } from '@kbn/share-plugin/public/mocks'; import { DiscoverSetup, DiscoverStart } from '.'; @@ -25,6 +26,7 @@ const createSetupContract = (): Setup => { const createStartContract = (): Start => { const startContract: Start = { locator: sharePluginMock.createLocator(), + DiscoverContainer: jest.fn().mockImplementation(() => <>), registerCustomizationProfile: jest.fn(), }; return startContract; diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index c7f2dcdd0c36b..41d3ba10f9b2d 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -7,7 +7,7 @@ */ import { i18n } from '@kbn/i18n'; -import React from 'react'; +import React, { ComponentType } from 'react'; import { BehaviorSubject, combineLatest, map } from 'rxjs'; import { AppMountParameters, @@ -78,6 +78,7 @@ import { createProfileRegistry, } from './customizations/profile_registry'; import { SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER } from './embeddable/constants'; +import { DiscoverContainerInternal, DiscoverContainerProps } from './components/discover_container'; const DocViewerLegacyTable = React.lazy( () => import('./services/doc_views/components/doc_viewer_table/legacy') @@ -162,6 +163,7 @@ export interface DiscoverStart { * ``` */ readonly locator: undefined | DiscoverAppLocator; + readonly DiscoverContainer: ComponentType; readonly registerCustomizationProfile: RegisterCustomizationProfile; } @@ -420,18 +422,31 @@ export class DiscoverPlugin // initializeServices are assigned at start and used // when the application/embeddable is mounted - const { uiActions } = plugins; - - uiActions.registerTrigger(SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER); - const viewSavedSearchAction = new ViewSavedSearchAction(core.application); - uiActions.addTriggerAction('CONTEXT_MENU_TRIGGER', viewSavedSearchAction); - setUiActions(plugins.uiActions); + plugins.uiActions.addTriggerAction('CONTEXT_MENU_TRIGGER', viewSavedSearchAction); + plugins.uiActions.registerTrigger(SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER); + setUiActions(plugins.uiActions); injectTruncateStyles(core.uiSettings.get(TRUNCATE_MAX_HEIGHT)); + const isDev = this.initializerContext.env.mode.dev; + + const getDiscoverServicesInternal = () => { + return this.getDiscoverServices(core, plugins); + }; + return { locator: this.locator, + DiscoverContainer: ({ overrideServices, ...restProps }: DiscoverContainerProps) => { + return ( + + ); + }, registerCustomizationProfile: createRegisterCustomizationProfile(this.profileRegistry), }; } @@ -442,6 +457,23 @@ export class DiscoverPlugin } } + private getDiscoverServices = async (core: CoreStart, plugins: DiscoverStartPlugins) => { + const { locator, contextLocator, singleDocLocator } = await getProfileAwareLocators({ + locator: this.locator!, + contextLocator: this.contextLocator!, + singleDocLocator: this.singleDocLocator!, + }); + + return buildServices( + core, + plugins, + this.initializerContext, + locator, + contextLocator, + singleDocLocator + ); + }; + private registerEmbeddable(core: CoreSetup, plugins: DiscoverSetupPlugins) { const getStartServices = async () => { const [coreStart, deps] = await core.getStartServices(); @@ -451,25 +483,12 @@ export class DiscoverPlugin }; }; - const getDiscoverServices = async () => { - const [coreStart, discoverStartPlugins] = await core.getStartServices(); - const { locator, contextLocator, singleDocLocator } = await getProfileAwareLocators({ - locator: this.locator!, - contextLocator: this.contextLocator!, - singleDocLocator: this.singleDocLocator!, - }); - - return buildServices( - coreStart, - discoverStartPlugins, - this.initializerContext, - locator, - contextLocator, - singleDocLocator - ); + const getDiscoverServicesInternal = async () => { + const [coreStart, deps] = await core.getStartServices(); + return this.getDiscoverServices(coreStart, deps); }; - const factory = new SearchEmbeddableFactory(getStartServices, getDiscoverServices); + const factory = new SearchEmbeddableFactory(getStartServices, getDiscoverServicesInternal); plugins.embeddable.registerEmbeddableFactory(factory.type, factory); } } diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index 3b2903f686079..51377e4246122 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -3,7 +3,13 @@ "compilerOptions": { "outDir": "target/types" }, - "include": ["common/**/*", "public/**/*", "server/**/*", "../../../typings/**/*", ".storybook/**/*"], + "include": [ + "common/**/*", + "public/**/*", + "server/**/*", + "../../../typings/**/*", + ".storybook/**/*" + ], "kbn_references": [ "@kbn/core", "@kbn/charts-plugin", @@ -55,9 +61,11 @@ "@kbn/unified-field-list", "@kbn/core-saved-objects-api-server", "@kbn/cell-actions", - "@kbn/discover-utils", + "@kbn/shared-ux-utility", + "@kbn/core-application-browser", + "@kbn/discover-utils" ], "exclude": [ - "target/**/*", + "target/**/*" ] } diff --git a/src/plugins/navigation/public/mocks.ts b/src/plugins/navigation/public/mocks.ts index 64e535b6e114a..e6e4ff5128b0e 100644 --- a/src/plugins/navigation/public/mocks.ts +++ b/src/plugins/navigation/public/mocks.ts @@ -23,6 +23,7 @@ const createStartContract = (): jest.Mocked => { const startContract = { ui: { TopNavMenu: jest.fn(), + createTopNavWithCustomContext: jest.fn().mockImplementation(() => jest.fn()), AggregateQueryTopNavMenu: jest.fn(), }, }; diff --git a/src/plugins/navigation/public/plugin.ts b/src/plugins/navigation/public/plugin.ts index e3fe470d9c338..3be546918cdc2 100644 --- a/src/plugins/navigation/public/plugin.ts +++ b/src/plugins/navigation/public/plugin.ts @@ -7,12 +7,14 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { NavigationPublicPluginSetup, NavigationPublicPluginStart, NavigationPluginStartDependencies, } from './types'; import { TopNavMenuExtensionsRegistry, createTopNav } from './top_nav_menu'; +import { RegisteredTopNavMenuData } from './top_nav_menu/top_nav_menu_data'; export class NavigationPublicPlugin implements Plugin @@ -36,10 +38,31 @@ export class NavigationPublicPlugin ): NavigationPublicPluginStart { const extensions = this.topNavMenuExtensionsRegistry.getAll(); + /* + * + * This helps clients of navigation to create + * a TopNav Search Bar which does not uses global unifiedSearch/data/query service + * + * Useful in creating multiple stateful SearchBar in the same app without affecting + * global filters + * + * */ + const createCustomTopNav = ( + /* + * Custom instance of unified search if it needs to be overridden + * + * */ + customUnifiedSearch?: UnifiedSearchPublicPluginStart, + customExtensions?: RegisteredTopNavMenuData[] + ) => { + return createTopNav(customUnifiedSearch ?? unifiedSearch, customExtensions ?? extensions); + }; + return { ui: { TopNavMenu: createTopNav(unifiedSearch, extensions), AggregateQueryTopNavMenu: createTopNav(unifiedSearch, extensions), + createTopNavWithCustomContext: createCustomTopNav, }, }; } diff --git a/src/plugins/navigation/public/types.ts b/src/plugins/navigation/public/types.ts index a4ca72cf9cb3a..8958aa91d5ff6 100644 --- a/src/plugins/navigation/public/types.ts +++ b/src/plugins/navigation/public/types.ts @@ -8,7 +8,8 @@ import { AggregateQuery, Query } from '@kbn/es-query'; import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; -import { TopNavMenuProps, TopNavMenuExtensionsRegistrySetup } from './top_nav_menu'; +import { TopNavMenuProps, TopNavMenuExtensionsRegistrySetup, createTopNav } from './top_nav_menu'; +import { RegisteredTopNavMenuData } from './top_nav_menu/top_nav_menu_data'; export interface NavigationPublicPluginSetup { registerMenuItem: TopNavMenuExtensionsRegistrySetup['register']; @@ -18,6 +19,10 @@ export interface NavigationPublicPluginStart { ui: { TopNavMenu: (props: TopNavMenuProps) => React.ReactElement; AggregateQueryTopNavMenu: (props: TopNavMenuProps) => React.ReactElement; + createTopNavWithCustomContext: ( + customUnifiedSearch?: UnifiedSearchPublicPluginStart, + customExtensions?: RegisteredTopNavMenuData[] + ) => ReturnType; }; } diff --git a/src/plugins/unified_histogram/public/__mocks__/services.tsx b/src/plugins/unified_histogram/public/__mocks__/services.tsx index 6b6e5a7f46864..b7efb79941412 100644 --- a/src/plugins/unified_histogram/public/__mocks__/services.tsx +++ b/src/plugins/unified_histogram/public/__mocks__/services.tsx @@ -33,7 +33,9 @@ export const unifiedHistogramServicesMock = { suggestions: jest.fn(() => allSuggestionsMock), }; }), - EditLensConfigPanelApi: jest.fn().mockResolvedValue(Lens Config Panel Component), + EditLensConfigPanelApi: jest + .fn() + .mockResolvedValue(() => Lens Config Panel Component), }, storage: { get: jest.fn(), diff --git a/src/plugins/unified_histogram/public/chart/chart.tsx b/src/plugins/unified_histogram/public/chart/chart.tsx index 907ec70aa3b69..ba6ffbaf149fe 100644 --- a/src/plugins/unified_histogram/public/chart/chart.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.tsx @@ -42,7 +42,7 @@ import { useTotalHits } from './hooks/use_total_hits'; import { useRequestParams } from './hooks/use_request_params'; import { useChartStyles } from './hooks/use_chart_styles'; import { useChartActions } from './hooks/use_chart_actions'; -import { useChartConfigPanel } from './hooks/use_chart_config_panel'; +import { ChartConfigPanel } from './chart_config_panel'; import { getLensAttributes } from './utils/get_lens_attributes'; import { useRefetch } from './hooks/use_refetch'; import { useEditVisualization } from './hooks/use_edit_visualization'; @@ -220,19 +220,6 @@ export function Chart({ ] ); - const ChartConfigPanel = useChartConfigPanel({ - services, - lensAttributesContext, - dataView, - lensTablesAdapter, - currentSuggestion, - isFlyoutVisible, - setIsFlyoutVisible, - isPlainRecord, - query: originalQuery, - onSuggestionChange, - }); - const onSuggestionSelectorChange = useCallback( (s: Suggestion | undefined) => { onSuggestionChange?.(s); @@ -455,7 +442,22 @@ export function Chart({ isSaveable={false} /> )} - {isFlyoutVisible && ChartConfigPanel} + {isFlyoutVisible && ( + + )} ); } diff --git a/src/plugins/unified_histogram/public/chart/chart_config_panel.test.tsx b/src/plugins/unified_histogram/public/chart/chart_config_panel.test.tsx new file mode 100644 index 0000000000000..710666ac6637b --- /dev/null +++ b/src/plugins/unified_histogram/public/chart/chart_config_panel.test.tsx @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import { render } from '@testing-library/react'; +import { act } from 'react-dom/test-utils'; +import { setTimeout } from 'timers/promises'; +import { dataViewWithTimefieldMock } from '../__mocks__/data_view_with_timefield'; +import { unifiedHistogramServicesMock } from '../__mocks__/services'; +import { lensTablesAdapterMock } from '../__mocks__/lens_table_adapter'; +import { ChartConfigPanel } from './chart_config_panel'; +import type { LensAttributesContext } from './utils/get_lens_attributes'; + +describe('ChartConfigPanel', () => { + it('should return a jsx element to edit the visualization', async () => { + const lensAttributes = { + visualizationType: 'lnsXY', + title: 'test', + } as TypedLensByValueInput['attributes']; + const { container } = render( + + ); + await act(() => setTimeout(0)); + expect(container).not.toBeEmptyDOMElement(); + }); + + it('should return null if not in text based mode', async () => { + const lensAttributes = { + visualizationType: 'lnsXY', + title: 'test', + } as TypedLensByValueInput['attributes']; + const { container } = render( + + ); + await act(() => setTimeout(0)); + expect(container).toBeEmptyDOMElement(); + }); +}); diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.tsx b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx similarity index 92% rename from src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.tsx rename to src/plugins/unified_histogram/public/chart/chart_config_panel.tsx index c8b70c043fcdc..c3faacd5b9a40 100644 --- a/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.tsx +++ b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx @@ -12,10 +12,10 @@ import type { Suggestion } from '@kbn/lens-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { Datatable } from '@kbn/expressions-plugin/common'; -import type { UnifiedHistogramServices } from '../../types'; -import type { LensAttributesContext } from '../utils/get_lens_attributes'; +import type { UnifiedHistogramServices } from '../types'; +import type { LensAttributesContext } from './utils/get_lens_attributes'; -export function useChartConfigPanel({ +export function ChartConfigPanel({ services, lensAttributesContext, dataView, @@ -49,7 +49,9 @@ export function useChartConfigPanel({ ...(datasourceState && { datasourceState }), ...(visualizationState && { visualizationState }), } as Suggestion; - onSuggestionChange?.(updatedSuggestion); + if (!isEqual(updatedSuggestion, currentSuggestion)) { + onSuggestionChange?.(updatedSuggestion); + } }, [currentSuggestion, onSuggestionChange] ); diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.test.tsx b/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.test.tsx deleted file mode 100644 index 5f0d4b17e80db..0000000000000 --- a/src/plugins/unified_histogram/public/chart/hooks/use_chart_config_panel.test.tsx +++ /dev/null @@ -1,66 +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 type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; -import { renderHook } from '@testing-library/react-hooks'; -import { act } from 'react-test-renderer'; -import { setTimeout } from 'timers/promises'; -import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield'; -import { unifiedHistogramServicesMock } from '../../__mocks__/services'; -import { lensTablesAdapterMock } from '../../__mocks__/lens_table_adapter'; -import { useChartConfigPanel } from './use_chart_config_panel'; -import type { LensAttributesContext } from '../utils/get_lens_attributes'; - -describe('useChartConfigPanel', () => { - it('should return a jsx element to edit the visualization', async () => { - const lensAttributes = { - visualizationType: 'lnsXY', - title: 'test', - } as TypedLensByValueInput['attributes']; - const hook = renderHook(() => - useChartConfigPanel({ - services: unifiedHistogramServicesMock, - dataView: dataViewWithTimefieldMock, - lensAttributesContext: { - attributes: lensAttributes, - } as unknown as LensAttributesContext, - isFlyoutVisible: true, - setIsFlyoutVisible: jest.fn(), - isPlainRecord: true, - lensTablesAdapter: lensTablesAdapterMock, - query: { - sql: 'Select * from test', - }, - }) - ); - await act(() => setTimeout(0)); - expect(hook.result.current).toBeDefined(); - expect(hook.result.current).not.toBeNull(); - }); - - it('should return null if not in text based mode', async () => { - const lensAttributes = { - visualizationType: 'lnsXY', - title: 'test', - } as TypedLensByValueInput['attributes']; - const hook = renderHook(() => - useChartConfigPanel({ - services: unifiedHistogramServicesMock, - dataView: dataViewWithTimefieldMock, - lensAttributesContext: { - attributes: lensAttributes, - } as unknown as LensAttributesContext, - isFlyoutVisible: true, - setIsFlyoutVisible: jest.fn(), - isPlainRecord: false, - }) - ); - await act(() => setTimeout(0)); - expect(hook.result.current).toBeNull(); - }); -}); diff --git a/src/plugins/unified_search/public/index.ts b/src/plugins/unified_search/public/index.ts index 8d7a6146e02a5..b658a21d10cfd 100755 --- a/src/plugins/unified_search/public/index.ts +++ b/src/plugins/unified_search/public/index.ts @@ -28,6 +28,7 @@ export type { DataViewPickerProps } from './dataview_picker'; export type { ApplyGlobalFilterActionContext } from './actions'; export { ACTION_GLOBAL_APPLY_FILTER, UPDATE_FILTER_REFERENCES_ACTION } from './actions'; export { UPDATE_FILTER_REFERENCES_TRIGGER } from './triggers'; +export { createSearchBar } from './search_bar/create_search_bar'; /* * Autocomplete query suggestions: diff --git a/src/plugins/unified_search/public/mocks/mocks.ts b/src/plugins/unified_search/public/mocks/mocks.ts index d6140fe0ccc99..3c2ea2a0a38fe 100644 --- a/src/plugins/unified_search/public/mocks/mocks.ts +++ b/src/plugins/unified_search/public/mocks/mocks.ts @@ -34,6 +34,7 @@ const createStartContract = (): Start => { autocomplete: autocompleteStartMock, ui: { IndexPatternSelect: jest.fn(), + getCustomSearchBar: jest.fn(), SearchBar: jest.fn().mockReturnValue(null), AggregateQuerySearchBar: jest.fn().mockReturnValue(null), FiltersBuilderLazy: jest.fn(), diff --git a/src/plugins/unified_search/public/plugin.ts b/src/plugins/unified_search/public/plugin.ts index 5aeef71e82d8b..aa86d433547af 100755 --- a/src/plugins/unified_search/public/plugin.ts +++ b/src/plugins/unified_search/public/plugin.ts @@ -20,6 +20,7 @@ import type { UnifiedSearchSetupDependencies, UnifiedSearchPluginSetup, UnifiedSearchPublicPluginStart, + UnifiedSearchPublicPluginStartUi, } from './types'; import { createFilterAction } from './actions/apply_filter_action'; import { createUpdateFilterReferencesAction } from './actions/update_filter_references_action'; @@ -73,16 +74,28 @@ export class UnifiedSearchPublicPlugin setIndexPatterns(dataViews); const autocompleteStart = this.autocomplete.start(); - const SearchBar = createSearchBar({ - core, - data, - storage: this.storage, - usageCollection: this.usageCollection, - isScreenshotMode: Boolean(screenshotMode?.isScreenshotMode()), - unifiedSearch: { - autocomplete: autocompleteStart, - }, - }); + /* + * + * unifiedsearch uses global data service to create stateful search bar. + * This function helps in creating a search bar with different instances of data service + * so that it can be easy to use multiple stateful searchbars in the single applications + * + * */ + const getCustomSearchBar: UnifiedSearchPublicPluginStartUi['getCustomSearchBar'] = ( + customDataService + ) => + createSearchBar({ + core, + data: customDataService ?? data, + storage: this.storage, + usageCollection: this.usageCollection, + isScreenshotMode: Boolean(screenshotMode?.isScreenshotMode()), + unifiedSearch: { + autocomplete: autocompleteStart, + }, + }); + + const SearchBar = getCustomSearchBar(); uiActions.attachAction(APPLY_FILTER_TRIGGER, ACTION_GLOBAL_APPLY_FILTER); @@ -92,6 +105,7 @@ export class UnifiedSearchPublicPlugin ui: { IndexPatternSelect: createIndexPatternSelect(dataViews), SearchBar, + getCustomSearchBar, AggregateQuerySearchBar: SearchBar, FiltersBuilderLazy, }, diff --git a/src/plugins/unified_search/public/search_bar/create_search_bar.tsx b/src/plugins/unified_search/public/search_bar/create_search_bar.tsx index c713bb52e73f6..d9dd66bbf15aa 100644 --- a/src/plugins/unified_search/public/search_bar/create_search_bar.tsx +++ b/src/plugins/unified_search/public/search_bar/create_search_bar.tsx @@ -23,7 +23,7 @@ import { useSavedQuery } from './lib/use_saved_query'; import { useQueryStringManager } from './lib/use_query_string_manager'; import type { UnifiedSearchPublicPluginStart } from '../types'; -interface StatefulSearchBarDeps { +export interface StatefulSearchBarDeps { core: CoreStart; data: DataPublicPluginStart; storage: IStorageWrapper; diff --git a/src/plugins/unified_search/public/types.ts b/src/plugins/unified_search/public/types.ts index 66abc195b5b19..a6360b69cca26 100755 --- a/src/plugins/unified_search/public/types.ts +++ b/src/plugins/unified_search/public/types.ts @@ -20,6 +20,7 @@ import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management import { AutocompleteSetup, AutocompleteStart } from './autocomplete'; import type { IndexPatternSelectProps, StatefulSearchBarProps } from '.'; import type { FiltersBuilderProps } from './filters_builder/filters_builder'; +import { StatefulSearchBarDeps } from './search_bar/create_search_bar'; export interface UnifiedSearchSetupDependencies { uiActions: UiActionsSetup; @@ -39,15 +40,18 @@ export interface UnifiedSearchStartDependencies { screenshotMode?: ScreenshotModePluginStart; } +type AggQuerySearchBarComp = ( + props: StatefulSearchBarProps +) => React.ReactElement; + /** * Unified search plugin prewired UI components */ export interface UnifiedSearchPublicPluginStartUi { IndexPatternSelect: React.ComponentType; + getCustomSearchBar: (customDataService?: StatefulSearchBarDeps['data']) => AggQuerySearchBarComp; SearchBar: (props: StatefulSearchBarProps) => React.ReactElement; - AggregateQuerySearchBar: ( - props: StatefulSearchBarProps - ) => React.ReactElement; + AggregateQuerySearchBar: AggQuerySearchBarComp; FiltersBuilderLazy: React.ComponentType; } diff --git a/x-pack/plugins/alerting/common/routes/r_rule/index.ts b/x-pack/plugins/alerting/common/routes/r_rule/index.ts new file mode 100644 index 0000000000000..43de19735a40c --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { rRuleSchema } from './schemas/latest'; +export type { RRule } from './types/latest'; + +export { rRuleSchema as rRuleSchemaV1 } from './schemas/v1'; +export type { RRule as RRuleV1 } from './types/latest'; diff --git a/x-pack/plugins/alerting/common/routes/rule/create/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/schemas/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/create/schemas/latest.ts rename to x-pack/plugins/alerting/common/routes/r_rule/schemas/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/r_rule/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/schemas/v1.ts new file mode 100644 index 0000000000000..5e10629e4f7ee --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/schemas/v1.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; +import { + validateStartDateV1, + validateEndDateV1, + createValidateRecurrenceByV1, +} from '../validation'; + +export const rRuleSchema = schema.object({ + dtstart: schema.string({ validate: validateStartDateV1 }), + tzid: schema.string(), + freq: schema.maybe( + schema.oneOf([schema.literal(0), schema.literal(1), schema.literal(2), schema.literal(3)]) + ), + interval: schema.maybe( + schema.number({ + validate: (interval: number) => { + if (interval < 1) return 'rRule interval must be > 0'; + }, + }) + ), + until: schema.maybe(schema.string({ validate: validateEndDateV1 })), + count: schema.maybe( + schema.number({ + validate: (count: number) => { + if (count < 1) return 'rRule count must be > 0'; + }, + }) + ), + byweekday: schema.maybe( + schema.arrayOf(schema.string(), { + validate: createValidateRecurrenceByV1('byweekday'), + }) + ), + bymonthday: schema.maybe( + schema.arrayOf(schema.number(), { + validate: createValidateRecurrenceByV1('bymonthday'), + }) + ), + bymonth: schema.maybe( + schema.arrayOf(schema.number(), { + validate: createValidateRecurrenceByV1('bymonth'), + }) + ), +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/create/types/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/types/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/create/types/latest.ts rename to x-pack/plugins/alerting/common/routes/r_rule/types/latest.ts diff --git a/x-pack/plugins/reporting/server/export_types/png_v2/metadata.ts b/x-pack/plugins/alerting/common/routes/r_rule/types/v1.ts similarity index 65% rename from x-pack/plugins/reporting/server/export_types/png_v2/metadata.ts rename to x-pack/plugins/alerting/common/routes/r_rule/types/v1.ts index 56e18b96f663a..a8a2cf0f65e04 100644 --- a/x-pack/plugins/reporting/server/export_types/png_v2/metadata.ts +++ b/x-pack/plugins/alerting/common/routes/r_rule/types/v1.ts @@ -4,10 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type { TypeOf } from '@kbn/config-schema'; +import { rRuleSchemaV1 } from '..'; -import { PNG_REPORT_TYPE_V2 } from '../../../common/constants'; - -export const metadata = { - id: PNG_REPORT_TYPE_V2, - name: 'PNG', -}; +export type RRule = TypeOf; diff --git a/x-pack/plugins/alerting/common/routes/r_rule/validation/index.ts b/x-pack/plugins/alerting/common/routes/r_rule/validation/index.ts new file mode 100644 index 0000000000000..fc98963e03189 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/validation/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { validateStartDate } from './validate_start_date/latest'; +export { validateEndDate } from './validate_end_date/latest'; +export { createValidateRecurrenceBy } from './validate_recurrence_by/latest'; + +export { validateStartDate as validateStartDateV1 } from './validate_start_date/v1'; +export { validateEndDate as validateEndDateV1 } from './validate_end_date/v1'; +export { createValidateRecurrenceBy as createValidateRecurrenceByV1 } from './validate_recurrence_by/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/rule_response/constants/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_end_date/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/rule_response/constants/latest.ts rename to x-pack/plugins/alerting/common/routes/r_rule/validation/validate_end_date/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_end_date/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_end_date/v1.ts new file mode 100644 index 0000000000000..895c1aeea4dfb --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_end_date/v1.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const validateEndDate = (date: string) => { + const parsedValue = Date.parse(date); + if (isNaN(parsedValue)) return `Invalid date: ${date}`; + if (parsedValue <= Date.now()) return `Invalid snooze date as it is in the past: ${date}`; + return; +}; diff --git a/x-pack/plugins/alerting/common/routes/rule/rule_response/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_recurrence_by/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/rule_response/schemas/latest.ts rename to x-pack/plugins/alerting/common/routes/r_rule/validation/validate_recurrence_by/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_recurrence_by/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_recurrence_by/v1.ts new file mode 100644 index 0000000000000..0ab609355c680 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_recurrence_by/v1.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const validateRecurrenceBy = (name: string, array: T[]) => { + if (array.length === 0) { + return `rRule ${name} cannot be empty`; + } +}; + +export const createValidateRecurrenceBy = (name: string) => { + return (array: T[]) => validateRecurrenceBy(name, array); +}; diff --git a/x-pack/plugins/alerting/common/routes/rule/rule_response/types/latest.ts b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_start_date/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/rule_response/types/latest.ts rename to x-pack/plugins/alerting/common/routes/r_rule/validation/validate_start_date/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_start_date/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_start_date/v1.ts new file mode 100644 index 0000000000000..3cbc0da0af1b5 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/r_rule/validation/validate_start_date/v1.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const validateStartDate = (date: string) => { + const parsedValue = Date.parse(date); + if (isNaN(parsedValue)) return `Invalid date: ${date}`; + return; +}; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/index.ts new file mode 100644 index 0000000000000..1ae4a238cbf21 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { + ruleSnoozeScheduleSchema, + bulkEditOperationsSchema, + bulkEditRulesRequestBodySchema, +} from './schemas/latest'; +export type { + RuleSnoozeSchedule, + BulkEditRulesRequestBody, + BulkEditRulesResponse, +} from './types/latest'; + +export { + ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1, + bulkEditOperationsSchema as bulkEditOperationsSchemaV1, + bulkEditRulesRequestBodySchema as bulkEditRulesRequestBodySchemaV1, +} from './schemas/v1'; +export type { + RuleSnoozeSchedule as RuleSnoozeScheduleV1, + BulkEditRulesRequestBody as BulkEditRulesRequestBodyV1, + BulkEditRulesResponse as BulkEditRulesResponseV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/create/transforms/transform_create_body/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/latest.ts similarity index 100% rename from x-pack/plugins/alerting/server/routes/rule/create/transforms/transform_create_body/latest.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts new file mode 100644 index 0000000000000..adbebc679c218 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts @@ -0,0 +1,107 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; +import { validateDurationV1, validateNotifyWhenV1 } from '../../../validation'; +import { validateSnoozeScheduleV1 } from '../validation'; +import { rRuleSchemaV1 } from '../../../../r_rule'; +import { ruleNotifyWhenV1 } from '../../../response'; + +const notifyWhenSchema = schema.oneOf( + [ + schema.literal(ruleNotifyWhenV1.CHANGE), + schema.literal(ruleNotifyWhenV1.ACTIVE), + schema.literal(ruleNotifyWhenV1.THROTTLE), + ], + { validate: validateNotifyWhenV1 } +); + +export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); + +export const ruleSnoozeScheduleSchema = schema.object({ + id: schema.maybe(schema.string()), + duration: schema.number(), + rRule: rRuleSchemaV1, +}); + +const ruleSnoozeScheduleSchemaWithValidation = schema.object( + { + id: schema.maybe(schema.string()), + duration: schema.number(), + rRule: rRuleSchemaV1, + }, + { validate: validateSnoozeScheduleV1 } +); + +const ruleActionSchema = schema.object({ + group: schema.string(), + id: schema.string(), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + uuid: schema.maybe(schema.string()), + frequency: schema.maybe( + schema.object({ + summary: schema.boolean(), + throttle: schema.nullable(schema.string()), + notifyWhen: notifyWhenSchema, + }) + ), +}); + +export const bulkEditOperationsSchema = schema.arrayOf( + schema.oneOf([ + schema.object({ + operation: schema.oneOf([ + schema.literal('add'), + schema.literal('delete'), + schema.literal('set'), + ]), + field: schema.literal('tags'), + value: schema.arrayOf(schema.string()), + }), + schema.object({ + operation: schema.oneOf([schema.literal('add'), schema.literal('set')]), + field: schema.literal('actions'), + value: schema.arrayOf(ruleActionSchema), + }), + schema.object({ + operation: schema.literal('set'), + field: schema.literal('schedule'), + value: schema.object({ interval: schema.string({ validate: validateDurationV1 }) }), + }), + schema.object({ + operation: schema.literal('set'), + field: schema.literal('throttle'), + value: schema.nullable(schema.string()), + }), + schema.object({ + operation: schema.literal('set'), + field: schema.literal('notifyWhen'), + value: notifyWhenSchema, + }), + schema.object({ + operation: schema.oneOf([schema.literal('set')]), + field: schema.literal('snoozeSchedule'), + value: ruleSnoozeScheduleSchemaWithValidation, + }), + schema.object({ + operation: schema.oneOf([schema.literal('delete')]), + field: schema.literal('snoozeSchedule'), + value: schema.maybe(scheduleIdsSchema), + }), + schema.object({ + operation: schema.literal('set'), + field: schema.literal('apiKey'), + }), + ]), + { minSize: 1 } +); + +export const bulkEditRulesRequestBodySchema = schema.object({ + filter: schema.maybe(schema.string()), + ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1 })), + operations: bulkEditOperationsSchema, +}); diff --git a/x-pack/plugins/reporting/server/export_types/png/metadata.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/latest.ts similarity index 81% rename from x-pack/plugins/reporting/server/export_types/png/metadata.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/latest.ts index 37c77b7e013e6..25300c97a6d2e 100644 --- a/x-pack/plugins/reporting/server/export_types/png/metadata.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/latest.ts @@ -5,7 +5,4 @@ * 2.0. */ -export const metadata = { - id: 'png', - name: 'PNG', -}; +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/v1.ts new file mode 100644 index 0000000000000..8f98d1c140746 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/v1.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 { TypeOf } from '@kbn/config-schema'; +import { RuleParamsV1, RuleResponseV1 } from '../../../response'; +import { ruleSnoozeScheduleSchemaV1, bulkEditRulesRequestBodySchemaV1 } from '..'; + +export type RuleSnoozeSchedule = TypeOf; +export type BulkEditRulesRequestBody = TypeOf; + +interface BulkEditActionSkippedResult { + id: RuleResponseV1['id']; + name?: RuleResponseV1['name']; + skip_reason: 'RULE_NOT_MODIFIED'; +} + +interface BulkEditOperationError { + message: string; + status?: number; + rule: { + id: string; + name: string; + }; +} + +export interface BulkEditRulesResponse { + body: { + rules: Array>; + skipped: BulkEditActionSkippedResult[]; + errors: BulkEditOperationError[]; + total: number; + }; +} diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/index.ts new file mode 100644 index 0000000000000..c11ce4f73f42c --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { validateSnoozeSchedule } from './validate_snooze_schedule/latest'; + +export { validateSnoozeSchedule as validateSnoozeScheduleV1 } from './validate_snooze_schedule/v1'; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/metadata.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/latest.ts similarity index 79% rename from x-pack/plugins/reporting/server/export_types/printable_pdf/metadata.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/latest.ts index 66b6ad88e43d9..25300c97a6d2e 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/metadata.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/latest.ts @@ -5,7 +5,4 @@ * 2.0. */ -export const metadata = { - id: 'printablePdf', - name: 'PDF', -}; +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/v1.ts new file mode 100644 index 0000000000000..65460110cd107 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/v1.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Frequency } from '@kbn/rrule'; +import moment from 'moment'; +import { RuleSnoozeScheduleV1 } from '../..'; + +export const validateSnoozeSchedule = (schedule: RuleSnoozeScheduleV1) => { + const intervalIsDaily = schedule.rRule.freq === Frequency.DAILY; + const durationInDays = moment.duration(schedule.duration, 'milliseconds').asDays(); + if (intervalIsDaily && schedule.rRule.interval && durationInDays >= schedule.rRule.interval) { + return 'Recurrence interval must be longer than the snooze duration'; + } +}; diff --git a/x-pack/plugins/alerting/common/routes/rule/create/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/index.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/create/index.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/create/index.ts diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/metadata.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/latest.ts similarity index 78% rename from x-pack/plugins/reporting/server/export_types/printable_pdf_v2/metadata.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/latest.ts index f4fc93a86821b..25300c97a6d2e 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/metadata.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/latest.ts @@ -5,7 +5,4 @@ * 2.0. */ -export const metadata = { - id: 'printablePdfV2', - name: 'PDF', -}; +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/create/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts similarity index 97% rename from x-pack/plugins/alerting/common/routes/rule/create/schemas/v1.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts index 2fa5f7660461b..98d82abf62be4 100644 --- a/x-pack/plugins/alerting/common/routes/rule/create/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts @@ -6,13 +6,13 @@ */ import { schema } from '@kbn/config-schema'; -import { ruleNotifyWhenV1 } from '../../rule_response'; +import { ruleNotifyWhenV1 } from '../../../response'; import { validateNotifyWhenV1, validateDurationV1, validateHoursV1, validateTimezoneV1, -} from '../../validation'; +} from '../../../validation'; export const notifyWhenSchema = schema.oneOf( [ diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/types.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/types/latest.ts similarity index 69% rename from x-pack/plugins/reporting/server/export_types/printable_pdf_v2/types.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/create/types/latest.ts index b150d53984706..25300c97a6d2e 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/types.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/types/latest.ts @@ -5,7 +5,4 @@ * 2.0. */ -export type { - JobParamsPDFV2, - TaskPayloadPDFV2, -} from '../../../common/types/export_types/printable_pdf_v2'; +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/create/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/types/v1.ts similarity index 83% rename from x-pack/plugins/alerting/common/routes/rule/create/types/v1.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/create/types/v1.ts index d97af8bb6f69f..466f5d61eac46 100644 --- a/x-pack/plugins/alerting/common/routes/rule/create/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/types/v1.ts @@ -5,12 +5,12 @@ * 2.0. */ import type { TypeOf } from '@kbn/config-schema'; -import { RuleParamsV1, RuleResponseV1 } from '../../rule_response'; +import { RuleParamsV1, RuleResponseV1 } from '../../../response'; import { - actionSchema as actionSchemaV1, - actionFrequencySchema as actionFrequencySchemaV1, - createParamsSchema as createParamsSchemaV1, - createBodySchema as createBodySchemaV1, + actionSchemaV1, + actionFrequencySchemaV1, + createParamsSchemaV1, + createBodySchemaV1, } from '..'; export type CreateRuleAction = TypeOf; diff --git a/x-pack/plugins/alerting/common/routes/rule/response/constants/latest.ts b/x-pack/plugins/alerting/common/routes/rule/response/constants/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/response/constants/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/rule_response/constants/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/constants/v1.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/rule_response/constants/v1.ts rename to x-pack/plugins/alerting/common/routes/rule/response/constants/v1.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/rule_response/index.ts b/x-pack/plugins/alerting/common/routes/rule/response/index.ts similarity index 85% rename from x-pack/plugins/alerting/common/routes/rule/rule_response/index.ts rename to x-pack/plugins/alerting/common/routes/rule/response/index.ts index 451266e3a3483..1b7180910ca0a 100644 --- a/x-pack/plugins/alerting/common/routes/rule/rule_response/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/index.ts @@ -14,9 +14,10 @@ export { monitoringSchema, rRuleSchema, ruleResponseSchema, + ruleSnoozeScheduleSchema, } from './schemas/latest'; -export type { RuleParams, RuleResponse } from './types/latest'; +export type { RuleParams, RuleResponse, RuleSnoozeSchedule } from './types/latest'; export { ruleNotifyWhen, @@ -43,6 +44,7 @@ export { monitoringSchema as monitoringSchemaV1, rRuleSchema as rRuleSchemaV1, ruleResponseSchema as ruleResponseSchemaV1, + ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1, } from './schemas/v1'; export { @@ -61,4 +63,8 @@ export type { RuleExecutionStatusWarningReason as RuleExecutionStatusWarningReasonV1, } from './constants/v1'; -export type { RuleParams as RuleParamsV1, RuleResponse as RuleResponseV1 } from './types/v1'; +export type { + RuleParams as RuleParamsV1, + RuleResponse as RuleResponseV1, + RuleSnoozeSchedule as RuleSnoozeScheduleV1, +} from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/response/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/response/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/response/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/rule_response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts similarity index 98% rename from x-pack/plugins/alerting/common/routes/rule/rule_response/schemas/v1.ts rename to x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts index 8dbc37ea6aaad..3aecec56c3a41 100644 --- a/x-pack/plugins/alerting/common/routes/rule/rule_response/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts @@ -217,7 +217,7 @@ export const rRuleSchema = schema.object({ bysecond: schema.arrayOf(schema.number()), }); -const snoozeScheduleSchema = schema.object({ +export const ruleSnoozeScheduleSchema = schema.object({ duration: schema.number(), rRule: rRuleSchema, id: schema.maybe(schema.string()), @@ -248,7 +248,7 @@ export const ruleResponseSchema = schema.object({ muted_alert_ids: schema.arrayOf(schema.string()), execution_status: ruleExecutionStatusSchema, monitoring: schema.maybe(monitoringSchema), - snooze_schedule: schema.maybe(schema.arrayOf(snoozeScheduleSchema)), + snooze_schedule: schema.maybe(schema.arrayOf(ruleSnoozeScheduleSchema)), active_snoozes: schema.maybe(schema.arrayOf(schema.string())), is_snoozed_until: schema.maybe(schema.nullable(schema.string())), last_run: schema.maybe(schema.nullable(ruleLastRunSchema)), diff --git a/x-pack/plugins/alerting/common/routes/rule/response/types/latest.ts b/x-pack/plugins/alerting/common/routes/rule/response/types/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/response/types/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/rule_response/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts similarity index 92% rename from x-pack/plugins/alerting/common/routes/rule/rule_response/types/v1.ts rename to x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts index affd98575e270..cd19cf9fa5c5e 100644 --- a/x-pack/plugins/alerting/common/routes/rule/rule_response/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts @@ -6,9 +6,10 @@ */ import type { TypeOf } from '@kbn/config-schema'; -import { ruleParamsSchemaV1, ruleResponseSchemaV1 } from '..'; +import { ruleParamsSchemaV1, ruleResponseSchemaV1, ruleSnoozeScheduleSchemaV1 } from '..'; export type RuleParams = TypeOf; +export type RuleSnoozeSchedule = TypeOf; type RuleResponseSchemaType = TypeOf; export interface RuleResponse { diff --git a/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts b/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts index e239b1990f7b4..e58e5f5ef7cfd 100644 --- a/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ruleNotifyWhenV1, RuleNotifyWhenV1 } from '../../rule_response'; +import { ruleNotifyWhenV1, RuleNotifyWhenV1 } from '../../response'; export function validateNotifyWhen(notifyWhen: string) { if (Object.values(ruleNotifyWhenV1).includes(notifyWhen as RuleNotifyWhenV1)) { diff --git a/x-pack/plugins/alerting/server/application/r_rule/schemas/index.ts b/x-pack/plugins/alerting/server/application/r_rule/schemas/index.ts new file mode 100644 index 0000000000000..12e793318558d --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/schemas/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { rRuleSchema } from './r_rule_schema'; +export { rRuleRequestSchema } from './r_rule_request_schema'; diff --git a/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_request_schema.ts b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_request_schema.ts new file mode 100644 index 0000000000000..0c83d16dee024 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_request_schema.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { schema } from '@kbn/config-schema'; +import { validateStartDate, validateEndDate, createValidateRecurrenceBy } from '../validation'; + +export const rRuleRequestSchema = schema.object({ + dtstart: schema.string({ validate: validateStartDate }), + tzid: schema.string(), + freq: schema.maybe( + schema.oneOf([schema.literal(0), schema.literal(1), schema.literal(2), schema.literal(3)]) + ), + interval: schema.maybe( + schema.number({ + validate: (interval: number) => { + if (interval < 1) return 'rRule interval must be > 0'; + }, + }) + ), + until: schema.maybe(schema.string({ validate: validateEndDate })), + count: schema.maybe( + schema.number({ + validate: (count: number) => { + if (count < 1) return 'rRule count must be > 0'; + }, + }) + ), + byweekday: schema.maybe( + schema.arrayOf(schema.string(), { + validate: createValidateRecurrenceBy('byweekday'), + }) + ), + bymonthday: schema.maybe( + schema.arrayOf(schema.number(), { + validate: createValidateRecurrenceBy('bymonthday'), + }) + ), + bymonth: schema.maybe( + schema.arrayOf(schema.number(), { + validate: createValidateRecurrenceBy('bymonth'), + }) + ), +}); diff --git a/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_schema.ts b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_schema.ts new file mode 100644 index 0000000000000..6f8b2f8f4fc7a --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_schema.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { schema } from '@kbn/config-schema'; + +export const rRuleSchema = schema.object({ + dtstart: schema.string(), + tzid: schema.string(), + freq: schema.maybe( + schema.oneOf([ + schema.literal(0), + schema.literal(1), + schema.literal(2), + schema.literal(3), + schema.literal(4), + schema.literal(5), + schema.literal(6), + ]) + ), + until: schema.maybe(schema.string()), + count: schema.maybe(schema.number()), + interval: schema.maybe(schema.number()), + wkst: schema.maybe( + schema.oneOf([ + schema.literal('MO'), + schema.literal('TU'), + schema.literal('WE'), + schema.literal('TH'), + schema.literal('FR'), + schema.literal('SA'), + schema.literal('SU'), + ]) + ), + byweekday: schema.maybe(schema.arrayOf(schema.oneOf([schema.string(), schema.number()]))), + bymonth: schema.maybe(schema.arrayOf(schema.number())), + bysetpos: schema.maybe(schema.arrayOf(schema.number())), + bymonthday: schema.arrayOf(schema.number()), + byyearday: schema.arrayOf(schema.number()), + byweekno: schema.arrayOf(schema.number()), + byhour: schema.arrayOf(schema.number()), + byminute: schema.arrayOf(schema.number()), + bysecond: schema.arrayOf(schema.number()), +}); diff --git a/x-pack/plugins/alerting/server/application/r_rule/types/index.ts b/x-pack/plugins/alerting/server/application/r_rule/types/index.ts new file mode 100644 index 0000000000000..080598aca88e3 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/types/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { RRule } from './r_rule'; +export type { RRuleRequest } from './r_rule_request'; diff --git a/x-pack/plugins/alerting/server/application/r_rule/types/r_rule.ts b/x-pack/plugins/alerting/server/application/r_rule/types/r_rule.ts new file mode 100644 index 0000000000000..57700ea1b57d2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/types/r_rule.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TypeOf } from '@kbn/config-schema'; +import { rRuleSchema } from '../schemas/r_rule_schema'; + +export type RRule = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/r_rule/types/r_rule_request.ts b/x-pack/plugins/alerting/server/application/r_rule/types/r_rule_request.ts new file mode 100644 index 0000000000000..4f90eae946935 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/types/r_rule_request.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { TypeOf } from '@kbn/config-schema'; +import { rRuleRequestSchema } from '../schemas/r_rule_request_schema'; + +export type RRuleRequest = TypeOf; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/metadata.ts b/x-pack/plugins/alerting/server/application/r_rule/validation/index.ts similarity index 55% rename from x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/metadata.ts rename to x-pack/plugins/alerting/server/application/r_rule/validation/index.ts index c27b8484697dd..f48e8d5bf1c9a 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/metadata.ts +++ b/x-pack/plugins/alerting/server/application/r_rule/validation/index.ts @@ -5,9 +5,6 @@ * 2.0. */ -import { CSV_SEARCHSOURCE_IMMEDIATE_TYPE } from '../../../common/constants'; - -export const metadata = { - id: CSV_SEARCHSOURCE_IMMEDIATE_TYPE, - name: CSV_SEARCHSOURCE_IMMEDIATE_TYPE, -}; +export { validateStartDate } from './validate_start_date'; +export { validateEndDate } from './validate_end_date'; +export { validateRecurrenceBy, createValidateRecurrenceBy } from './validate_recurrence_by'; diff --git a/x-pack/plugins/alerting/server/application/r_rule/validation/validate_end_date.ts b/x-pack/plugins/alerting/server/application/r_rule/validation/validate_end_date.ts new file mode 100644 index 0000000000000..895c1aeea4dfb --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/validation/validate_end_date.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const validateEndDate = (date: string) => { + const parsedValue = Date.parse(date); + if (isNaN(parsedValue)) return `Invalid date: ${date}`; + if (parsedValue <= Date.now()) return `Invalid snooze date as it is in the past: ${date}`; + return; +}; diff --git a/x-pack/plugins/alerting/server/application/r_rule/validation/validate_recurrence_by.ts b/x-pack/plugins/alerting/server/application/r_rule/validation/validate_recurrence_by.ts new file mode 100644 index 0000000000000..0ab609355c680 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/validation/validate_recurrence_by.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const validateRecurrenceBy = (name: string, array: T[]) => { + if (array.length === 0) { + return `rRule ${name} cannot be empty`; + } +}; + +export const createValidateRecurrenceBy = (name: string) => { + return (array: T[]) => validateRecurrenceBy(name, array); +}; diff --git a/x-pack/plugins/alerting/server/application/r_rule/validation/validate_start_date.ts b/x-pack/plugins/alerting/server/application/r_rule/validation/validate_start_date.ts new file mode 100644 index 0000000000000..3cbc0da0af1b5 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/r_rule/validation/validate_start_date.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const validateStartDate = (date: string) => { + const parsedValue = Date.parse(date); + if (isNaN(parsedValue)) return `Invalid date: ${date}`; + return; +}; diff --git a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts similarity index 94% rename from x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts rename to x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts index 1f6e86945b1b5..9eeba46aeb865 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts @@ -6,27 +6,33 @@ */ import { schema } from '@kbn/config-schema'; +import { omit } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; import { AlertConsumers } from '@kbn/rule-data-utils'; -import { RulesClient, ConstructorOptions } from '../rules_client'; +import { RulesClient, ConstructorOptions } from '../../../../rules_client/rules_client'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; -import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; -import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock'; -import { RecoveredActionGroup, RuleTypeParams } from '../../../common'; +import { ruleTypeRegistryMock } from '../../../../rule_type_registry.mock'; +import { alertingAuthorizationMock } from '../../../../authorization/alerting_authorization.mock'; +import { RecoveredActionGroup, RuleTypeParams } from '../../../../../common'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; -import { AlertingAuthorization } from '../../authorization/alerting_authorization'; +import { AlertingAuthorization } from '../../../../authorization/alerting_authorization'; import { ActionsAuthorization, ActionsClient } from '@kbn/actions-plugin/server'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; -import { getBeforeSetup, setGlobalDate } from './lib'; -import { bulkMarkApiKeysForInvalidation } from '../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; -import { NormalizedAlertAction } from '../types'; -import { enabledRule1, enabledRule2, siemRule1, siemRule2 } from './test_helpers'; -import { migrateLegacyActions } from '../lib'; -import { migrateLegacyActionsMock } from '../lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock'; - -jest.mock('../lib/siem_legacy_actions/migrate_legacy_actions', () => { +import { getBeforeSetup, setGlobalDate } from '../../../../rules_client/tests/lib'; +import { bulkMarkApiKeysForInvalidation } from '../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; +import { NormalizedAlertAction } from '../../../../rules_client/types'; +import { + enabledRule1, + enabledRule2, + siemRule1, + siemRule2, +} from '../../../../rules_client/tests/test_helpers'; +import { migrateLegacyActions } from '../../../../rules_client/lib'; +import { migrateLegacyActionsMock } from '../../../../rules_client/lib/siem_legacy_actions/retrieve_migrated_legacy_actions.mock'; + +jest.mock('../../../../rules_client/lib/siem_legacy_actions/migrate_legacy_actions', () => { return { migrateLegacyActions: jest.fn(), }; @@ -37,11 +43,11 @@ jest.mock('../lib/siem_legacy_actions/migrate_legacy_actions', () => { resultedReferences: [], }); -jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ +jest.mock('../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ bulkMarkApiKeysForInvalidation: jest.fn(), })); -jest.mock('../../lib/snooze/is_snooze_active', () => ({ +jest.mock('../../../../lib/snooze/is_snooze_active', () => ({ isSnoozeActive: jest.fn(), })); @@ -50,7 +56,7 @@ jest.mock('uuid', () => { return { v4: () => `${uuid++}` }; }); -const { isSnoozeActive } = jest.requireMock('../../lib/snooze/is_snooze_active'); +const { isSnoozeActive } = jest.requireMock('../../../../lib/snooze/is_snooze_active'); const taskManager = taskManagerMock.createStart(); const ruleTypeRegistry = ruleTypeRegistryMock.create(); @@ -105,10 +111,21 @@ describe('bulkEdit()', () => { attributes: { enabled: false, tags: ['foo'], + createdBy: 'user', + createdAt: '2019-02-12T21:01:22.479Z', + updatedAt: '2019-02-12T21:01:22.479Z', + legacyId: null, + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], alertTypeId: 'myType', schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: {}, throttle: null, notifyWhen: null, @@ -244,6 +261,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: {}, throttle: null, notifyWhen: null, @@ -301,6 +322,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: {}, throttle: null, notifyWhen: null, @@ -354,6 +379,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: {}, throttle: null, notifyWhen: null, @@ -621,8 +650,15 @@ describe('bulkEdit()', () => { ], { overwrite: true } ); + expect(result.rules[0]).toEqual({ - ...existingRule.attributes, + ...omit(existingRule.attributes, 'legacyId'), + createdAt: new Date(existingRule.attributes.createdAt), + updatedAt: new Date(existingRule.attributes.updatedAt), + executionStatus: { + ...existingRule.attributes.executionStatus, + lastExecutionDate: new Date(existingRule.attributes.executionStatus.lastExecutionDate), + }, actions: [existingAction, { ...newAction, uuid: '222' }], id: existingRule.id, snoozeSchedule: [], @@ -827,7 +863,13 @@ describe('bulkEdit()', () => { { overwrite: true } ); expect(result.rules[0]).toEqual({ - ...existingRule.attributes, + ...omit(existingRule.attributes, 'legacyId'), + createdAt: new Date(existingRule.attributes.createdAt), + updatedAt: new Date(existingRule.attributes.updatedAt), + executionStatus: { + ...existingRule.attributes.executionStatus, + lastExecutionDate: new Date(existingRule.attributes.executionStatus.lastExecutionDate), + }, actions: [ existingAction, { @@ -875,6 +917,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['test-1', 'test-2', 'test-4', 'test-5'], }, @@ -940,6 +986,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['test-1'], }, @@ -1040,6 +1090,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: {}, throttle: null, notifyWhen: null, @@ -1414,7 +1468,7 @@ describe('bulkEdit()', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any (unsecuredSavedObjectsClient.bulkCreate.mock.calls[0][0][0].attributes as any) .snoozeSchedule - ).toBeUndefined(); + ).toEqual([]); }); }); @@ -1491,6 +1545,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['index-1', 'index-2', 'index-3'], }, @@ -1559,6 +1617,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['index-1', 'index-2'], }, @@ -1628,6 +1690,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['index-1', 'index-2', 'index-3'], }, @@ -2041,6 +2107,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['test-index-*'] }, throttle: null, notifyWhen: null, @@ -2437,6 +2507,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['test-index-*'] }, throttle: null, notifyWhen: null, @@ -2514,6 +2588,10 @@ describe('bulkEdit()', () => { schedule: { interval: '1m' }, consumer: 'myApp', scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, params: { index: ['test-index-*'] }, throttle: null, notifyWhen: null, @@ -2551,6 +2629,10 @@ describe('bulkEdit()', () => { tags: ['foo'], alertTypeId: 'myType', schedule: { interval: '1m' }, + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, consumer: 'myApp', params: { index: ['test-index-*'] }, throttle: null, diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts new file mode 100644 index 0000000000000..050b138eddd6b --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -0,0 +1,890 @@ +/* + * Copyright 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 pMap from 'p-map'; +import Boom from '@hapi/boom'; +import { cloneDeep } from 'lodash'; +import { AlertConsumers } from '@kbn/rule-data-utils'; +import { KueryNode, nodeBuilder } from '@kbn/es-query'; +import { + SavedObjectsBulkUpdateObject, + SavedObjectsBulkCreateObject, + SavedObjectsFindResult, + SavedObjectsUpdateResponse, +} from '@kbn/core/server'; +import { BulkActionSkipResult } from '../../../../../common/bulk_edit'; +import { RuleTypeRegistry } from '../../../../types'; +import { + validateRuleTypeParams, + getRuleNotifyWhenType, + validateMutatedRuleTypeParams, + convertRuleIdsToKueryNode, +} from '../../../../lib'; +import { WriteOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { parseDuration } from '../../../../../common/parse_duration'; +import { bulkMarkApiKeysForInvalidation } from '../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { + retryIfBulkEditConflicts, + applyBulkEditOperation, + buildKueryNodeFilter, + injectReferencesIntoActions, + getBulkSnooze, + getBulkUnsnooze, + verifySnoozeScheduleLimit, +} from '../../../../rules_client/common'; +import { + alertingAuthorizationFilterOpts, + MAX_RULES_NUMBER_FOR_BULK_OPERATION, + RULE_TYPE_CHECKS_CONCURRENCY, + API_KEY_GENERATE_CONCURRENCY, +} from '../../../../rules_client/common/constants'; +import { getMappedParams } from '../../../../rules_client/common/mapped_params_utils'; +import { + extractReferences, + validateActions, + updateMeta, + addGeneratedActionValues, + createNewAPIKeySet, +} from '../../../../rules_client/lib'; +import { + BulkOperationError, + RuleBulkOperationAggregation, + RulesClientContext, + NormalizedAlertActionWithGeneratedValues, +} from '../../../../rules_client/types'; +import { migrateLegacyActions } from '../../../../rules_client/lib'; +import { + BulkEditFields, + BulkEditOperation, + BulkEditOptionsFilter, + BulkEditOptionsIds, + ParamsModifier, + ShouldIncrementRevision, +} from './types'; +import { RawRuleAction, RawRule, SanitizedRule } from '../../../../types'; +import { ruleNotifyWhen } from '../../constants'; +import { ruleDomainSchema } from '../../schemas'; +import { RuleParams, RuleDomain, RuleSnoozeSchedule } from '../../types'; +import { findRulesSo, bulkCreateRulesSo } from '../../../../data/rule'; +import { RuleAttributes, RuleActionAttributes } from '../../../../data/rule/types'; +import { + transformRuleAttributesToRuleDomain, + transformRuleDomainToRuleAttributes, + transformRuleDomainToRule, +} from '../../transforms'; + +export const bulkEditFieldsToExcludeFromRevisionUpdates = new Set(['snoozeSchedule', 'apiKey']); + +type ApiKeysMap = Map< + string, + { + oldApiKey?: string; + newApiKey?: string; + oldApiKeyCreatedByUser?: boolean | null; + newApiKeyCreatedByUser?: boolean | null; + } +>; + +type ApiKeyAttributes = Pick; + +type RuleType = ReturnType; + +// TODO (http-versioning): This should be of type Rule, change this when all rule types are fixed +export interface BulkEditResult { + rules: Array>; + skipped: BulkActionSkipResult[]; + errors: BulkOperationError[]; + total: number; +} + +export type BulkEditOptions = + | BulkEditOptionsFilter + | BulkEditOptionsIds; + +export async function bulkEditRules( + context: RulesClientContext, + options: BulkEditOptions +): Promise> { + const queryFilter = (options as BulkEditOptionsFilter).filter; + const ids = (options as BulkEditOptionsIds).ids; + + if (ids && queryFilter) { + throw Boom.badRequest( + "Both 'filter' and 'ids' are supplied. Define either 'ids' or 'filter' properties in method arguments" + ); + } + + const qNodeQueryFilter = buildKueryNodeFilter(queryFilter); + + const qNodeFilter = ids ? convertRuleIdsToKueryNode(ids) : qNodeQueryFilter; + let authorizationTuple; + try { + authorizationTuple = await context.authorization.getFindAuthorizationFilter( + AlertingAuthorizationEntity.Rule, + alertingAuthorizationFilterOpts + ); + } catch (error) { + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.BULK_EDIT, + error, + }) + ); + throw error; + } + const { filter: authorizationFilter } = authorizationTuple; + const qNodeFilterWithAuth = + authorizationFilter && qNodeFilter + ? nodeBuilder.and([qNodeFilter, authorizationFilter as KueryNode]) + : qNodeFilter; + + const { aggregations, total } = await findRulesSo({ + savedObjectsClient: context.unsecuredSavedObjectsClient, + savedObjectsFindOptions: { + filter: qNodeFilterWithAuth, + page: 1, + perPage: 0, + aggs: { + alertTypeId: { + multi_terms: { + terms: [ + { field: 'alert.attributes.alertTypeId' }, + { field: 'alert.attributes.consumer' }, + ], + }, + }, + }, + }, + }); + + if (total > MAX_RULES_NUMBER_FOR_BULK_OPERATION) { + throw Boom.badRequest( + `More than ${MAX_RULES_NUMBER_FOR_BULK_OPERATION} rules matched for bulk edit` + ); + } + const buckets = aggregations?.alertTypeId.buckets; + + if (buckets === undefined) { + throw Error('No rules found for bulk edit'); + } + + await pMap( + buckets, + async ({ key: [ruleType, consumer] }) => { + context.ruleTypeRegistry.ensureRuleTypeEnabled(ruleType); + + try { + await context.authorization.ensureAuthorized({ + ruleTypeId: ruleType, + consumer, + operation: WriteOperations.BulkEdit, + entity: AlertingAuthorizationEntity.Rule, + }); + } catch (error) { + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.BULK_EDIT, + error, + }) + ); + throw error; + } + }, + { concurrency: RULE_TYPE_CHECKS_CONCURRENCY } + ); + + const { apiKeysToInvalidate, results, errors, skipped } = await retryIfBulkEditConflicts( + context.logger, + `rulesClient.update('operations=${JSON.stringify(options.operations)}, paramsModifier=${ + options.paramsModifier ? '[Function]' : undefined + }', shouldIncrementRevision=${options.shouldIncrementRevision ? '[Function]' : undefined}')`, + (filterKueryNode: KueryNode | null) => + bulkEditRulesOcc(context, { + filter: filterKueryNode, + operations: options.operations, + paramsModifier: options.paramsModifier, + shouldIncrementRevision: options.shouldIncrementRevision, + }), + qNodeFilterWithAuth + ); + + if (apiKeysToInvalidate.length > 0) { + await bulkMarkApiKeysForInvalidation( + { apiKeys: apiKeysToInvalidate }, + context.logger, + context.unsecuredSavedObjectsClient + ); + } + + const updatedRules = results.map(({ id, attributes, references }) => { + // TODO (http-versioning): alertTypeId should never be null, but we need to + // fix the type cast from SavedObjectsBulkUpdateObject to SavedObjectsBulkUpdateObject + // when we are doing the bulk create and this should fix itself + const ruleType = context.ruleTypeRegistry.get(attributes.alertTypeId!); + const ruleDomain = transformRuleAttributesToRuleDomain(attributes as RuleAttributes, { + id, + logger: context.logger, + ruleType, + references, + omitGeneratedValues: false, + }); + try { + ruleDomainSchema.validate(ruleDomain); + } catch (e) { + context.logger.warn(`Error validating bulk edited rule domain object for id: ${id}, ${e}`); + } + return ruleDomain; + }); + + // TODO (http-versioning): This should be of type Rule, change this when all rule types are fixed + const publicRules = updatedRules.map((rule: RuleDomain) => { + return transformRuleDomainToRule(rule); + }) as Array>; + + await bulkUpdateSchedules(context, options.operations, updatedRules); + + return { rules: publicRules, skipped, errors, total }; +} + +async function bulkEditRulesOcc( + context: RulesClientContext, + { + filter, + operations, + paramsModifier, + shouldIncrementRevision, + }: { + filter: KueryNode | null; + operations: BulkEditOperation[]; + paramsModifier?: ParamsModifier; + shouldIncrementRevision?: ShouldIncrementRevision; + } +): Promise<{ + apiKeysToInvalidate: string[]; + rules: Array>; + resultSavedObjects: Array>; + errors: BulkOperationError[]; + skipped: BulkActionSkipResult[]; +}> { + const rulesFinder = + await context.encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( + { + filter, + type: 'alert', + perPage: 100, + ...(context.namespace ? { namespaces: [context.namespace] } : undefined), + } + ); + + const rules: Array> = []; + const skipped: BulkActionSkipResult[] = []; + const errors: BulkOperationError[] = []; + const apiKeysMap: ApiKeysMap = new Map(); + const username = await context.getUserName(); + + for await (const response of rulesFinder.find()) { + await pMap( + response.saved_objects, + async (rule: SavedObjectsFindResult) => + updateRuleAttributesAndParamsInMemory({ + context, + rule, + operations, + paramsModifier, + apiKeysMap, + rules, + skipped, + errors, + username, + shouldIncrementRevision, + }), + { concurrency: API_KEY_GENERATE_CONCURRENCY } + ); + } + await rulesFinder.close(); + + const { result, apiKeysToInvalidate } = + rules.length > 0 + ? await saveBulkUpdatedRules(context, rules, apiKeysMap) + : { + result: { saved_objects: [] }, + apiKeysToInvalidate: [], + }; + + return { + apiKeysToInvalidate, + resultSavedObjects: result.saved_objects, + errors, + rules, + skipped, + }; +} + +async function bulkUpdateSchedules( + context: RulesClientContext, + operations: BulkEditOperation[], + updatedRules: Array> +): Promise { + const scheduleOperation = operations.find( + ( + operation + ): operation is Extract }> => + operation.field === 'schedule' + ); + + if (!scheduleOperation?.value) { + return; + } + const taskIds = updatedRules.reduce((acc, rule) => { + if (rule.scheduledTaskId) { + acc.push(rule.scheduledTaskId); + } + return acc; + }, []); + + try { + await context.taskManager.bulkUpdateSchedules(taskIds, scheduleOperation.value); + context.logger.debug( + `Successfully updated schedules for underlying tasks: ${taskIds.join(', ')}` + ); + } catch (error) { + context.logger.error( + `Failure to update schedules for underlying tasks: ${taskIds.join( + ', ' + )}. TaskManager bulkUpdateSchedules failed with Error: ${error.message}` + ); + } +} + +async function updateRuleAttributesAndParamsInMemory({ + context, + rule, + operations, + paramsModifier, + apiKeysMap, + rules, + skipped, + errors, + username, + shouldIncrementRevision = () => true, +}: { + context: RulesClientContext; + rule: SavedObjectsFindResult; + operations: BulkEditOperation[]; + paramsModifier?: ParamsModifier; + apiKeysMap: ApiKeysMap; + rules: Array>; + skipped: BulkActionSkipResult[]; + errors: BulkOperationError[]; + username: string | null; + shouldIncrementRevision?: ShouldIncrementRevision; +}): Promise { + try { + if (rule.attributes.apiKey) { + apiKeysMap.set(rule.id, { + oldApiKey: rule.attributes.apiKey, + oldApiKeyCreatedByUser: rule.attributes.apiKeyCreatedByUser, + }); + } + + const ruleType = context.ruleTypeRegistry.get(rule.attributes.alertTypeId); + + await ensureAuthorizationForBulkUpdate(context, operations, rule); + + // migrate legacy actions only for SIEM rules + // TODO (http-versioning) Remove RawRuleAction and RawRule casts + const migratedActions = await migrateLegacyActions(context, { + ruleId: rule.id, + actions: rule.attributes.actions as RawRuleAction[], + references: rule.references, + attributes: rule.attributes as RawRule, + }); + + if (migratedActions.hasLegacyActions) { + rule.attributes.actions = migratedActions.resultedActions; + rule.references = migratedActions.resultedReferences; + } + + const ruleActions = injectReferencesIntoActions( + rule.id, + rule.attributes.actions || [], + rule.references || [] + ); + + const ruleDomain: RuleDomain = transformRuleAttributesToRuleDomain( + rule.attributes, + { + id: rule.id, + logger: context.logger, + ruleType: context.ruleTypeRegistry.get(rule.attributes.alertTypeId), + references: rule.references, + } + ); + + const { + rule: updatedRule, + ruleActions: updatedRuleActions, + hasUpdateApiKeyOperation, + isAttributesUpdateSkipped, + } = await getUpdatedAttributesFromOperations({ + context, + operations, + rule: ruleDomain, + ruleActions, + ruleType, + }); + + validateScheduleInterval(context, updatedRule.schedule.interval, ruleType.id, rule.id); + + const { modifiedParams: ruleParams, isParamsUpdateSkipped } = paramsModifier + ? await paramsModifier(updatedRule.params) + : { + modifiedParams: updatedRule.params, + isParamsUpdateSkipped: true, + }; + + // Increment revision if params ended up being modified AND it wasn't already incremented as part of attribute update + if ( + shouldIncrementRevision(ruleParams) && + !isParamsUpdateSkipped && + rule.attributes.revision === updatedRule.revision + ) { + updatedRule.revision += 1; + } + + // If neither attributes nor parameters were updated, mark + // the rule as skipped and continue to the next rule. + if (isAttributesUpdateSkipped && isParamsUpdateSkipped) { + skipped.push({ + id: rule.id, + name: rule.attributes.name, + skip_reason: 'RULE_NOT_MODIFIED', + }); + return; + } + + // validate rule params + const validatedAlertTypeParams = validateRuleTypeParams(ruleParams, ruleType.validate.params); + const validatedMutatedAlertTypeParams = validateMutatedRuleTypeParams( + validatedAlertTypeParams, + rule.attributes.params, + ruleType.validate.params + ); + + const { + actions: rawAlertActions, + references, + params: updatedParams, + } = await extractReferences( + context, + ruleType, + updatedRuleActions as NormalizedAlertActionWithGeneratedValues[], + validatedMutatedAlertTypeParams + ); + + const ruleAttributes = transformRuleDomainToRuleAttributes(updatedRule, { + legacyId: rule.attributes.legacyId, + actionsWithRefs: rawAlertActions, + paramsWithRefs: updatedParams as RuleAttributes['params'], + }); + + const { apiKeyAttributes } = await prepareApiKeys( + context, + rule, + ruleType, + apiKeysMap, + ruleAttributes, + hasUpdateApiKeyOperation, + username + ); + + const { updatedAttributes } = updateAttributes( + context, + ruleAttributes, + apiKeyAttributes, + updatedParams, + rawAlertActions, + username + ); + + rules.push({ + ...rule, + references, + attributes: updatedAttributes, + }); + } catch (error) { + errors.push({ + message: error.message, + rule: { + id: rule.id, + name: rule.attributes?.name, + }, + }); + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.BULK_EDIT, + error, + }) + ); + } +} + +async function ensureAuthorizationForBulkUpdate( + context: RulesClientContext, + operations: BulkEditOperation[], + rule: SavedObjectsFindResult +): Promise { + if (rule.attributes.actions.length === 0) { + return; + } + + for (const operation of operations) { + const { field } = operation; + if (field === 'snoozeSchedule' || field === 'apiKey') { + try { + await context.actionsAuthorization.ensureAuthorized({ operation: 'execute' }); + break; + } catch (error) { + throw Error(`Rule not authorized for bulk ${field} update - ${error.message}`); + } + } + } +} + +async function getUpdatedAttributesFromOperations({ + context, + operations, + rule, + ruleActions, + ruleType, +}: { + context: RulesClientContext; + operations: BulkEditOperation[]; + rule: RuleDomain; + ruleActions: RuleDomain['actions']; + ruleType: RuleType; +}) { + let updatedRule = cloneDeep(rule); + let updatedRuleActions = ruleActions; + let hasUpdateApiKeyOperation = false; + let isAttributesUpdateSkipped = true; + + for (const operation of operations) { + // Check if the update should be skipped for the current action. + // If it should, save the skip reasons in attributesUpdateSkipReasons + // and continue to the next operation before without + // the `isAttributesUpdateSkipped` flag to false. + switch (operation.field) { + case 'actions': { + const updatedOperation = { + ...operation, + value: addGeneratedActionValues(operation.value), + }; + + try { + await validateActions(context, ruleType, { + ...updatedRule, + actions: updatedOperation.value, + }); + } catch (e) { + // If validateActions fails on the first attempt, it may be because of legacy rule-level frequency params + updatedRule = await attemptToMigrateLegacyFrequency( + context, + updatedOperation, + updatedRule, + ruleType + ); + } + + const { modifiedAttributes, isAttributeModified } = applyBulkEditOperation( + updatedOperation, + { + actions: updatedRuleActions, + } + ); + if (isAttributeModified) { + updatedRuleActions = modifiedAttributes.actions; + isAttributesUpdateSkipped = false; + } + + break; + } + case 'snoozeSchedule': { + // Silently skip adding snooze or snooze schedules on security + // rules until we implement snoozing of their rules + if (updatedRule.consumer === AlertConsumers.SIEM) { + // While the rule is technically not updated, we are still marking + // the rule as updated in case of snoozing, until support + // for snoozing is added. + isAttributesUpdateSkipped = false; + break; + } + if (operation.operation === 'set') { + const snoozeAttributes = getBulkSnooze( + updatedRule, + operation.value as RuleSnoozeSchedule + ); + try { + verifySnoozeScheduleLimit(snoozeAttributes.snoozeSchedule); + } catch (error) { + throw Error(`Error updating rule: could not add snooze - ${error.message}`); + } + updatedRule = { + ...updatedRule, + muteAll: snoozeAttributes.muteAll, + snoozeSchedule: snoozeAttributes.snoozeSchedule as RuleDomain['snoozeSchedule'], + }; + } + if (operation.operation === 'delete') { + const idsToDelete = operation.value && [...operation.value]; + if (idsToDelete?.length === 0) { + updatedRule.snoozeSchedule?.forEach((schedule) => { + if (schedule.id) { + idsToDelete.push(schedule.id); + } + }); + } + const snoozeAttributes = getBulkUnsnooze(updatedRule, idsToDelete); + updatedRule = { + ...updatedRule, + muteAll: snoozeAttributes.muteAll, + snoozeSchedule: snoozeAttributes.snoozeSchedule as RuleDomain['snoozeSchedule'], + }; + } + isAttributesUpdateSkipped = false; + break; + } + case 'apiKey': { + hasUpdateApiKeyOperation = true; + isAttributesUpdateSkipped = false; + break; + } + default: { + if (operation.field === 'schedule') { + validateScheduleOperation(operation.value, updatedRule.actions, rule.id); + } + const { modifiedAttributes, isAttributeModified } = applyBulkEditOperation( + operation, + updatedRule + ); + + if (isAttributeModified) { + updatedRule = { + ...updatedRule, + ...modifiedAttributes, + }; + isAttributesUpdateSkipped = false; + } + } + } + // Only increment revision if update wasn't skipped and `operation.field` should result in a revision increment + if ( + !isAttributesUpdateSkipped && + !bulkEditFieldsToExcludeFromRevisionUpdates.has(operation.field) && + rule.revision - updatedRule.revision === 0 + ) { + updatedRule.revision += 1; + } + } + return { + rule: updatedRule, + ruleActions: updatedRuleActions, + hasUpdateApiKeyOperation, + isAttributesUpdateSkipped, + }; +} + +function validateScheduleInterval( + context: RulesClientContext, + scheduleInterval: string, + ruleTypeId: string, + ruleId: string +): void { + if (!scheduleInterval) { + return; + } + const isIntervalInvalid = parseDuration(scheduleInterval) < context.minimumScheduleIntervalInMs; + if (isIntervalInvalid && context.minimumScheduleInterval.enforce) { + throw Error( + `Error updating rule: the interval is less than the allowed minimum interval of ${context.minimumScheduleInterval.value}` + ); + } else if (isIntervalInvalid && !context.minimumScheduleInterval.enforce) { + context.logger.warn( + `Rule schedule interval (${scheduleInterval}) for "${ruleTypeId}" rule type with ID "${ruleId}" is less than the minimum value (${context.minimumScheduleInterval.value}). Running rules at this interval may impact alerting performance. Set "xpack.alerting.rules.minimumScheduleInterval.enforce" to true to prevent such changes.` + ); + } +} + +/** + * Validate that updated schedule interval is not longer than any of the existing action frequencies + * @param schedule Schedule interval that user tries to set + * @param actions Rule actions + */ +function validateScheduleOperation( + schedule: RuleDomain['schedule'], + actions: RuleDomain['actions'], + ruleId: string +): void { + const scheduleInterval = parseDuration(schedule.interval); + const actionsWithInvalidThrottles = []; + + for (const action of actions) { + // check for actions throttled shorter than the rule schedule + if ( + action.frequency?.notifyWhen === ruleNotifyWhen.THROTTLE && + parseDuration(action.frequency.throttle!) < scheduleInterval + ) { + actionsWithInvalidThrottles.push(action); + } + } + + if (actionsWithInvalidThrottles.length > 0) { + throw Error( + `Error updating rule with ID "${ruleId}": the interval ${schedule.interval} is longer than the action frequencies` + ); + } +} + +async function prepareApiKeys( + context: RulesClientContext, + rule: SavedObjectsFindResult, + ruleType: RuleType, + apiKeysMap: ApiKeysMap, + attributes: RuleAttributes, + hasUpdateApiKeyOperation: boolean, + username: string | null +): Promise<{ apiKeyAttributes: ApiKeyAttributes }> { + const apiKeyAttributes = await createNewAPIKeySet(context, { + id: ruleType.id, + ruleName: attributes.name, + username, + shouldUpdateApiKey: attributes.enabled || hasUpdateApiKeyOperation, + errorMessage: 'Error updating rule: could not create API key', + }); + + // collect generated API keys + if (apiKeyAttributes.apiKey) { + apiKeysMap.set(rule.id, { + ...apiKeysMap.get(rule.id), + newApiKey: apiKeyAttributes.apiKey, + newApiKeyCreatedByUser: apiKeyAttributes.apiKeyCreatedByUser, + }); + } + + return { + apiKeyAttributes, + }; +} + +function updateAttributes( + context: RulesClientContext, + attributes: RuleAttributes, + apiKeyAttributes: ApiKeyAttributes, + updatedParams: RuleParams, + rawAlertActions: RuleActionAttributes[], + username: string | null +): { + updatedAttributes: RuleAttributes; +} { + // get notifyWhen + const notifyWhen = getRuleNotifyWhenType( + attributes.notifyWhen ?? null, + attributes.throttle ?? null + ); + + // TODO (http-versioning) Remove casts when updateMeta has been converted + const castedAttributes = attributes as RawRule; + const updatedAttributes = updateMeta(context, { + ...castedAttributes, + ...apiKeyAttributes, + params: updatedParams as RawRule['params'], + actions: rawAlertActions as RawRule['actions'], + notifyWhen, + updatedBy: username, + updatedAt: new Date().toISOString(), + }) as RuleAttributes; + + // add mapped_params + const mappedParams = getMappedParams(updatedParams); + + if (Object.keys(mappedParams).length) { + updatedAttributes.mapped_params = mappedParams; + } + + return { + updatedAttributes, + }; +} + +async function saveBulkUpdatedRules( + context: RulesClientContext, + rules: Array>, + apiKeysMap: ApiKeysMap +) { + const apiKeysToInvalidate: string[] = []; + let result; + try { + // TODO (http-versioning): for whatever reasoning we are using SavedObjectsBulkUpdateObject + // everywhere when it should be SavedObjectsBulkCreateObject. We need to fix it in + // bulk_disable, bulk_enable, etc. to fix this cast + result = await bulkCreateRulesSo({ + savedObjectsClient: context.unsecuredSavedObjectsClient, + bulkCreateRuleAttributes: rules as Array>, + savedObjectsBulkCreateOptions: { overwrite: true }, + }); + } catch (e) { + // avoid unused newly generated API keys + if (apiKeysMap.size > 0) { + await bulkMarkApiKeysForInvalidation( + { + apiKeys: Array.from(apiKeysMap.values()) + .filter((value) => value.newApiKey && !value.newApiKeyCreatedByUser) + .map((value) => value.newApiKey as string), + }, + context.logger, + context.unsecuredSavedObjectsClient + ); + } + throw e; + } + + result.saved_objects.map(({ id, error }) => { + const oldApiKey = apiKeysMap.get(id)?.oldApiKey; + const oldApiKeyCreatedByUser = apiKeysMap.get(id)?.oldApiKeyCreatedByUser; + const newApiKey = apiKeysMap.get(id)?.newApiKey; + const newApiKeyCreatedByUser = apiKeysMap.get(id)?.newApiKeyCreatedByUser; + + // if SO wasn't saved and has new API key it will be invalidated + if (error && newApiKey && !newApiKeyCreatedByUser) { + apiKeysToInvalidate.push(newApiKey); + // if SO saved and has old Api Key it will be invalidate + } else if (!error && oldApiKey && !oldApiKeyCreatedByUser) { + apiKeysToInvalidate.push(oldApiKey); + } + }); + + return { result, apiKeysToInvalidate }; +} + +async function attemptToMigrateLegacyFrequency( + context: RulesClientContext, + operation: BulkEditOperation, + rule: RuleDomain, + ruleType: RuleType +) { + if (operation.field !== 'actions') + throw new Error('Can only perform frequency migration on an action operation'); + // Try to remove the rule-level frequency params, and then validate actions + if (typeof rule.notifyWhen !== 'undefined') rule.notifyWhen = undefined; + if (rule.throttle) rule.throttle = undefined; + await validateActions(context, ruleType, { + ...rule, + actions: operation.value, + }); + return rule; +} diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/index.ts new file mode 100644 index 0000000000000..e470e73eb3dba --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { BulkEditRuleSnoozeSchedule, BulkEditOperation } from './types'; +export { bulkEditRules } from './bulk_edit_rules'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/schemas/bulk_edit_rules_option_schemas.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/schemas/bulk_edit_rules_option_schemas.ts new file mode 100644 index 0000000000000..f80d63210cf4a --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/schemas/bulk_edit_rules_option_schemas.ts @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { schema } from '@kbn/config-schema'; +import { rRuleRequestSchema } from '../../../../r_rule/schemas'; +import { notifyWhenSchema } from '../../../schemas'; +import { validateDuration } from '../../../validation'; +import { validateSnoozeSchedule } from '../validation'; + +export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); + +export const bulkEditRuleSnoozeScheduleSchema = schema.object({ + id: schema.maybe(schema.string()), + duration: schema.number(), + rRule: rRuleRequestSchema, +}); +const bulkEditRuleSnoozeScheduleSchemaWithValidation = schema.object( + { + id: schema.maybe(schema.string()), + duration: schema.number(), + rRule: rRuleRequestSchema, + }, + { validate: validateSnoozeSchedule } +); + +const bulkEditActionSchema = schema.object({ + group: schema.string(), + id: schema.string(), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + uuid: schema.maybe(schema.string()), + frequency: schema.maybe( + schema.object({ + summary: schema.boolean(), + throttle: schema.nullable(schema.string()), + notifyWhen: notifyWhenSchema, + }) + ), +}); + +const bulkEditTagSchema = schema.object({ + operation: schema.oneOf([schema.literal('add'), schema.literal('delete'), schema.literal('set')]), + field: schema.literal('tags'), + value: schema.arrayOf(schema.string()), +}); + +const bulkEditActionsSchema = schema.object({ + operation: schema.oneOf([schema.literal('add'), schema.literal('set')]), + field: schema.literal('actions'), + value: schema.arrayOf(bulkEditActionSchema), +}); + +const bulkEditScheduleSchema = schema.object({ + operation: schema.literal('set'), + field: schema.literal('schedule'), + value: schema.object({ interval: schema.string({ validate: validateDuration }) }), +}); + +const bulkEditThrottleSchema = schema.object({ + operation: schema.literal('set'), + field: schema.literal('throttle'), + value: schema.nullable(schema.string()), +}); + +const bulkEditNotifyWhenSchema = schema.object({ + operation: schema.literal('set'), + field: schema.literal('notifyWhen'), + value: notifyWhenSchema, +}); + +const bulkEditSnoozeSchema = schema.object({ + operation: schema.oneOf([schema.literal('set')]), + field: schema.literal('snoozeSchedule'), + value: bulkEditRuleSnoozeScheduleSchemaWithValidation, +}); + +const bulkEditUnsnoozeSchema = schema.object({ + operation: schema.oneOf([schema.literal('delete')]), + field: schema.literal('snoozeSchedule'), + value: schema.maybe(scheduleIdsSchema), +}); + +const bulkEditApiKeySchema = schema.object({ + operation: schema.literal('set'), + field: schema.literal('apiKey'), +}); + +export const bulkEditOperationSchema = schema.oneOf([ + bulkEditTagSchema, + bulkEditActionsSchema, + bulkEditScheduleSchema, + bulkEditThrottleSchema, + bulkEditNotifyWhenSchema, + bulkEditSnoozeSchema, + bulkEditUnsnoozeSchema, + bulkEditApiKeySchema, +]); + +export const bulkEditOperationsSchema = schema.arrayOf(bulkEditOperationSchema, { minSize: 1 }); diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/metadata.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/schemas/index.ts similarity index 63% rename from x-pack/plugins/reporting/server/export_types/csv_searchsource/metadata.ts rename to x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/schemas/index.ts index 187d64d872a9d..9ebceff7a0283 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/metadata.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/schemas/index.ts @@ -5,9 +5,8 @@ * 2.0. */ -import { CSV_JOB_TYPE } from '../../../common/constants'; - -export const metadata = { - id: 'csv_searchsource', - name: CSV_JOB_TYPE, -}; +export { + bulkEditRuleSnoozeScheduleSchema, + bulkEditOperationsSchema, + bulkEditOperationSchema, +} from './bulk_edit_rules_option_schemas'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts new file mode 100644 index 0000000000000..a74b7fe152069 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TypeOf } from '@kbn/config-schema'; +import { KueryNode } from '@kbn/es-query'; +import { + bulkEditRuleSnoozeScheduleSchema, + bulkEditOperationsSchema, + bulkEditOperationSchema, +} from '../schemas'; +import { RuleParams, RuleDomain, Rule } from '../../../types'; + +export type BulkEditRuleSnoozeSchedule = TypeOf; +export type BulkEditOperation = TypeOf; +export type BulkEditOperations = TypeOf; + +export type ParamsModifier = ( + params: Params +) => Promise>; + +interface ParamsModifierResult { + modifiedParams: Params; + isParamsUpdateSkipped: boolean; +} + +export type ShouldIncrementRevision = (params?: Params) => boolean; + +export type BulkEditFields = keyof Pick< + RuleDomain, + 'actions' | 'tags' | 'schedule' | 'throttle' | 'notifyWhen' | 'snoozeSchedule' | 'apiKey' +>; + +export interface BulkEditOptionsCommon { + operations: BulkEditOperation[]; + paramsModifier?: ParamsModifier; + shouldIncrementRevision?: ShouldIncrementRevision; +} + +export type BulkEditOptionsFilter = BulkEditOptionsCommon & { + filter?: string | KueryNode; +}; + +export type BulkEditOptionsIds = BulkEditOptionsCommon & { + ids: string[]; +}; + +export type BulkEditSkipReason = 'RULE_NOT_MODIFIED'; + +export interface BulkActionSkipResult { + id: Rule['id']; + name?: Rule['name']; + skip_reason: BulkEditSkipReason; +} + +export interface BulkOperationError { + message: string; + status?: number; + rule: { + id: string; + name: string; + }; +} diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/index.ts new file mode 100644 index 0000000000000..100e29880ef40 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/index.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. + */ + +export type { + BulkEditRuleSnoozeSchedule, + BulkEditOperation, + BulkEditOperations, + BulkEditFields, + BulkEditOptionsFilter, + BulkEditOptionsIds, + BulkActionSkipResult, + BulkEditOptionsCommon, + BulkOperationError, + ParamsModifier, + ShouldIncrementRevision, +} from './bulk_edit_rules_options'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/validation/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/validation/index.ts new file mode 100644 index 0000000000000..243daccc5a15a --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/validation/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 { validateSnoozeSchedule } from './validate_snooze_schedule'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/validation/validate_snooze_schedule.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/validation/validate_snooze_schedule.ts new file mode 100644 index 0000000000000..16fd324cfcb7c --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/validation/validate_snooze_schedule.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Frequency } from '@kbn/rrule'; +import moment from 'moment'; +import { BulkEditRuleSnoozeSchedule } from '../types'; + +export const validateSnoozeSchedule = (schedule: BulkEditRuleSnoozeSchedule) => { + const intervalIsDaily = schedule.rRule.freq === Frequency.DAILY; + const durationInDays = moment.duration(schedule.duration, 'milliseconds').asDays(); + if (intervalIsDaily && schedule.rRule.interval && durationInDays >= schedule.rRule.interval) { + return 'Recurrence interval must be longer than the snooze duration'; + } +}; diff --git a/x-pack/plugins/alerting/server/application/rule/create/create_rule.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.test.ts similarity index 99% rename from x-pack/plugins/alerting/server/application/rule/create/create_rule.test.ts rename to x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.test.ts index e8779face1e8a..b0c20db945b0e 100644 --- a/x-pack/plugins/alerting/server/application/rule/create/create_rule.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.test.ts @@ -7,24 +7,24 @@ import { schema } from '@kbn/config-schema'; import { CreateRuleParams } from './create_rule'; -import { RulesClient, ConstructorOptions } from '../../../rules_client'; +import { RulesClient, ConstructorOptions } from '../../../../rules_client'; import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; -import { ruleTypeRegistryMock } from '../../../rule_type_registry.mock'; -import { alertingAuthorizationMock } from '../../../authorization/alerting_authorization.mock'; +import { ruleTypeRegistryMock } from '../../../../rule_type_registry.mock'; +import { alertingAuthorizationMock } from '../../../../authorization/alerting_authorization.mock'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; -import { AlertingAuthorization } from '../../../authorization/alerting_authorization'; +import { AlertingAuthorization } from '../../../../authorization/alerting_authorization'; import { ActionsAuthorization, ActionsClient } from '@kbn/actions-plugin/server'; -import { ruleNotifyWhen } from '../constants'; +import { ruleNotifyWhen } from '../../constants'; import { TaskStatus } from '@kbn/task-manager-plugin/server'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; -import { getBeforeSetup, setGlobalDate } from '../../../rules_client/tests/lib'; -import { RecoveredActionGroup } from '../../../../common'; -import { bulkMarkApiKeysForInvalidation } from '../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; -import { getRuleExecutionStatusPending, getDefaultMonitoring } from '../../../lib'; +import { getBeforeSetup, setGlobalDate } from '../../../../rules_client/tests/lib'; +import { RecoveredActionGroup } from '../../../../../common'; +import { bulkMarkApiKeysForInvalidation } from '../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; +import { getRuleExecutionStatusPending, getDefaultMonitoring } from '../../../../lib'; -jest.mock('../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ +jest.mock('../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ bulkMarkApiKeysForInvalidation: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/application/rule/create/create_rule.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.ts similarity index 81% rename from x-pack/plugins/alerting/server/application/rule/create/create_rule.ts rename to x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.ts index 89dea65bbe85a..ddd6691a635a3 100644 --- a/x-pack/plugins/alerting/server/application/rule/create/create_rule.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.ts @@ -8,30 +8,34 @@ import Semver from 'semver'; import Boom from '@hapi/boom'; import { SavedObject, SavedObjectsUtils } from '@kbn/core/server'; import { withSpan } from '@kbn/apm-utils'; -import { parseDuration } from '../../../../common/parse_duration'; -import { WriteOperations, AlertingAuthorizationEntity } from '../../../authorization'; -import { validateRuleTypeParams, getRuleNotifyWhenType, getDefaultMonitoring } from '../../../lib'; -import { getRuleExecutionStatusPending } from '../../../lib/rule_execution_status'; +import { parseDuration } from '../../../../../common/parse_duration'; +import { WriteOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { + validateRuleTypeParams, + getRuleNotifyWhenType, + getDefaultMonitoringRuleDomainProperties, +} from '../../../../lib'; +import { getRuleExecutionStatusPending } from '../../../../lib/rule_execution_status'; import { extractReferences, validateActions, addGeneratedActionValues, -} from '../../../rules_client/lib'; -import { generateAPIKeyName, apiKeyAsAlertAttributes } from '../../../rules_client/common'; -import { ruleAuditEvent, RuleAuditAction } from '../../../rules_client/common/audit_events'; -import { RulesClientContext } from '../../../rules_client/types'; -import { Rule, RuleDomain, RuleParams } from '../types'; -import { SanitizedRule } from '../../../types'; +} from '../../../../rules_client/lib'; +import { generateAPIKeyName, apiKeyAsRuleDomainProperties } from '../../../../rules_client/common'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { RulesClientContext } from '../../../../rules_client/types'; +import { RuleDomain, RuleParams } from '../../types'; +import { SanitizedRule } from '../../../../types'; import { transformRuleAttributesToRuleDomain, transformRuleDomainToRuleAttributes, transformRuleDomainToRule, -} from '../transforms'; -import { ruleDomainSchema } from '../schemas'; -import { RuleAttributes } from '../../../data/rule/types'; +} from '../../transforms'; +import { ruleDomainSchema } from '../../schemas'; +import { RuleAttributes } from '../../../../data/rule/types'; import type { CreateRuleData } from './types'; import { createRuleDataSchema } from './schemas'; -import { createRuleSavedObject } from '../../../rules_client/lib'; +import { createRuleSavedObject } from '../../../../rules_client/lib'; export interface CreateRuleOptions { id?: string; @@ -142,7 +146,9 @@ export async function createRule( const ruleAttributes = transformRuleDomainToRuleAttributes( { ...data, - ...apiKeyAsAlertAttributes(createdAPIKey, username, isAuthTypeApiKey), + // TODO (http-versioning) create a rule domain version of this function + // Right now this works because the 2 types can interop but it's not ideal + ...apiKeyAsRuleDomainProperties(createdAPIKey, username, isAuthTypeApiKey), id, createdBy: username, updatedBy: username, @@ -154,13 +160,13 @@ export async function createRule( notifyWhen, throttle, executionStatus: getRuleExecutionStatusPending(lastRunTimestamp.toISOString()), - monitoring: getDefaultMonitoring(lastRunTimestamp.toISOString()) as Rule['monitoring'], + monitoring: getDefaultMonitoringRuleDomainProperties(lastRunTimestamp.toISOString()), revision: 0, running: false, }, { legacyId, - actionsWithRefs: actions as RuleAttributes['actions'], + actionsWithRefs: actions, paramsWithRefs: updatedParams, } ); @@ -193,7 +199,7 @@ export async function createRule( try { ruleDomainSchema.validate(ruleDomain); } catch (e) { - context.logger.warn(`Error validating rule domain object for id: ${id}, ${e}`); + context.logger.warn(`Error validating created rule domain object for id: ${id}, ${e}`); } // Convert domain rule to rule (Remove certain properties) diff --git a/x-pack/plugins/alerting/server/application/rule/create/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/index.ts similarity index 100% rename from x-pack/plugins/alerting/server/application/rule/create/index.ts rename to x-pack/plugins/alerting/server/application/rule/methods/create/index.ts diff --git a/x-pack/plugins/alerting/server/application/rule/create/schemas/create_rule_data_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts similarity index 94% rename from x-pack/plugins/alerting/server/application/rule/create/schemas/create_rule_data_schema.ts rename to x-pack/plugins/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts index da19c3fdde7d7..ce51e88c5ce73 100644 --- a/x-pack/plugins/alerting/server/application/rule/create/schemas/create_rule_data_schema.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts @@ -6,8 +6,8 @@ */ import { schema } from '@kbn/config-schema'; -import { validateDuration } from '../../../../../common/routes/rule/validation'; -import { notifyWhenSchema, actionAlertsFilterSchema } from '../../schemas'; +import { validateDuration } from '../../../validation'; +import { notifyWhenSchema, actionAlertsFilterSchema } from '../../../schemas'; export const createRuleDataSchema = schema.object({ name: schema.string(), diff --git a/x-pack/plugins/alerting/server/application/rule/create/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/schemas/index.ts similarity index 100% rename from x-pack/plugins/alerting/server/application/rule/create/schemas/index.ts rename to x-pack/plugins/alerting/server/application/rule/methods/create/schemas/index.ts diff --git a/x-pack/plugins/alerting/server/application/rule/create/types/create_rule_data.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/types/create_rule_data.ts similarity index 95% rename from x-pack/plugins/alerting/server/application/rule/create/types/create_rule_data.ts rename to x-pack/plugins/alerting/server/application/rule/methods/create/types/create_rule_data.ts index d1caf4b47260a..e75cbb5456c22 100644 --- a/x-pack/plugins/alerting/server/application/rule/create/types/create_rule_data.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/types/create_rule_data.ts @@ -7,7 +7,7 @@ import { TypeOf } from '@kbn/config-schema'; import { createRuleDataSchema } from '../schemas'; -import { RuleParams } from '../../types'; +import { RuleParams } from '../../../types'; type CreateRuleDataType = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/rule/create/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/types/index.ts similarity index 100% rename from x-pack/plugins/alerting/server/application/rule/create/types/index.ts rename to x-pack/plugins/alerting/server/application/rule/methods/create/types/index.ts diff --git a/x-pack/plugins/alerting/server/application/rule/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/schemas/index.ts index 5b366be10f817..50cecadfe4a71 100644 --- a/x-pack/plugins/alerting/server/application/rule/schemas/index.ts +++ b/x-pack/plugins/alerting/server/application/rule/schemas/index.ts @@ -7,7 +7,6 @@ export { ruleParamsSchema, - rRuleSchema, snoozeScheduleSchema, ruleExecutionStatusSchema, ruleLastRunSchema, diff --git a/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts b/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts index 8c6312ce42bed..07efe4793b562 100644 --- a/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts +++ b/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts @@ -12,6 +12,7 @@ import { ruleExecutionStatusErrorReason, ruleExecutionStatusWarningReason, } from '../constants'; +import { rRuleSchema } from '../../r_rule/schemas'; import { dateSchema } from './date_schema'; import { notifyWhenSchema } from './notify_when_schema'; import { actionDomainSchema, actionSchema } from './action_schemas'; @@ -122,45 +123,6 @@ export const monitoringSchema = schema.object({ }), }); -export const rRuleSchema = schema.object({ - dtstart: schema.string(), - tzid: schema.string(), - freq: schema.maybe( - schema.oneOf([ - schema.literal(0), - schema.literal(1), - schema.literal(2), - schema.literal(3), - schema.literal(4), - schema.literal(5), - schema.literal(6), - ]) - ), - until: schema.maybe(schema.string()), - count: schema.maybe(schema.number()), - interval: schema.maybe(schema.number()), - wkst: schema.maybe( - schema.oneOf([ - schema.literal('MO'), - schema.literal('TU'), - schema.literal('WE'), - schema.literal('TH'), - schema.literal('FR'), - schema.literal('SA'), - schema.literal('SU'), - ]) - ), - byweekday: schema.maybe(schema.arrayOf(schema.oneOf([schema.string(), schema.number()]))), - bymonth: schema.maybe(schema.arrayOf(schema.number())), - bysetpos: schema.maybe(schema.arrayOf(schema.number())), - bymonthday: schema.arrayOf(schema.number()), - byyearday: schema.arrayOf(schema.number()), - byweekno: schema.arrayOf(schema.number()), - byhour: schema.arrayOf(schema.number()), - byminute: schema.arrayOf(schema.number()), - bysecond: schema.arrayOf(schema.number()), -}); - export const snoozeScheduleSchema = schema.object({ duration: schema.number(), rRule: rRuleSchema, diff --git a/x-pack/plugins/alerting/server/application/rule/types/index.ts b/x-pack/plugins/alerting/server/application/rule/types/index.ts index f27a0ad9f2813..21c0935e08a7a 100644 --- a/x-pack/plugins/alerting/server/application/rule/types/index.ts +++ b/x-pack/plugins/alerting/server/application/rule/types/index.ts @@ -5,4 +5,12 @@ * 2.0. */ -export type { Rule, RuleDomain, RuleLastRun, Monitoring, RuleParams, RuleNotifyWhen } from './rule'; +export type { + Rule, + RuleDomain, + RuleLastRun, + Monitoring, + RuleParams, + RuleNotifyWhen, + RuleSnoozeSchedule, +} from './rule'; diff --git a/x-pack/plugins/alerting/server/application/rule/types/rule.ts b/x-pack/plugins/alerting/server/application/rule/types/rule.ts index fe81ed156e9bf..04e37a125aa40 100644 --- a/x-pack/plugins/alerting/server/application/rule/types/rule.ts +++ b/x-pack/plugins/alerting/server/application/rule/types/rule.ts @@ -15,7 +15,6 @@ import { } from '../constants'; import { ruleParamsSchema, - rRuleSchema, snoozeScheduleSchema, ruleExecutionStatusSchema, ruleLastRunSchema, @@ -36,8 +35,7 @@ export type RuleExecutionStatusWarningReason = typeof ruleExecutionStatusWarningReason[keyof typeof ruleExecutionStatusWarningReason]; export type RuleParams = TypeOf; -export type RRule = TypeOf; -export type SnoozeSchedule = TypeOf; +export type RuleSnoozeSchedule = TypeOf; export type RuleLastRun = TypeOf; export type Monitoring = TypeOf; export type Action = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/rule/validation/index.ts b/x-pack/plugins/alerting/server/application/rule/validation/index.ts new file mode 100644 index 0000000000000..4bb530eb39f99 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/validation/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 { validateDuration } from './validate_duration'; diff --git a/x-pack/plugins/alerting/server/application/rule/validation/validate_duration.ts b/x-pack/plugins/alerting/server/application/rule/validation/validate_duration.ts new file mode 100644 index 0000000000000..d07d710687cc0 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/validation/validate_duration.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. + */ + +const SECONDS_REGEX = /^[1-9][0-9]*s$/; +const MINUTES_REGEX = /^[1-9][0-9]*m$/; +const HOURS_REGEX = /^[1-9][0-9]*h$/; +const DAYS_REGEX = /^[1-9][0-9]*d$/; + +export function validateDuration(duration: string) { + if (duration.match(SECONDS_REGEX)) { + return; + } + if (duration.match(MINUTES_REGEX)) { + return; + } + if (duration.match(HOURS_REGEX)) { + return; + } + if (duration.match(DAYS_REGEX)) { + return; + } + return 'string is not a valid duration: ' + duration; +} diff --git a/x-pack/plugins/alerting/server/data/rule/index.ts b/x-pack/plugins/alerting/server/data/rule/index.ts index 295ede18c8f9a..6256ac9b2278a 100644 --- a/x-pack/plugins/alerting/server/data/rule/index.ts +++ b/x-pack/plugins/alerting/server/data/rule/index.ts @@ -5,9 +5,13 @@ * 2.0. */ -export { createRuleSo } from './create_rule_so'; -export type { CreateRuleSoParams } from './create_rule_so'; -export { updateRuleSo } from './update_rule_so'; -export type { UpdateRuleSoParams } from './update_rule_so'; -export { deleteRuleSo } from './delete_rule_so'; -export type { DeleteRuleSoParams } from './delete_rule_so'; +export { createRuleSo } from './methods/create_rule_so'; +export type { CreateRuleSoParams } from './methods/create_rule_so'; +export { updateRuleSo } from './methods/update_rule_so'; +export type { UpdateRuleSoParams } from './methods/update_rule_so'; +export { deleteRuleSo } from './methods/delete_rule_so'; +export type { DeleteRuleSoParams } from './methods/delete_rule_so'; +export { findRulesSo } from './methods/find_rules_so'; +export type { FindRulesSoParams } from './methods/find_rules_so'; +export { bulkCreateRulesSo } from './methods/bulk_create_rule_so'; +export type { BulkCreateRulesSoParams } from './methods/bulk_create_rule_so'; diff --git a/x-pack/plugins/alerting/server/data/rule/methods/bulk_create_rule_so.ts b/x-pack/plugins/alerting/server/data/rule/methods/bulk_create_rule_so.ts new file mode 100644 index 0000000000000..6bc0ee04b394d --- /dev/null +++ b/x-pack/plugins/alerting/server/data/rule/methods/bulk_create_rule_so.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + SavedObjectsClientContract, + SavedObjectsCreateOptions, + SavedObjectsBulkCreateObject, + SavedObjectsBulkResponse, +} from '@kbn/core/server'; +import { RuleAttributes } from '../types'; + +export interface BulkCreateRulesSoParams { + savedObjectsClient: SavedObjectsClientContract; + bulkCreateRuleAttributes: Array>; + savedObjectsBulkCreateOptions?: SavedObjectsCreateOptions; +} + +export const bulkCreateRulesSo = ( + params: BulkCreateRulesSoParams +): Promise> => { + const { savedObjectsClient, bulkCreateRuleAttributes, savedObjectsBulkCreateOptions } = params; + + return savedObjectsClient.bulkCreate( + bulkCreateRuleAttributes, + savedObjectsBulkCreateOptions + ); +}; diff --git a/x-pack/plugins/alerting/server/data/rule/create_rule_so.ts b/x-pack/plugins/alerting/server/data/rule/methods/create_rule_so.ts similarity index 62% rename from x-pack/plugins/alerting/server/data/rule/create_rule_so.ts rename to x-pack/plugins/alerting/server/data/rule/methods/create_rule_so.ts index a9670c8a46d25..7574e9aca1608 100644 --- a/x-pack/plugins/alerting/server/data/rule/create_rule_so.ts +++ b/x-pack/plugins/alerting/server/data/rule/methods/create_rule_so.ts @@ -10,16 +10,16 @@ import { SavedObjectsCreateOptions, SavedObject, } from '@kbn/core/server'; -import { RuleAttributes } from './types'; +import { RuleAttributes } from '../types'; export interface CreateRuleSoParams { - savedObjectClient: SavedObjectsClientContract; + savedObjectsClient: SavedObjectsClientContract; ruleAttributes: RuleAttributes; - savedObjectCreateOptions?: SavedObjectsCreateOptions; + savedObjectsCreateOptions?: SavedObjectsCreateOptions; } export const createRuleSo = (params: CreateRuleSoParams): Promise> => { - const { savedObjectClient, ruleAttributes, savedObjectCreateOptions } = params; + const { savedObjectsClient, ruleAttributes, savedObjectsCreateOptions } = params; - return savedObjectClient.create('alert', ruleAttributes, savedObjectCreateOptions); + return savedObjectsClient.create('alert', ruleAttributes, savedObjectsCreateOptions); }; diff --git a/x-pack/plugins/alerting/server/data/rule/delete_rule_so.ts b/x-pack/plugins/alerting/server/data/rule/methods/delete_rule_so.ts similarity index 65% rename from x-pack/plugins/alerting/server/data/rule/delete_rule_so.ts rename to x-pack/plugins/alerting/server/data/rule/methods/delete_rule_so.ts index 26af10436ede3..e3428cfc78f63 100644 --- a/x-pack/plugins/alerting/server/data/rule/delete_rule_so.ts +++ b/x-pack/plugins/alerting/server/data/rule/methods/delete_rule_so.ts @@ -8,13 +8,13 @@ import { SavedObjectsClientContract, SavedObjectsDeleteOptions } from '@kbn/core/server'; export interface DeleteRuleSoParams { - savedObjectClient: SavedObjectsClientContract; + savedObjectsClient: SavedObjectsClientContract; id: string; - savedObjectDeleteOptions?: SavedObjectsDeleteOptions; + savedObjectsDeleteOptions?: SavedObjectsDeleteOptions; } export const deleteRuleSo = (params: DeleteRuleSoParams): Promise<{}> => { - const { savedObjectClient, id, savedObjectDeleteOptions } = params; + const { savedObjectsClient, id, savedObjectsDeleteOptions } = params; - return savedObjectClient.delete('alert', id, savedObjectDeleteOptions); + return savedObjectsClient.delete('alert', id, savedObjectsDeleteOptions); }; diff --git a/x-pack/plugins/alerting/server/data/rule/methods/find_rules_so.ts b/x-pack/plugins/alerting/server/data/rule/methods/find_rules_so.ts new file mode 100644 index 0000000000000..1362c2406dbae --- /dev/null +++ b/x-pack/plugins/alerting/server/data/rule/methods/find_rules_so.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + SavedObjectsClientContract, + SavedObjectsFindOptions, + SavedObjectsFindResponse, +} from '@kbn/core/server'; +import { RuleAttributes } from '../types'; + +export interface FindRulesSoParams { + savedObjectsClient: SavedObjectsClientContract; + savedObjectsFindOptions: Omit; +} + +export const findRulesSo = >( + params: FindRulesSoParams +): Promise> => { + const { savedObjectsClient, savedObjectsFindOptions } = params; + + return savedObjectsClient.find({ + ...savedObjectsFindOptions, + type: 'alert', + }); +}; diff --git a/x-pack/plugins/alerting/server/data/rule/update_rule_so.ts b/x-pack/plugins/alerting/server/data/rule/methods/update_rule_so.ts similarity index 65% rename from x-pack/plugins/alerting/server/data/rule/update_rule_so.ts rename to x-pack/plugins/alerting/server/data/rule/methods/update_rule_so.ts index 7d68e21412f5b..8739202c237ea 100644 --- a/x-pack/plugins/alerting/server/data/rule/update_rule_so.ts +++ b/x-pack/plugins/alerting/server/data/rule/methods/update_rule_so.ts @@ -10,24 +10,24 @@ import { SavedObjectsUpdateOptions, SavedObjectsUpdateResponse, } from '@kbn/core/server'; -import { RuleAttributes } from './types'; +import { RuleAttributes } from '../types'; export interface UpdateRuleSoParams { - savedObjectClient: SavedObjectsClientContract; + savedObjectsClient: SavedObjectsClientContract; id: string; updateRuleAttributes: Partial; - savedObjectUpdateOptions?: SavedObjectsUpdateOptions; + savedObjectsUpdateOptions?: SavedObjectsUpdateOptions; } export const updateRuleSo = ( params: UpdateRuleSoParams ): Promise> => { - const { savedObjectClient, id, updateRuleAttributes, savedObjectUpdateOptions } = params; + const { savedObjectsClient, id, updateRuleAttributes, savedObjectsUpdateOptions } = params; - return savedObjectClient.update( + return savedObjectsClient.update( 'alert', id, updateRuleAttributes, - savedObjectUpdateOptions + savedObjectsUpdateOptions ); }; diff --git a/x-pack/plugins/alerting/server/data/rule/types/index.ts b/x-pack/plugins/alerting/server/data/rule/types/index.ts index eda48efddd60e..d0eef33f65547 100644 --- a/x-pack/plugins/alerting/server/data/rule/types/index.ts +++ b/x-pack/plugins/alerting/server/data/rule/types/index.ts @@ -8,6 +8,7 @@ export type { RuleNotifyWhenAttributes, RuleLastRunOutcomeValuesAttributes, + RuleActionAttributes, RuleExecutionStatusValuesAttributes, RuleExecutionStatusErrorReasonAttributes, RuleExecutionStatusWarningReasonAttributes, diff --git a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts index 4e2ff63ad8e8c..03ccf7c8a6b0d 100644 --- a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts +++ b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts @@ -144,7 +144,7 @@ interface AlertsFilterAttributes { timeframe?: AlertsFilterTimeFrameAttributes; } -interface RuleActionAttributes { +export interface RuleActionAttributes { uuid: string; group: string; actionRef: string; diff --git a/x-pack/plugins/alerting/server/index.ts b/x-pack/plugins/alerting/server/index.ts index 74deec270826b..263e014fa492c 100644 --- a/x-pack/plugins/alerting/server/index.ts +++ b/x-pack/plugins/alerting/server/index.ts @@ -36,14 +36,7 @@ export type { export { RuleNotifyWhen } from '../common'; export { DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT } from './config'; export type { PluginSetupContract, PluginStartContract } from './plugin'; -export type { - FindResult, - BulkEditOperation, - BulkOperationError, - BulkEditOptions, - BulkEditOptionsFilter, - BulkEditOptionsIds, -} from './rules_client'; +export type { FindResult, BulkEditOperation, BulkOperationError } from './rules_client'; export type { Rule } from './application/rule/types'; export type { PublicAlert as Alert } from './alert'; export { parseDuration, isRuleSnoozed } from './lib'; diff --git a/x-pack/plugins/alerting/server/lib/index.ts b/x-pack/plugins/alerting/server/lib/index.ts index 365b9e5b56747..db28ae5ff5649 100644 --- a/x-pack/plugins/alerting/server/lib/index.ts +++ b/x-pack/plugins/alerting/server/lib/index.ts @@ -31,6 +31,7 @@ export { lastRunFromState, lastRunFromError, lastRunToRaw } from './last_run_sta export { resetMonitoringLastRun, getDefaultMonitoring, + getDefaultMonitoringRuleDomainProperties, convertMonitoringFromRawAndVerify, } from './monitoring'; export { getNextRun } from './next_run'; diff --git a/x-pack/plugins/alerting/server/lib/monitoring.ts b/x-pack/plugins/alerting/server/lib/monitoring.ts index 9224600eeffc7..bff533cfc591f 100644 --- a/x-pack/plugins/alerting/server/lib/monitoring.ts +++ b/x-pack/plugins/alerting/server/lib/monitoring.ts @@ -12,6 +12,7 @@ import { RuleMonitoringHistory, RuleMonitoringLastRunMetrics, } from '../types'; +import { RuleDomain } from '../application/rule/types'; const INITIAL_LAST_RUN_METRICS: RuleMonitoringLastRunMetrics = { duration: 0, @@ -37,6 +38,23 @@ export const getDefaultMonitoring = (timestamp: string): RawRuleMonitoring => { }; }; +export const getDefaultMonitoringRuleDomainProperties = ( + timestamp: string +): RuleDomain['monitoring'] => { + return { + run: { + history: [], + calculated_metrics: { + success_ratio: 0, + }, + last_run: { + timestamp, + metrics: INITIAL_LAST_RUN_METRICS, + }, + }, + }; +}; + export const resetMonitoringLastRun = (monitoring: RuleMonitoring): RawRuleMonitoring => { const { run, ...restMonitoring } = monitoring; const { last_run: lastRun, ...restRun } = run; diff --git a/x-pack/plugins/alerting/server/routes/bulk_edit_rules.ts b/x-pack/plugins/alerting/server/routes/bulk_edit_rules.ts deleted file mode 100644 index f22d7d2055b09..0000000000000 --- a/x-pack/plugins/alerting/server/routes/bulk_edit_rules.ts +++ /dev/null @@ -1,145 +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 { schema } from '@kbn/config-schema'; -import { IRouter } from '@kbn/core/server'; - -import { ILicenseState, RuleTypeDisabledError, validateDurationSchema } from '../lib'; -import { verifyAccessAndContext, rewriteRule, handleDisabledApiKeysError } from './lib'; -import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; -import { snoozeScheduleSchema } from './snooze_rule'; -import { scheduleIdsSchema } from './unsnooze_rule'; - -const ruleActionSchema = schema.object({ - group: schema.string(), - id: schema.string(), - params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - uuid: schema.maybe(schema.string()), - frequency: schema.maybe( - schema.object({ - summary: schema.boolean(), - throttle: schema.nullable(schema.string()), - notifyWhen: schema.oneOf([ - schema.literal('onActionGroupChange'), - schema.literal('onActiveAlert'), - schema.literal('onThrottleInterval'), - ]), - }) - ), -}); - -const operationsSchema = schema.arrayOf( - schema.oneOf([ - schema.object({ - operation: schema.oneOf([ - schema.literal('add'), - schema.literal('delete'), - schema.literal('set'), - ]), - field: schema.literal('tags'), - value: schema.arrayOf(schema.string()), - }), - schema.object({ - operation: schema.oneOf([schema.literal('add'), schema.literal('set')]), - field: schema.literal('actions'), - value: schema.arrayOf(ruleActionSchema), - }), - schema.object({ - operation: schema.literal('set'), - field: schema.literal('schedule'), - value: schema.object({ interval: schema.string({ validate: validateDurationSchema }) }), - }), - schema.object({ - operation: schema.literal('set'), - field: schema.literal('throttle'), - value: schema.nullable(schema.string()), - }), - schema.object({ - operation: schema.literal('set'), - field: schema.literal('notifyWhen'), - value: schema.nullable( - schema.oneOf([ - schema.literal('onActionGroupChange'), - schema.literal('onActiveAlert'), - schema.literal('onThrottleInterval'), - ]) - ), - }), - schema.object({ - operation: schema.oneOf([schema.literal('set')]), - field: schema.literal('snoozeSchedule'), - value: snoozeScheduleSchema, - }), - schema.object({ - operation: schema.oneOf([schema.literal('delete')]), - field: schema.literal('snoozeSchedule'), - value: schema.maybe(scheduleIdsSchema), - }), - schema.object({ - operation: schema.literal('set'), - field: schema.literal('apiKey'), - }), - ]), - { minSize: 1 } -); - -const bodySchema = schema.object({ - filter: schema.maybe(schema.string()), - ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1 })), - operations: operationsSchema, -}); - -interface BuildBulkEditRulesRouteParams { - licenseState: ILicenseState; - path: string; - router: IRouter; -} - -const buildBulkEditRulesRoute = ({ licenseState, path, router }: BuildBulkEditRulesRouteParams) => { - router.post( - { - path, - validate: { - body: bodySchema, - }, - }, - handleDisabledApiKeysError( - router.handleLegacyErrors( - verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); - const { filter, operations, ids } = req.body; - - try { - const bulkEditResults = await rulesClient.bulkEdit({ - filter, - ids: ids as string[], - operations, - }); - return res.ok({ - body: { ...bulkEditResults, rules: bulkEditResults.rules.map(rewriteRule) }, - }); - } catch (e) { - if (e instanceof RuleTypeDisabledError) { - return e.sendResponse(res); - } - throw e; - } - }) - ) - ) - ); -}; - -export const bulkEditInternalRulesRoute = ( - router: IRouter, - licenseState: ILicenseState -) => - buildBulkEditRulesRoute({ - licenseState, - path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/_bulk_edit`, - router, - }); diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index 8d3c1c7ac5079..f9962d72eb772 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -13,7 +13,7 @@ import { Observable } from 'rxjs'; import { ILicenseState } from '../lib'; import { defineLegacyRoutes } from './legacy'; import { AlertingRequestHandlerContext } from '../types'; -import { createRuleRoute } from './rule/create'; +import { createRuleRoute } from './rule/apis/create'; import { getRuleRoute, getInternalRuleRoute } from './get_rule'; import { updateRuleRoute } from './update_rule'; import { deleteRuleRoute } from './delete_rule'; @@ -36,7 +36,7 @@ import { muteAlertRoute } from './mute_alert'; import { unmuteAllRuleRoute } from './unmute_all_rule'; import { unmuteAlertRoute } from './unmute_alert'; import { updateRuleApiKeyRoute } from './update_rule_api_key'; -import { bulkEditInternalRulesRoute } from './bulk_edit_rules'; +import { bulkEditInternalRulesRoute } from './rule/apis/bulk_edit/bulk_edit_rules_route'; import { snoozeRuleRoute } from './snooze_rule'; import { unsnoozeRuleRoute } from './unsnooze_rule'; import { runSoonRoute } from './run_soon'; diff --git a/x-pack/plugins/alerting/server/routes/bulk_edit_rules.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts similarity index 89% rename from x-pack/plugins/alerting/server/routes/bulk_edit_rules.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts index b2819fda6f60f..1b1ed454c5207 100644 --- a/x-pack/plugins/alerting/server/routes/bulk_edit_rules.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.test.ts @@ -7,23 +7,23 @@ import { httpServiceMock } from '@kbn/core/server/mocks'; -import { bulkEditInternalRulesRoute } from './bulk_edit_rules'; -import { licenseStateMock } from '../lib/license_state.mock'; -import { verifyApiAccess } from '../lib/license_api_access'; -import { RuleTypeDisabledError } from '../lib/errors/rule_type_disabled'; -import { mockHandlerArguments } from './_mock_handler_arguments'; -import { rulesClientMock } from '../rules_client.mock'; -import { SanitizedRule } from '../types'; +import { bulkEditInternalRulesRoute } from './bulk_edit_rules_route'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { RuleTypeDisabledError } from '../../../../lib/errors/rule_type_disabled'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { rulesClientMock } from '../../../../rules_client.mock'; +import { SanitizedRule } from '../../../../types'; const rulesClient = rulesClientMock.create(); -jest.mock('../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); beforeEach(() => { jest.resetAllMocks(); }); -describe('bulkEditInternalRulesRoute', () => { +describe('bulkEditRulesRoute', () => { const mockedAlert: SanitizedRule<{}> = { id: '1', alertTypeId: '1', diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts new file mode 100644 index 0000000000000..ae39ceba1ceb3 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IRouter } from '@kbn/core/server'; + +import { ILicenseState, RuleTypeDisabledError } from '../../../../lib'; +import { verifyAccessAndContext, handleDisabledApiKeysError } from '../../../lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../../../../types'; + +import { + bulkEditRulesRequestBodySchemaV1, + BulkEditRulesRequestBodyV1, + BulkEditRulesResponseV1, +} from '../../../../../common/routes/rule/apis/bulk_edit'; +import { Rule } from '../../../../application/rule/types'; +import type { RuleParamsV1 } from '../../../../../common/routes/rule/response'; + +import { transformRuleToRuleResponseV1 } from '../../transforms'; + +interface BuildBulkEditRulesRouteParams { + licenseState: ILicenseState; + path: string; + router: IRouter; +} + +const buildBulkEditRulesRoute = ({ licenseState, path, router }: BuildBulkEditRulesRouteParams) => { + router.post( + { + path, + validate: { + body: bulkEditRulesRequestBodySchemaV1, + }, + }, + handleDisabledApiKeysError( + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const rulesClient = (await context.alerting).getRulesClient(); + const bulkEditData: BulkEditRulesRequestBodyV1 = req.body; + + const { filter, operations, ids } = bulkEditData; + + try { + const bulkEditResults = await rulesClient.bulkEdit({ + filter, + ids, + operations, + }); + + const resultBody: BulkEditRulesResponseV1 = { + body: { + ...bulkEditResults, + rules: bulkEditResults.rules.map((rule) => { + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + return transformRuleToRuleResponseV1(rule as Rule); + }), + }, + }; + return res.ok(resultBody); + } catch (e) { + if (e instanceof RuleTypeDisabledError) { + return e.sendResponse(res); + } + throw e; + } + }) + ) + ) + ); +}; + +export const bulkEditInternalRulesRoute = ( + router: IRouter, + licenseState: ILicenseState +) => + buildBulkEditRulesRoute({ + licenseState, + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/_bulk_edit`, + router, + }); diff --git a/x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts similarity index 97% rename from x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts index 63f4789f1289d..e952a72ec3859 100644 --- a/x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts @@ -8,20 +8,20 @@ import { pick } from 'lodash'; import { createRuleRoute } from './create_rule_route'; import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../../../lib/license_state.mock'; -import { verifyApiAccess } from '../../../lib/license_api_access'; -import { mockHandlerArguments } from '../../_mock_handler_arguments'; -import type { CreateRuleRequestBodyV1 } from '../../../../common/routes/rule/create'; -import { rulesClientMock } from '../../../rules_client.mock'; -import { RuleTypeDisabledError } from '../../../lib'; -import { AsApiContract } from '../../lib'; -import { SanitizedRule } from '../../../types'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import type { CreateRuleRequestBodyV1 } from '../../../../../common/routes/rule/apis/create'; +import { rulesClientMock } from '../../../../rules_client.mock'; +import { RuleTypeDisabledError } from '../../../../lib'; +import { AsApiContract } from '../../../lib'; +import { SanitizedRule } from '../../../../types'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { usageCountersServiceMock } from '@kbn/usage-collection-plugin/server/usage_counters/usage_counters_service.mock'; const rulesClient = rulesClientMock.create(); -jest.mock('../../../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts similarity index 79% rename from x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts index 8f11c2cbc46a0..6b28b64284904 100644 --- a/x-pack/plugins/alerting/server/routes/rule/create/create_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts @@ -5,24 +5,27 @@ * 2.0. */ -import { RuleTypeDisabledError } from '../../../lib'; +import { RuleTypeDisabledError } from '../../../../lib'; import { handleDisabledApiKeysError, verifyAccessAndContext, countUsageOfPredefinedIds, -} from '../../lib'; -import { BASE_ALERTING_API_PATH } from '../../../types'; -import { RouteOptions } from '../..'; +} from '../../../lib'; +import { BASE_ALERTING_API_PATH } from '../../../../types'; +import { RouteOptions } from '../../..'; import type { CreateRuleRequestBodyV1, CreateRuleRequestParamsV1, CreateRuleResponseV1, -} from '../../../../common/routes/rule/create'; -import { createBodySchemaV1, createParamsSchemaV1 } from '../../../../common/routes/rule/create'; -import type { RuleParamsV1 } from '../../../../common/routes/rule/rule_response'; -import { Rule } from '../../../application/rule/types'; +} from '../../../../../common/routes/rule/apis/create'; +import { + createBodySchemaV1, + createParamsSchemaV1, +} from '../../../../../common/routes/rule/apis/create'; +import type { RuleParamsV1 } from '../../../../../common/routes/rule/response'; +import { Rule } from '../../../../application/rule/types'; import { transformCreateBodyV1 } from './transforms'; -import { transformRuleToRuleResponseV1 } from '../transforms'; +import { transformRuleToRuleResponseV1 } from '../../transforms'; export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOptions) => { router.post( diff --git a/x-pack/plugins/alerting/server/routes/rule/create/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/index.ts similarity index 100% rename from x-pack/plugins/alerting/server/routes/rule/create/index.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/create/index.ts diff --git a/x-pack/plugins/alerting/server/routes/rule/create/transforms/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/index.ts similarity index 100% rename from x-pack/plugins/alerting/server/routes/rule/create/transforms/index.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/index.ts diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/latest.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/create/transforms/transform_create_body/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts similarity index 87% rename from x-pack/plugins/alerting/server/routes/rule/create/transforms/transform_create_body/v1.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts index 38c081b2168ce..c6b29f4577f4c 100644 --- a/x-pack/plugins/alerting/server/routes/rule/create/transforms/transform_create_body/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts @@ -8,9 +8,9 @@ import type { CreateRuleActionV1, CreateRuleRequestBodyV1, -} from '../../../../../../common/routes/rule/create'; -import type { CreateRuleData } from '../../../../../application/rule/create'; -import type { RuleParams } from '../../../../../application/rule/types'; +} from '../../../../../../../common/routes/rule/apis/create'; +import type { CreateRuleData } from '../../../../../../application/rule/methods/create'; +import type { RuleParams } from '../../../../../../application/rule/types'; const transformCreateBodyActions = (actions: CreateRuleActionV1[]): CreateRuleData['actions'] => { if (!actions) return []; diff --git a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts index 38e6da6c11429..9c38431f24b9e 100644 --- a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { RuleResponseV1, RuleParamsV1 } from '../../../../../common/routes/rule/rule_response'; +import { RuleResponseV1, RuleParamsV1 } from '../../../../../common/routes/rule/response'; import { Rule, RuleLastRun, RuleParams } from '../../../../application/rule/types'; const transformRuleLastRun = (lastRun: RuleLastRun): RuleResponseV1['last_run'] => { diff --git a/x-pack/plugins/alerting/server/rules_client/common/api_key_as_alert_attributes.ts b/x-pack/plugins/alerting/server/rules_client/common/api_key_as_alert_attributes.ts index 841ffdd1703a7..c1941a8d0fa4b 100644 --- a/x-pack/plugins/alerting/server/rules_client/common/api_key_as_alert_attributes.ts +++ b/x-pack/plugins/alerting/server/rules_client/common/api_key_as_alert_attributes.ts @@ -7,7 +7,12 @@ import { RawRule } from '../../types'; import { CreateAPIKeyResult } from '../types'; +import { RuleDomain } from '../../application/rule/types'; +/** + * @deprecated TODO (http-versioning) make sure this is deprecated + * once all of the RawRules are phased out + */ export function apiKeyAsAlertAttributes( apiKey: CreateAPIKeyResult | null, username: string | null, @@ -25,3 +30,21 @@ export function apiKeyAsAlertAttributes( apiKeyCreatedByUser: null, }; } + +export function apiKeyAsRuleDomainProperties( + apiKey: CreateAPIKeyResult | null, + username: string | null, + createdByUser: boolean +): Pick { + return apiKey && apiKey.apiKeysEnabled + ? { + apiKeyOwner: username, + apiKey: Buffer.from(`${apiKey.result.id}:${apiKey.result.api_key}`).toString('base64'), + apiKeyCreatedByUser: createdByUser, + } + : { + apiKeyOwner: null, + apiKey: null, + apiKeyCreatedByUser: null, + }; +} diff --git a/x-pack/plugins/alerting/server/rules_client/common/apply_bulk_edit_operation.ts b/x-pack/plugins/alerting/server/rules_client/common/apply_bulk_edit_operation.ts index e20624c77b2c5..c718ce0d5fa32 100644 --- a/x-pack/plugins/alerting/server/rules_client/common/apply_bulk_edit_operation.ts +++ b/x-pack/plugins/alerting/server/rules_client/common/apply_bulk_edit_operation.ts @@ -32,7 +32,9 @@ export const applyBulkEditOperation = (operation: BulkEditOper switch (operation.operation) { case 'set': - set(rule, operation.field, operation.value); + if (operation.field !== 'apiKey') { + set(rule, operation.field, operation.value); + } break; case 'add': diff --git a/x-pack/plugins/alerting/server/rules_client/common/index.ts b/x-pack/plugins/alerting/server/rules_client/common/index.ts index ab380a6ca178b..6f8835d0c7260 100644 --- a/x-pack/plugins/alerting/server/rules_client/common/index.ts +++ b/x-pack/plugins/alerting/server/rules_client/common/index.ts @@ -13,7 +13,10 @@ export { applyBulkEditOperation } from './apply_bulk_edit_operation'; export { buildKueryNodeFilter } from './build_kuery_node_filter'; export { generateAPIKeyName } from './generate_api_key_name'; export * from './mapped_params_utils'; -export { apiKeyAsAlertAttributes } from './api_key_as_alert_attributes'; +export { + apiKeyAsAlertAttributes, + apiKeyAsRuleDomainProperties, +} from './api_key_as_alert_attributes'; export * from './inject_references'; export { parseDate } from './parse_date'; export { includeFieldsRequiredForAuthentication } from './include_fields_required_for_authentication'; diff --git a/x-pack/plugins/alerting/server/rules_client/common/inject_references.ts b/x-pack/plugins/alerting/server/rules_client/common/inject_references.ts index 07565240ed5c4..4aa9474c5873c 100644 --- a/x-pack/plugins/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/plugins/alerting/server/rules_client/common/inject_references.ts @@ -10,6 +10,7 @@ import { omit } from 'lodash'; import { SavedObjectReference, SavedObjectAttributes } from '@kbn/core/server'; import { UntypedNormalizedRuleType } from '../../rule_type_registry'; import { Rule, RawRule, RuleTypeParams } from '../../types'; +import { RuleActionAttributes } from '../../data/rule/types'; import { preconfiguredConnectorActionRefPrefix, extractedSavedObjectParamReferenceNamePrefix, @@ -17,7 +18,7 @@ import { export function injectReferencesIntoActions( alertId: string, - actions: RawRule['actions'], + actions: RawRule['actions'] | RuleActionAttributes[], references: SavedObjectReference[] ) { return actions.map((action) => { diff --git a/x-pack/plugins/alerting/server/rules_client/common/retry_if_bulk_edit_conflicts.ts b/x-pack/plugins/alerting/server/rules_client/common/retry_if_bulk_edit_conflicts.ts index 8d03d01df5af4..1a506b1b3fa86 100644 --- a/x-pack/plugins/alerting/server/rules_client/common/retry_if_bulk_edit_conflicts.ts +++ b/x-pack/plugins/alerting/server/rules_client/common/retry_if_bulk_edit_conflicts.ts @@ -12,7 +12,7 @@ import { Logger, SavedObjectsBulkUpdateObject, SavedObjectsUpdateResponse } from import { BulkActionSkipResult } from '../../../common/bulk_edit'; import { convertRuleIdsToKueryNode } from '../../lib'; import { BulkOperationError } from '../types'; -import { RawRule } from '../../types'; +import { RuleAttributes } from '../../data/rule/types'; import { waitBeforeNextRetry, RETRY_IF_CONFLICTS_ATTEMPTS } from './wait_before_next_retry'; // max number of failed SO ids in one retry filter @@ -20,15 +20,15 @@ const MaxIdsNumberInRetryFilter = 1000; type BulkEditOperation = (filter: KueryNode | null) => Promise<{ apiKeysToInvalidate: string[]; - rules: Array>; - resultSavedObjects: Array>; + rules: Array>; + resultSavedObjects: Array>; errors: BulkOperationError[]; skipped: BulkActionSkipResult[]; }>; interface ReturnRetry { apiKeysToInvalidate: string[]; - results: Array>; + results: Array>; errors: BulkOperationError[]; skipped: BulkActionSkipResult[]; } @@ -54,7 +54,7 @@ export const retryIfBulkEditConflicts = async ( filter: KueryNode | null, retries: number = RETRY_IF_CONFLICTS_ATTEMPTS, accApiKeysToInvalidate: string[] = [], - accResults: Array> = [], + accResults: Array> = [], accErrors: BulkOperationError[] = [], accSkipped: BulkActionSkipResult[] = [] ): Promise => { diff --git a/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts b/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts index 2a6d1b3b06e7a..edf61427b8339 100644 --- a/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts +++ b/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts @@ -7,8 +7,16 @@ import { i18n } from '@kbn/i18n'; import { RawRule, RuleSnoozeSchedule } from '../../types'; +import { + RuleDomain, + RuleParams, + RuleSnoozeSchedule as RuleDomainSnoozeSchedule, +} from '../../application/rule/types'; import { getActiveScheduledSnoozes } from '../../lib/is_rule_snoozed'; +/** + * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types + */ export function getSnoozeAttributes(attributes: RawRule, snoozeSchedule: RuleSnoozeSchedule) { // If duration is -1, instead mute all const { id: snoozeId, duration } = snoozeSchedule; @@ -16,34 +24,40 @@ export function getSnoozeAttributes(attributes: RawRule, snoozeSchedule: RuleSno if (duration === -1) { return { muteAll: true, - snoozeSchedule: clearUnscheduledSnooze(attributes), + snoozeSchedule: clearUnscheduledSnoozeAttributes(attributes), }; } return { snoozeSchedule: (snoozeId - ? clearScheduledSnoozesById(attributes, [snoozeId]) - : clearUnscheduledSnooze(attributes) + ? clearScheduledSnoozesAttributesById(attributes, [snoozeId]) + : clearUnscheduledSnoozeAttributes(attributes) ).concat(snoozeSchedule), muteAll: false, }; } -export function getBulkSnoozeAttributes(attributes: RawRule, snoozeSchedule: RuleSnoozeSchedule) { +export function getBulkSnooze( + rule: RuleDomain, + snoozeSchedule: RuleDomainSnoozeSchedule +): { + muteAll: RuleDomain['muteAll']; + snoozeSchedule: RuleDomain['snoozeSchedule']; +} { // If duration is -1, instead mute all const { id: snoozeId, duration } = snoozeSchedule; if (duration === -1) { return { muteAll: true, - snoozeSchedule: clearUnscheduledSnooze(attributes), + snoozeSchedule: clearUnscheduledSnooze(rule), }; } // Bulk adding snooze schedule, don't touch the existing snooze/indefinite snooze if (snoozeId) { - const existingSnoozeSchedules = attributes.snoozeSchedule || []; + const existingSnoozeSchedules = rule.snoozeSchedule || []; return { - muteAll: attributes.muteAll, + muteAll: rule.muteAll, snoozeSchedule: [...existingSnoozeSchedules, snoozeSchedule], }; } @@ -51,14 +65,17 @@ export function getBulkSnoozeAttributes(attributes: RawRule, snoozeSchedule: Rul // Bulk snoozing, don't touch the existing snooze schedules return { muteAll: false, - snoozeSchedule: [...clearUnscheduledSnooze(attributes), snoozeSchedule], + snoozeSchedule: [...(clearUnscheduledSnooze(rule) || []), snoozeSchedule], }; } +/** + * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types + */ export function getUnsnoozeAttributes(attributes: RawRule, scheduleIds?: string[]) { const snoozeSchedule = scheduleIds - ? clearScheduledSnoozesById(attributes, scheduleIds) - : clearCurrentActiveSnooze(attributes); + ? clearScheduledSnoozesAttributesById(attributes, scheduleIds) + : clearCurrentActiveSnoozeAttributes(attributes); return { snoozeSchedule, @@ -66,43 +83,65 @@ export function getUnsnoozeAttributes(attributes: RawRule, scheduleIds?: string[ }; } -export function getBulkUnsnoozeAttributes(attributes: RawRule, scheduleIds?: string[]) { +export function getBulkUnsnooze( + rule: RuleDomain, + scheduleIds?: string[] +) { // Bulk removing snooze schedules, don't touch the current snooze/indefinite snooze if (scheduleIds) { - const newSchedules = clearScheduledSnoozesById(attributes, scheduleIds); + const newSchedules = clearScheduledSnoozesById(rule, scheduleIds); // Unscheduled snooze is also known as snooze now - const unscheduledSnooze = - attributes.snoozeSchedule?.filter((s) => typeof s.id === 'undefined') || []; + const unscheduledSnooze = rule.snoozeSchedule?.filter((s) => typeof s.id === 'undefined') || []; return { snoozeSchedule: [...unscheduledSnooze, ...newSchedules], - muteAll: attributes.muteAll, + muteAll: rule.muteAll, }; } // Bulk unsnoozing, don't touch current snooze schedules that are NOT active return { - snoozeSchedule: clearCurrentActiveSnooze(attributes), + snoozeSchedule: clearCurrentActiveSnooze(rule), muteAll: false, }; } -export function clearUnscheduledSnooze(attributes: RawRule) { +/** + * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types + */ +export function clearUnscheduledSnoozeAttributes(attributes: RawRule) { // Clear any snoozes that have no ID property. These are "simple" snoozes created with the quick UI, e.g. snooze for 3 days starting now return attributes.snoozeSchedule ? attributes.snoozeSchedule.filter((s) => typeof s.id !== 'undefined') : []; } -export function clearScheduledSnoozesById(attributes: RawRule, ids: string[]) { +export function clearUnscheduledSnooze(rule: RuleDomain) { + return rule.snoozeSchedule ? rule.snoozeSchedule.filter((s) => typeof s.id !== 'undefined') : []; +} + +/** + * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types + */ +export function clearScheduledSnoozesAttributesById(attributes: RawRule, ids: string[]) { return attributes.snoozeSchedule ? attributes.snoozeSchedule.filter((s) => s.id && !ids.includes(s.id)) : []; } -export function clearCurrentActiveSnooze(attributes: RawRule) { +export function clearScheduledSnoozesById( + rule: RuleDomain, + ids: string[] +) { + return rule.snoozeSchedule ? rule.snoozeSchedule.filter((s) => s.id && !ids.includes(s.id)) : []; +} + +/** + * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types + */ +export function clearCurrentActiveSnoozeAttributes(attributes: RawRule) { // First attempt to cancel a simple (unscheduled) snooze - const clearedUnscheduledSnoozes = clearUnscheduledSnooze(attributes); + const clearedUnscheduledSnoozes = clearUnscheduledSnoozeAttributes(attributes); // Now clear any scheduled snoozes that are currently active and never recur const activeSnoozes = getActiveScheduledSnoozes(attributes); const activeSnoozeIds = activeSnoozes?.map((s) => s.id) ?? []; @@ -127,7 +166,37 @@ export function clearCurrentActiveSnooze(attributes: RawRule) { return clearedSnoozesAndSkippedRecurringSnoozes; } -export function verifySnoozeScheduleLimit(attributes: Partial) { +export function clearCurrentActiveSnooze(rule: RuleDomain) { + // First attempt to cancel a simple (unscheduled) snooze + const clearedUnscheduledSnoozes = clearUnscheduledSnooze(rule); + // Now clear any scheduled snoozes that are currently active and never recur + const activeSnoozes = getActiveScheduledSnoozes(rule); + const activeSnoozeIds = activeSnoozes?.map((s) => s.id) ?? []; + const recurringSnoozesToSkip: string[] = []; + const clearedNonRecurringActiveSnoozes = clearedUnscheduledSnoozes.filter((s) => { + if (!activeSnoozeIds.includes(s.id!)) return true; + // Check if this is a recurring snooze, and return true if so + if (s.rRule.freq && s.rRule.count !== 1) { + recurringSnoozesToSkip.push(s.id!); + return true; + } + }); + const clearedSnoozesAndSkippedRecurringSnoozes = clearedNonRecurringActiveSnoozes.map((s) => { + if (s.id && !recurringSnoozesToSkip.includes(s.id)) return s; + const currentRecurrence = activeSnoozes?.find((a) => a.id === s.id)?.lastOccurrence; + if (!currentRecurrence) return s; + return { + ...s, + skipRecurrences: (s.skipRecurrences ?? []).concat(currentRecurrence.toISOString()), + }; + }); + return clearedSnoozesAndSkippedRecurringSnoozes; +} + +/** + * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types + */ +export function verifySnoozeAttributeScheduleLimit(attributes: Partial) { const schedules = attributes.snoozeSchedule?.filter((snooze) => snooze.id); if (schedules && schedules.length > 5) { throw Error( @@ -137,3 +206,16 @@ export function verifySnoozeScheduleLimit(attributes: Partial) { ); } } + +export function verifySnoozeScheduleLimit( + snoozeSchedule: RuleDomain['snoozeSchedule'] +) { + const schedules = snoozeSchedule?.filter((snooze) => snooze.id); + if (schedules && schedules.length > 5) { + throw Error( + i18n.translate('xpack.alerting.rulesClient.snoozeSchedule.limitReached', { + defaultMessage: 'Rule cannot have more than 5 snooze schedules', + }) + ); + } +} diff --git a/x-pack/plugins/alerting/server/rules_client/lib/create_rule_saved_object.ts b/x-pack/plugins/alerting/server/rules_client/lib/create_rule_saved_object.ts index 6d45866dc73d3..14662953ba73b 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/create_rule_saved_object.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/create_rule_saved_object.ts @@ -68,8 +68,8 @@ export async function createRuleSavedObject createRuleSo({ ruleAttributes: updateMeta(context, rawRule as RawRule) as RuleAttributes, - savedObjectClient: context.unsecuredSavedObjectsClient, - savedObjectCreateOptions: { + savedObjectsClient: context.unsecuredSavedObjectsClient, + savedObjectsCreateOptions: { ...options, references, id: ruleId, @@ -101,7 +101,7 @@ export async function createRuleSavedObject updateRuleSo({ - savedObjectClient: context.unsecuredSavedObjectsClient, + savedObjectsClient: context.unsecuredSavedObjectsClient, id: createdAlert.id, updateRuleAttributes: { scheduledTaskId, diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index b87d71aa275bc..a78516b34cad0 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -5,898 +5,9 @@ * 2.0. */ -import pMap from 'p-map'; -import Boom from '@hapi/boom'; -import { cloneDeep } from 'lodash'; -import { AlertConsumers } from '@kbn/rule-data-utils'; -import { KueryNode, nodeBuilder } from '@kbn/es-query'; -import { - SavedObjectsBulkUpdateObject, - SavedObjectsFindResult, - SavedObjectsUpdateResponse, -} from '@kbn/core/server'; -import { BulkActionSkipResult } from '../../../common/bulk_edit'; -import { - RawRule, - SanitizedRule, - RuleTypeParams, - Rule, - RuleSnoozeSchedule, - RuleWithLegacyId, - RuleTypeRegistry, - RawRuleAction, - RuleNotifyWhen, -} from '../../types'; -import { - validateRuleTypeParams, - getRuleNotifyWhenType, - validateMutatedRuleTypeParams, - convertRuleIdsToKueryNode, -} from '../../lib'; -import { WriteOperations, AlertingAuthorizationEntity } from '../../authorization'; -import { parseDuration } from '../../../common/parse_duration'; -import { bulkMarkApiKeysForInvalidation } from '../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; -import { - retryIfBulkEditConflicts, - applyBulkEditOperation, - buildKueryNodeFilter, - injectReferencesIntoActions, - getBulkSnoozeAttributes, - getBulkUnsnoozeAttributes, - verifySnoozeScheduleLimit, - injectReferencesIntoParams, -} from '../common'; -import { - alertingAuthorizationFilterOpts, - MAX_RULES_NUMBER_FOR_BULK_OPERATION, - RULE_TYPE_CHECKS_CONCURRENCY, - API_KEY_GENERATE_CONCURRENCY, -} from '../common/constants'; -import { getMappedParams } from '../common/mapped_params_utils'; -import { - getAlertFromRaw, - extractReferences, - validateActions, - updateMeta, - addGeneratedActionValues, - createNewAPIKeySet, -} from '../lib'; -import { - NormalizedAlertAction, - BulkOperationError, - RuleBulkOperationAggregation, - RulesClientContext, - NormalizedAlertActionWithGeneratedValues, -} from '../types'; - -import { migrateLegacyActions } from '../lib'; - -export type BulkEditFields = keyof Pick< - Rule, - 'actions' | 'tags' | 'schedule' | 'throttle' | 'notifyWhen' | 'snoozeSchedule' | 'apiKey' ->; - -export const bulkEditFieldsToExcludeFromRevisionUpdates: ReadonlySet = - new Set(['snoozeSchedule', 'apiKey']); - -export type BulkEditOperation = - | { - operation: 'add' | 'delete' | 'set'; - field: Extract; - value: string[]; - } - | { - operation: 'add' | 'set'; - field: Extract; - value: NormalizedAlertAction[]; - } - | { - operation: 'set'; - field: Extract; - value: Rule['schedule']; - } - | { - operation: 'set'; - field: Extract; - value: Rule['throttle']; - } - | { - operation: 'set'; - field: Extract; - value: Rule['notifyWhen']; - } - | { - operation: 'set'; - field: Extract; - value: RuleSnoozeSchedule; - } - | { - operation: 'delete'; - field: Extract; - value?: string[]; - } - | { - operation: 'set'; - field: Extract; - value?: undefined; - }; - -type ApiKeysMap = Map< - string, - { - oldApiKey?: string; - newApiKey?: string; - oldApiKeyCreatedByUser?: boolean | null; - newApiKeyCreatedByUser?: boolean | null; - } ->; - -type ApiKeyAttributes = Pick; - -type RuleType = ReturnType; - +// TODO (http-versioning): This file exists only to provide the type export for +// security solution, once we version all of our types we can remove this file export interface RuleParamsModifierResult { modifiedParams: Params; isParamsUpdateSkipped: boolean; } - -export type RuleParamsModifier = ( - params: Params -) => Promise>; - -export type ShouldIncrementRevision = ( - params?: RuleTypeParams -) => boolean; - -export interface BulkEditOptionsFilter { - filter?: string | KueryNode; - operations: BulkEditOperation[]; - paramsModifier?: RuleParamsModifier; - shouldIncrementRevision?: ShouldIncrementRevision; -} - -export interface BulkEditOptionsIds { - ids: string[]; - operations: BulkEditOperation[]; - paramsModifier?: RuleParamsModifier; - shouldIncrementRevision?: ShouldIncrementRevision; -} - -export type BulkEditOptions = - | BulkEditOptionsFilter - | BulkEditOptionsIds; - -export async function bulkEdit( - context: RulesClientContext, - options: BulkEditOptions -): Promise<{ - rules: Array>; - skipped: BulkActionSkipResult[]; - errors: BulkOperationError[]; - total: number; -}> { - const queryFilter = (options as BulkEditOptionsFilter).filter; - const ids = (options as BulkEditOptionsIds).ids; - - if (ids && queryFilter) { - throw Boom.badRequest( - "Both 'filter' and 'ids' are supplied. Define either 'ids' or 'filter' properties in method arguments" - ); - } - - const qNodeQueryFilter = buildKueryNodeFilter(queryFilter); - - const qNodeFilter = ids ? convertRuleIdsToKueryNode(ids) : qNodeQueryFilter; - let authorizationTuple; - try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts - ); - } catch (error) { - context.auditLogger?.log( - ruleAuditEvent({ - action: RuleAuditAction.BULK_EDIT, - error, - }) - ); - throw error; - } - const { filter: authorizationFilter } = authorizationTuple; - const qNodeFilterWithAuth = - authorizationFilter && qNodeFilter - ? nodeBuilder.and([qNodeFilter, authorizationFilter as KueryNode]) - : qNodeFilter; - - const { aggregations, total } = await context.unsecuredSavedObjectsClient.find< - RawRule, - RuleBulkOperationAggregation - >({ - filter: qNodeFilterWithAuth, - page: 1, - perPage: 0, - type: 'alert', - aggs: { - alertTypeId: { - multi_terms: { - terms: [ - { field: 'alert.attributes.alertTypeId' }, - { field: 'alert.attributes.consumer' }, - ], - }, - }, - }, - }); - - if (total > MAX_RULES_NUMBER_FOR_BULK_OPERATION) { - throw Boom.badRequest( - `More than ${MAX_RULES_NUMBER_FOR_BULK_OPERATION} rules matched for bulk edit` - ); - } - const buckets = aggregations?.alertTypeId.buckets; - - if (buckets === undefined) { - throw Error('No rules found for bulk edit'); - } - - await pMap( - buckets, - async ({ key: [ruleType, consumer] }) => { - context.ruleTypeRegistry.ensureRuleTypeEnabled(ruleType); - - try { - await context.authorization.ensureAuthorized({ - ruleTypeId: ruleType, - consumer, - operation: WriteOperations.BulkEdit, - entity: AlertingAuthorizationEntity.Rule, - }); - } catch (error) { - context.auditLogger?.log( - ruleAuditEvent({ - action: RuleAuditAction.BULK_EDIT, - error, - }) - ); - throw error; - } - }, - { concurrency: RULE_TYPE_CHECKS_CONCURRENCY } - ); - - const { apiKeysToInvalidate, results, errors, skipped } = await retryIfBulkEditConflicts( - context.logger, - `rulesClient.update('operations=${JSON.stringify(options.operations)}, paramsModifier=${ - options.paramsModifier ? '[Function]' : undefined - }', shouldIncrementRevision=${options.shouldIncrementRevision ? '[Function]' : undefined}')`, - (filterKueryNode: KueryNode | null) => - bulkEditOcc(context, { - filter: filterKueryNode, - operations: options.operations, - paramsModifier: options.paramsModifier, - shouldIncrementRevision: options.shouldIncrementRevision, - }), - qNodeFilterWithAuth - ); - - if (apiKeysToInvalidate.length > 0) { - await bulkMarkApiKeysForInvalidation( - { apiKeys: apiKeysToInvalidate }, - context.logger, - context.unsecuredSavedObjectsClient - ); - } - - const updatedRules = results.map(({ id, attributes, references }) => { - return getAlertFromRaw( - context, - id, - attributes.alertTypeId as string, - attributes as RawRule, - references, - false, - false, - false, - false - ); - }); - - await bulkUpdateSchedules(context, options.operations, updatedRules); - - return { rules: updatedRules, skipped, errors, total }; -} - -async function bulkEditOcc( - context: RulesClientContext, - { - filter, - operations, - paramsModifier, - shouldIncrementRevision, - }: { - filter: KueryNode | null; - operations: BulkEditOptions['operations']; - paramsModifier: BulkEditOptions['paramsModifier']; - shouldIncrementRevision?: BulkEditOptions['shouldIncrementRevision']; - } -): Promise<{ - apiKeysToInvalidate: string[]; - rules: Array>; - resultSavedObjects: Array>; - errors: BulkOperationError[]; - skipped: BulkActionSkipResult[]; -}> { - const rulesFinder = - await context.encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( - { - filter, - type: 'alert', - perPage: 100, - ...(context.namespace ? { namespaces: [context.namespace] } : undefined), - } - ); - - const rules: Array> = []; - const skipped: BulkActionSkipResult[] = []; - const errors: BulkOperationError[] = []; - const apiKeysMap: ApiKeysMap = new Map(); - const username = await context.getUserName(); - - for await (const response of rulesFinder.find()) { - await pMap( - response.saved_objects, - async (rule: SavedObjectsFindResult) => - updateRuleAttributesAndParamsInMemory({ - context, - rule, - operations, - paramsModifier, - apiKeysMap, - rules, - skipped, - errors, - username, - shouldIncrementRevision, - }), - { concurrency: API_KEY_GENERATE_CONCURRENCY } - ); - } - await rulesFinder.close(); - - const { result, apiKeysToInvalidate } = - rules.length > 0 - ? await saveBulkUpdatedRules(context, rules, apiKeysMap) - : { - result: { saved_objects: [] }, - apiKeysToInvalidate: [], - }; - - return { - apiKeysToInvalidate, - resultSavedObjects: result.saved_objects, - errors, - rules, - skipped, - }; -} - -async function bulkUpdateSchedules( - context: RulesClientContext, - operations: BulkEditOperation[], - updatedRules: Array -): Promise { - const scheduleOperation = operations.find( - ( - operation - ): operation is Extract }> => - operation.field === 'schedule' - ); - - if (!scheduleOperation?.value) { - return; - } - const taskIds = updatedRules.reduce((acc, rule) => { - if (rule.scheduledTaskId) { - acc.push(rule.scheduledTaskId); - } - return acc; - }, []); - - try { - await context.taskManager.bulkUpdateSchedules(taskIds, scheduleOperation.value); - context.logger.debug( - `Successfully updated schedules for underlying tasks: ${taskIds.join(', ')}` - ); - } catch (error) { - context.logger.error( - `Failure to update schedules for underlying tasks: ${taskIds.join( - ', ' - )}. TaskManager bulkUpdateSchedules failed with Error: ${error.message}` - ); - } -} - -async function updateRuleAttributesAndParamsInMemory({ - context, - rule, - operations, - paramsModifier, - apiKeysMap, - rules, - skipped, - errors, - username, - shouldIncrementRevision = () => true, -}: { - context: RulesClientContext; - rule: SavedObjectsFindResult; - operations: BulkEditOptions['operations']; - paramsModifier: BulkEditOptions['paramsModifier']; - apiKeysMap: ApiKeysMap; - rules: Array>; - skipped: BulkActionSkipResult[]; - errors: BulkOperationError[]; - username: string | null; - shouldIncrementRevision: BulkEditOptions['shouldIncrementRevision']; -}): Promise { - try { - if (rule.attributes.apiKey) { - apiKeysMap.set(rule.id, { - oldApiKey: rule.attributes.apiKey, - oldApiKeyCreatedByUser: rule.attributes.apiKeyCreatedByUser, - }); - } - - const ruleType = context.ruleTypeRegistry.get(rule.attributes.alertTypeId); - - await ensureAuthorizationForBulkUpdate(context, operations, rule); - - // migrate legacy actions only for SIEM rules - const migratedActions = await migrateLegacyActions(context, { - ruleId: rule.id, - actions: rule.attributes.actions, - references: rule.references, - attributes: rule.attributes, - }); - - if (migratedActions.hasLegacyActions) { - rule.attributes.actions = migratedActions.resultedActions; - rule.references = migratedActions.resultedReferences; - } - - const { attributes, ruleActions, hasUpdateApiKeyOperation, isAttributesUpdateSkipped } = - await getUpdatedAttributesFromOperations(context, operations, rule, ruleType); - - validateScheduleInterval(context, attributes.schedule.interval, ruleType.id, rule.id); - - const params = injectReferencesIntoParams( - rule.id, - ruleType, - attributes.params, - rule.references || [] - ); - const { modifiedParams: ruleParams, isParamsUpdateSkipped } = paramsModifier - ? await paramsModifier(params) - : { - modifiedParams: params, - isParamsUpdateSkipped: true, - }; - - // Increment revision if params ended up being modified AND it wasn't already incremented as part of attribute update - if ( - shouldIncrementRevision(ruleParams) && - !isParamsUpdateSkipped && - rule.attributes.revision === attributes.revision - ) { - attributes.revision += 1; - } - - // If neither attributes nor parameters were updated, mark - // the rule as skipped and continue to the next rule. - if (isAttributesUpdateSkipped && isParamsUpdateSkipped) { - skipped.push({ - id: rule.id, - name: rule.attributes.name, - skip_reason: 'RULE_NOT_MODIFIED', - }); - return; - } - - // validate rule params - const validatedAlertTypeParams = validateRuleTypeParams(ruleParams, ruleType.validate.params); - const validatedMutatedAlertTypeParams = validateMutatedRuleTypeParams( - validatedAlertTypeParams, - rule.attributes.params, - ruleType.validate.params - ); - - const { - actions: rawAlertActions, - references, - params: updatedParams, - } = await extractReferences( - context, - ruleType, - ruleActions.actions as NormalizedAlertActionWithGeneratedValues[], - validatedMutatedAlertTypeParams - ); - - const { apiKeyAttributes } = await prepareApiKeys( - context, - rule, - ruleType, - apiKeysMap, - attributes, - hasUpdateApiKeyOperation, - username - ); - - const { updatedAttributes } = updateAttributes( - context, - attributes, - apiKeyAttributes, - updatedParams, - rawAlertActions, - username - ); - - rules.push({ - ...rule, - references, - attributes: updatedAttributes, - }); - } catch (error) { - errors.push({ - message: error.message, - rule: { - id: rule.id, - name: rule.attributes?.name, - }, - }); - context.auditLogger?.log( - ruleAuditEvent({ - action: RuleAuditAction.BULK_EDIT, - error, - }) - ); - } -} - -async function ensureAuthorizationForBulkUpdate( - context: RulesClientContext, - operations: BulkEditOperation[], - rule: SavedObjectsFindResult -): Promise { - if (rule.attributes.actions.length === 0) { - return; - } - - for (const operation of operations) { - const { field } = operation; - if (field === 'snoozeSchedule' || field === 'apiKey') { - try { - await context.actionsAuthorization.ensureAuthorized({ operation: 'execute' }); - break; - } catch (error) { - throw Error(`Rule not authorized for bulk ${field} update - ${error.message}`); - } - } - } -} - -async function getUpdatedAttributesFromOperations( - context: RulesClientContext, - operations: BulkEditOperation[], - rule: SavedObjectsFindResult, - ruleType: RuleType -) { - let attributes = cloneDeep(rule.attributes); - let ruleActions = { - actions: injectReferencesIntoActions( - rule.id, - rule.attributes.actions || [], - rule.references || [] - ), - }; - - let hasUpdateApiKeyOperation = false; - let isAttributesUpdateSkipped = true; - - for (const operation of operations) { - // Check if the update should be skipped for the current action. - // If it should, save the skip reasons in attributesUpdateSkipReasons - // and continue to the next operation before without - // the `isAttributesUpdateSkipped` flag to false. - switch (operation.field) { - case 'actions': { - const updatedOperation = { - ...operation, - value: addGeneratedActionValues(operation.value), - }; - - try { - await validateActions(context, ruleType, { - ...attributes, - actions: updatedOperation.value, - }); - } catch (e) { - // If validateActions fails on the first attempt, it may be because of legacy rule-level frequency params - attributes = await attemptToMigrateLegacyFrequency( - context, - updatedOperation, - attributes, - ruleType - ); - } - - const { modifiedAttributes, isAttributeModified } = applyBulkEditOperation( - updatedOperation, - ruleActions - ); - if (isAttributeModified) { - ruleActions = modifiedAttributes; - isAttributesUpdateSkipped = false; - } - - break; - } - case 'snoozeSchedule': { - // Silently skip adding snooze or snooze schedules on security - // rules until we implement snoozing of their rules - if (rule.attributes.consumer === AlertConsumers.SIEM) { - // While the rule is technically not updated, we are still marking - // the rule as updated in case of snoozing, until support - // for snoozing is added. - isAttributesUpdateSkipped = false; - break; - } - if (operation.operation === 'set') { - const snoozeAttributes = getBulkSnoozeAttributes(rule.attributes, operation.value); - try { - verifySnoozeScheduleLimit(snoozeAttributes); - } catch (error) { - throw Error(`Error updating rule: could not add snooze - ${error.message}`); - } - attributes = { - ...attributes, - ...snoozeAttributes, - }; - } - if (operation.operation === 'delete') { - const idsToDelete = operation.value && [...operation.value]; - if (idsToDelete?.length === 0) { - attributes.snoozeSchedule?.forEach((schedule) => { - if (schedule.id) { - idsToDelete.push(schedule.id); - } - }); - } - attributes = { - ...attributes, - ...getBulkUnsnoozeAttributes(attributes, idsToDelete), - }; - } - isAttributesUpdateSkipped = false; - break; - } - case 'apiKey': { - hasUpdateApiKeyOperation = true; - isAttributesUpdateSkipped = false; - break; - } - default: { - if (operation.field === 'schedule') { - validateScheduleOperation(operation.value, attributes.actions, rule.id); - } - const { modifiedAttributes, isAttributeModified } = applyBulkEditOperation( - operation, - rule.attributes - ); - - if (isAttributeModified) { - attributes = { - ...attributes, - ...modifiedAttributes, - }; - isAttributesUpdateSkipped = false; - } - } - } - // Only increment revision if update wasn't skipped and `operation.field` should result in a revision increment - if ( - !isAttributesUpdateSkipped && - !bulkEditFieldsToExcludeFromRevisionUpdates.has(operation.field) && - rule.attributes.revision - attributes.revision === 0 - ) { - attributes.revision += 1; - } - } - return { - attributes, - ruleActions, - hasUpdateApiKeyOperation, - isAttributesUpdateSkipped, - }; -} - -function validateScheduleInterval( - context: RulesClientContext, - scheduleInterval: string, - ruleTypeId: string, - ruleId: string -): void { - if (!scheduleInterval) { - return; - } - const isIntervalInvalid = parseDuration(scheduleInterval) < context.minimumScheduleIntervalInMs; - if (isIntervalInvalid && context.minimumScheduleInterval.enforce) { - throw Error( - `Error updating rule: the interval is less than the allowed minimum interval of ${context.minimumScheduleInterval.value}` - ); - } else if (isIntervalInvalid && !context.minimumScheduleInterval.enforce) { - context.logger.warn( - `Rule schedule interval (${scheduleInterval}) for "${ruleTypeId}" rule type with ID "${ruleId}" is less than the minimum value (${context.minimumScheduleInterval.value}). Running rules at this interval may impact alerting performance. Set "xpack.alerting.rules.minimumScheduleInterval.enforce" to true to prevent such changes.` - ); - } -} - -/** - * Validate that updated schedule interval is not longer than any of the existing action frequencies - * @param schedule Schedule interval that user tries to set - * @param actions Rule actions - */ -function validateScheduleOperation( - schedule: RawRule['schedule'], - actions: RawRule['actions'], - ruleId: string -): void { - const scheduleInterval = parseDuration(schedule.interval); - const actionsWithInvalidThrottles = []; - - for (const action of actions) { - // check for actions throttled shorter than the rule schedule - if ( - action.frequency?.notifyWhen === RuleNotifyWhen.THROTTLE && - parseDuration(action.frequency.throttle!) < scheduleInterval - ) { - actionsWithInvalidThrottles.push(action); - } - } - - if (actionsWithInvalidThrottles.length > 0) { - throw Error( - `Error updating rule with ID "${ruleId}": the interval ${schedule.interval} is longer than the action frequencies` - ); - } -} - -async function prepareApiKeys( - context: RulesClientContext, - rule: SavedObjectsFindResult, - ruleType: RuleType, - apiKeysMap: ApiKeysMap, - attributes: RawRule, - hasUpdateApiKeyOperation: boolean, - username: string | null -): Promise<{ apiKeyAttributes: ApiKeyAttributes }> { - const apiKeyAttributes = await createNewAPIKeySet(context, { - id: ruleType.id, - ruleName: attributes.name, - username, - shouldUpdateApiKey: attributes.enabled || hasUpdateApiKeyOperation, - errorMessage: 'Error updating rule: could not create API key', - }); - - // collect generated API keys - if (apiKeyAttributes.apiKey) { - apiKeysMap.set(rule.id, { - ...apiKeysMap.get(rule.id), - newApiKey: apiKeyAttributes.apiKey, - newApiKeyCreatedByUser: apiKeyAttributes.apiKeyCreatedByUser, - }); - } - - return { - apiKeyAttributes, - }; -} - -function updateAttributes( - context: RulesClientContext, - attributes: RawRule, - apiKeyAttributes: ApiKeyAttributes, - updatedParams: RuleTypeParams, - rawAlertActions: RawRuleAction[], - username: string | null -): { - updatedAttributes: RawRule; -} { - // get notifyWhen - const notifyWhen = getRuleNotifyWhenType( - attributes.notifyWhen ?? null, - attributes.throttle ?? null - ); - - const updatedAttributes = updateMeta(context, { - ...attributes, - ...apiKeyAttributes, - params: updatedParams as RawRule['params'], - actions: rawAlertActions, - notifyWhen, - updatedBy: username, - updatedAt: new Date().toISOString(), - }); - - // add mapped_params - const mappedParams = getMappedParams(updatedParams); - - if (Object.keys(mappedParams).length) { - updatedAttributes.mapped_params = mappedParams; - } - - return { - updatedAttributes, - }; -} - -async function saveBulkUpdatedRules( - context: RulesClientContext, - rules: Array>, - apiKeysMap: ApiKeysMap -) { - const apiKeysToInvalidate: string[] = []; - let result; - try { - result = await context.unsecuredSavedObjectsClient.bulkCreate(rules, { overwrite: true }); - } catch (e) { - // avoid unused newly generated API keys - if (apiKeysMap.size > 0) { - await bulkMarkApiKeysForInvalidation( - { - apiKeys: Array.from(apiKeysMap.values()) - .filter((value) => value.newApiKey && !value.newApiKeyCreatedByUser) - .map((value) => value.newApiKey as string), - }, - context.logger, - context.unsecuredSavedObjectsClient - ); - } - throw e; - } - - result.saved_objects.map(({ id, error }) => { - const oldApiKey = apiKeysMap.get(id)?.oldApiKey; - const oldApiKeyCreatedByUser = apiKeysMap.get(id)?.oldApiKeyCreatedByUser; - const newApiKey = apiKeysMap.get(id)?.newApiKey; - const newApiKeyCreatedByUser = apiKeysMap.get(id)?.newApiKeyCreatedByUser; - - // if SO wasn't saved and has new API key it will be invalidated - if (error && newApiKey && !newApiKeyCreatedByUser) { - apiKeysToInvalidate.push(newApiKey); - // if SO saved and has old Api Key it will be invalidate - } else if (!error && oldApiKey && !oldApiKeyCreatedByUser) { - apiKeysToInvalidate.push(oldApiKey); - } - }); - - return { result, apiKeysToInvalidate }; -} - -async function attemptToMigrateLegacyFrequency( - context: RulesClientContext, - operation: BulkEditOperation, - attributes: SavedObjectsFindResult['attributes'], - ruleType: RuleType -) { - if (operation.field !== 'actions') - throw new Error('Can only perform frequency migration on an action operation'); - // Try to remove the rule-level frequency params, and then validate actions - if (typeof attributes.notifyWhen !== 'undefined') attributes.notifyWhen = undefined; - if (attributes.throttle) attributes.throttle = undefined; - await validateActions(context, ruleType, { - ...attributes, - actions: operation.value, - }); - return attributes; -} diff --git a/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts b/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts index dbc00b2135176..ca5584da706a7 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts @@ -12,7 +12,7 @@ import { partiallyUpdateAlert } from '../../saved_objects'; import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; import { RulesClientContext } from '../types'; import { updateMeta } from '../lib'; -import { clearUnscheduledSnooze } from '../common'; +import { clearUnscheduledSnoozeAttributes } from '../common'; export async function muteAll(context: RulesClientContext, { id }: { id: string }): Promise { return await retryIfConflicts( @@ -63,7 +63,7 @@ async function muteAllWithOCC(context: RulesClientContext, { id }: { id: string const updateAttributes = updateMeta(context, { muteAll: true, mutedInstanceIds: [], - snoozeSchedule: clearUnscheduledSnooze(attributes), + snoozeSchedule: clearUnscheduledSnoozeAttributes(attributes), updatedBy: await context.getUserName(), updatedAt: new Date().toISOString(), }); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/snooze.ts b/x-pack/plugins/alerting/server/rules_client/methods/snooze.ts index 8bfd19bc9c583..6f1187526b521 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/snooze.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/snooze.ts @@ -14,7 +14,7 @@ import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; import { validateSnoozeStartDate } from '../../lib/validate_snooze_date'; import { RuleMutedError } from '../../lib/errors/rule_muted'; import { RulesClientContext } from '../types'; -import { getSnoozeAttributes, verifySnoozeScheduleLimit } from '../common'; +import { getSnoozeAttributes, verifySnoozeAttributeScheduleLimit } from '../common'; import { updateMeta } from '../lib'; export interface SnoozeParams { @@ -88,7 +88,7 @@ async function snoozeWithOCC( const newAttrs = getSnoozeAttributes(attributes, snoozeSchedule); try { - verifySnoozeScheduleLimit(newAttrs); + verifySnoozeAttributeScheduleLimit(newAttrs); } catch (error) { throw Boom.badRequest(error.message); } diff --git a/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts b/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts index d5cd81b2664d6..e69f09a219700 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts @@ -12,7 +12,7 @@ import { partiallyUpdateAlert } from '../../saved_objects'; import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; import { RulesClientContext } from '../types'; import { updateMeta } from '../lib'; -import { clearUnscheduledSnooze } from '../common'; +import { clearUnscheduledSnoozeAttributes } from '../common'; export async function unmuteAll( context: RulesClientContext, @@ -66,7 +66,7 @@ async function unmuteAllWithOCC(context: RulesClientContext, { id }: { id: strin const updateAttributes = updateMeta(context, { muteAll: false, mutedInstanceIds: [], - snoozeSchedule: clearUnscheduledSnooze(attributes), + snoozeSchedule: clearUnscheduledSnoozeAttributes(attributes), updatedBy: await context.getUserName(), updatedAt: new Date().toISOString(), }); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/update.ts b/x-pack/plugins/alerting/server/rules_client/methods/update.ts index f68b41067ddae..68dc7fa0dd6a7 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/update.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/update.ts @@ -8,7 +8,6 @@ import Boom from '@hapi/boom'; import { isEqual } from 'lodash'; import { SavedObject } from '@kbn/core/server'; -import type { ShouldIncrementRevision } from './bulk_edit'; import { PartialRule, RawRule, @@ -35,6 +34,8 @@ import { migrateLegacyActions, } from '../lib'; +type ShouldIncrementRevision = (params?: RuleTypeParams) => boolean; + export interface UpdateOptions { id: string; data: { @@ -47,7 +48,7 @@ export interface UpdateOptions { notifyWhen?: RuleNotifyWhenType | null; }; allowMissingConnectorSecrets?: boolean; - shouldIncrementRevision?: ShouldIncrementRevision; + shouldIncrementRevision?: ShouldIncrementRevision; } export async function update( diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index a509fd3145c44..d34a8d10ef172 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -10,7 +10,7 @@ import { parseDuration } from '../../common/parse_duration'; import { RulesClientContext, BulkOptions, MuteOptions } from './types'; import { clone, CloneArguments } from './methods/clone'; -import { createRule, CreateRuleParams } from '../application/rule/create'; +import { createRule, CreateRuleParams } from '../application/rule/methods/create'; import { get, GetParams } from './methods/get'; import { resolve, ResolveParams } from './methods/resolve'; import { getAlertState, GetAlertStateParams } from './methods/get_alert_state'; @@ -37,7 +37,10 @@ import { aggregate, AggregateParams } from './methods/aggregate'; import { deleteRule } from './methods/delete'; import { update, UpdateOptions } from './methods/update'; import { bulkDeleteRules } from './methods/bulk_delete'; -import { bulkEdit, BulkEditOptions } from './methods/bulk_edit'; +import { + bulkEditRules, + BulkEditOptions, +} from '../application/rule/methods/bulk_edit/bulk_edit_rules'; import { bulkEnableRules } from './methods/bulk_enable'; import { bulkDisableRules } from './methods/bulk_disable'; import { updateApiKey } from './methods/update_api_key'; @@ -136,7 +139,7 @@ export class RulesClient { public bulkDeleteRules = (options: BulkOptions) => bulkDeleteRules(this.context, options); public bulkEdit = (options: BulkEditOptions) => - bulkEdit(this.context, options); + bulkEditRules(this.context, options); public bulkEnableRules = (options: BulkOptions) => bulkEnableRules(this.context, options); public bulkDisableRules = (options: BulkOptions) => bulkDisableRules(this.context, options); diff --git a/x-pack/plugins/alerting/server/rules_client/types.ts b/x-pack/plugins/alerting/server/rules_client/types.ts index fceac39d6bbdf..afcaaaaf34499 100644 --- a/x-pack/plugins/alerting/server/rules_client/types.ts +++ b/x-pack/plugins/alerting/server/rules_client/types.ts @@ -31,10 +31,7 @@ import { AlertingRulesConfig } from '../config'; export type { BulkEditOperation, BulkEditFields, - BulkEditOptions, - BulkEditOptionsFilter, - BulkEditOptionsIds, -} from './methods/bulk_edit'; +} from '../application/rule/methods/bulk_edit/types'; export type { FindOptions, FindResult } from './methods/find'; export type { UpdateOptions } from './methods/update'; export type { GetAlertSummaryParams } from './methods/get_alert_summary'; diff --git a/x-pack/plugins/canvas/server/feature.test.ts b/x-pack/plugins/canvas/server/feature.test.ts index e9bd23ec42e0e..513db3f668e14 100644 --- a/x-pack/plugins/canvas/server/feature.test.ts +++ b/x-pack/plugins/canvas/server/feature.test.ts @@ -5,15 +5,13 @@ * 2.0. */ -import { ReportingStart } from '@kbn/reporting-plugin/server/types'; import { getCanvasFeature } from './feature'; +import { ReportingStart } from '@kbn/reporting-plugin/server/types'; +import { reportingMock } from '@kbn/reporting-plugin/server/mocks'; let mockReportingPlugin: ReportingStart; beforeEach(() => { - mockReportingPlugin = { - usesUiCapabilities: () => false, - registerExportTypes: () => {}, - }; + mockReportingPlugin = reportingMock.createStart(); }); it('Provides a feature declaration ', () => { @@ -86,10 +84,7 @@ it('Provides a feature declaration ', () => { }); it(`Calls on Reporting whether to include Generate PDF as a sub-feature`, () => { - mockReportingPlugin = { - usesUiCapabilities: () => true, - registerExportTypes: () => {}, - }; + mockReportingPlugin.usesUiCapabilities = () => true; expect(getCanvasFeature({ reporting: mockReportingPlugin })).toMatchInlineSnapshot(` Object { "app": Array [ diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index dcaf2bb0e6460..45125e4411f3a 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -127,6 +127,7 @@ export const MAX_DELETE_IDS_LENGTH = 100 as const; export const MAX_SUGGESTED_PROFILES = 10 as const; export const MAX_CASES_TO_UPDATE = 100 as const; export const MAX_BULK_CREATE_ATTACHMENTS = 100 as const; +export const MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES = 100 as const; /** * Cases features diff --git a/x-pack/plugins/cases/server/client/cases/mock.ts b/x-pack/plugins/cases/server/client/cases/mock.ts index bee726524061a..ca96d20bad570 100644 --- a/x-pack/plugins/cases/server/client/cases/mock.ts +++ b/x-pack/plugins/cases/server/client/cases/mock.ts @@ -9,7 +9,7 @@ import type { CaseUserActionsDeprecatedResponse } from '../../../common/types/ap import { ConnectorTypes, UserActionActions } from '../../../common/types/domain'; import type { Comment, CommentResponseAlertsType } from '../../../common/api'; import { CommentType, ExternalReferenceStorageType } from '../../../common/api'; -import { SECURITY_SOLUTION_OWNER } from '../../../common/constants'; +import { FILE_ATTACHMENT_TYPE, SECURITY_SOLUTION_OWNER } from '../../../common/constants'; export const updateUser = { updated_at: '2020-03-13T08:34:53.450Z', @@ -228,6 +228,16 @@ export const commentPersistableState: Comment = { version: 'WzEsMV0=', }; +export const commentFileExternalReference: Comment = { + ...commentExternalReference, + externalReferenceAttachmentTypeId: FILE_ATTACHMENT_TYPE, + externalReferenceMetadata: { files: [{ name: '', extension: '', mimeType: '', created: '' }] }, + externalReferenceStorage: { + type: ExternalReferenceStorageType.savedObject as const, + soType: 'file', + }, +}; + export const basicParams = { description: 'a description', title: 'a title', diff --git a/x-pack/plugins/cases/server/common/limiter_checker/base_limiter.ts b/x-pack/plugins/cases/server/common/limiter_checker/base_limiter.ts index cf9fcec712e61..f4e72554636ae 100644 --- a/x-pack/plugins/cases/server/common/limiter_checker/base_limiter.ts +++ b/x-pack/plugins/cases/server/common/limiter_checker/base_limiter.ts @@ -10,8 +10,8 @@ import type { Limiter } from './types'; interface LimiterParams { limit: number; - attachmentType: CommentType; - field: string; + attachmentType: CommentType | CommentType[]; + field?: string; attachmentNoun: string; } diff --git a/x-pack/plugins/cases/server/common/limiter_checker/index.ts b/x-pack/plugins/cases/server/common/limiter_checker/index.ts index 97928f2eeb356..1ef34d70e7e25 100644 --- a/x-pack/plugins/cases/server/common/limiter_checker/index.ts +++ b/x-pack/plugins/cases/server/common/limiter_checker/index.ts @@ -13,6 +13,7 @@ import type { AttachmentService } from '../../services'; import type { Limiter } from './types'; import { AlertLimiter } from './limiters/alerts'; import { FileLimiter } from './limiters/files'; +import { PersistableStateAndExternalReferencesLimiter } from './limiters/persistable_state_and_external_references'; export class AttachmentLimitChecker { private readonly limiters: Limiter[]; @@ -22,7 +23,11 @@ export class AttachmentLimitChecker { fileService: FileServiceStart, private readonly caseId: string ) { - this.limiters = [new AlertLimiter(attachmentService), new FileLimiter(fileService)]; + this.limiters = [ + new AlertLimiter(attachmentService), + new FileLimiter(fileService), + new PersistableStateAndExternalReferencesLimiter(attachmentService), + ]; } public async validate(requests: CommentRequest[]) { diff --git a/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.test.ts b/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.test.ts new file mode 100644 index 0000000000000..df40e3841f1d7 --- /dev/null +++ b/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.test.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAttachmentServiceMock } from '../../../services/mocks'; +import { PersistableStateAndExternalReferencesLimiter } from './persistable_state_and_external_references'; +import { + createExternalReferenceRequests, + createFileRequests, + createPersistableStateRequests, + createUserRequests, +} from '../test_utils'; +import { MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES } from '../../../../common/constants'; + +describe('PersistableStateAndExternalReferencesLimiter', () => { + const caseId = 'test-id'; + const attachmentService = createAttachmentServiceMock(); + attachmentService.countPersistableStateAndExternalReferenceAttachments.mockResolvedValue(1); + + const limiter = new PersistableStateAndExternalReferencesLimiter(attachmentService); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('public fields', () => { + it('sets the errorMessage to the 100 limit', () => { + expect(limiter.errorMessage).toMatchInlineSnapshot( + `"Case has reached the maximum allowed number (100) of attached persistable state and external reference attachments."` + ); + }); + + it('sets the limit to 100', () => { + expect(limiter.limit).toBe(MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES); + }); + }); + + describe('countOfItemsWithinCase', () => { + it('calls the attachment service with the right params', () => { + limiter.countOfItemsWithinCase(caseId); + + expect( + attachmentService.countPersistableStateAndExternalReferenceAttachments + ).toHaveBeenCalledWith({ caseId }); + }); + }); + + describe('countOfItemsInRequest', () => { + it('returns 0 when passed an empty array', () => { + expect(limiter.countOfItemsInRequest([])).toBe(0); + }); + + it('returns 0 when the requests are not for persistable state attachments or external references', () => { + expect(limiter.countOfItemsInRequest(createUserRequests(2))).toBe(0); + }); + + it('counts persistable state attachments or external references correctly', () => { + expect( + limiter.countOfItemsInRequest([ + createPersistableStateRequests(1)[0], + createExternalReferenceRequests(1)[0], + createUserRequests(1)[0], + createFileRequests({ + numRequests: 1, + numFiles: 1, + })[0], + ]) + ).toBe(2); + }); + + it('excludes fileAttachmentsRequests from the count', () => { + expect( + limiter.countOfItemsInRequest( + createFileRequests({ + numRequests: 1, + numFiles: 1, + }) + ) + ).toBe(0); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.ts b/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.ts new file mode 100644 index 0000000000000..b16baa919cffd --- /dev/null +++ b/x-pack/plugins/cases/server/common/limiter_checker/limiters/persistable_state_and_external_references.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { AttachmentService } from '../../../services'; +import { CommentType } from '../../../../common/api'; +import type { CommentRequest } from '../../../../common/api'; +import { MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES } from '../../../../common/constants'; +import { isFileAttachmentRequest, isPersistableStateOrExternalReference } from '../../utils'; +import { BaseLimiter } from '../base_limiter'; + +export class PersistableStateAndExternalReferencesLimiter extends BaseLimiter { + constructor(private readonly attachmentService: AttachmentService) { + super({ + limit: MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES, + attachmentType: [CommentType.persistableState, CommentType.externalReference], + attachmentNoun: 'persistable state and external reference attachments', + }); + } + + public async countOfItemsWithinCase(caseId: string): Promise { + return this.attachmentService.countPersistableStateAndExternalReferenceAttachments({ + caseId, + }); + } + + public countOfItemsInRequest(requests: CommentRequest[]): number { + const totalReferences = requests + .filter(isPersistableStateOrExternalReference) + .filter((request) => !isFileAttachmentRequest(request)); + + return totalReferences.length; + } +} diff --git a/x-pack/plugins/cases/server/common/limiter_checker/test_utils.ts b/x-pack/plugins/cases/server/common/limiter_checker/test_utils.ts index f0c990e439bdf..fc9515c133069 100644 --- a/x-pack/plugins/cases/server/common/limiter_checker/test_utils.ts +++ b/x-pack/plugins/cases/server/common/limiter_checker/test_utils.ts @@ -11,6 +11,8 @@ import type { CommentRequestUserType, CommentRequestAlertType, FileAttachmentMetadata, + CommentRequestPersistableStateType, + CommentRequestExternalReferenceType, } from '../../../common/api'; import type { FileAttachmentRequest } from '../types'; @@ -26,6 +28,37 @@ export const createUserRequests = (num: number): CommentRequestUserType[] => { return requests; }; +export const createPersistableStateRequests = ( + num: number +): CommentRequestPersistableStateType[] => { + return [...Array(num).keys()].map(() => { + return { + persistableStateAttachmentTypeId: '.test', + persistableStateAttachmentState: {}, + type: CommentType.persistableState as const, + owner: 'test', + }; + }); +}; + +export const createExternalReferenceRequests = ( + num: number +): CommentRequestExternalReferenceType[] => { + return [...Array(num).keys()].map((value) => { + return { + type: CommentType.externalReference as const, + owner: 'test', + externalReferenceAttachmentTypeId: '.test', + externalReferenceId: 'so-id', + externalReferenceMetadata: {}, + externalReferenceStorage: { + soType: `${value}`, + type: ExternalReferenceStorageType.savedObject, + }, + }; + }); +}; + export const createFileRequests = ({ numRequests, numFiles, diff --git a/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts b/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts index 94b3ac3e3be3d..779ed8767a9b3 100644 --- a/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts +++ b/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts @@ -10,6 +10,12 @@ import type { SavedObject } from '@kbn/core-saved-objects-api-server'; import { createCasesClientMockArgs } from '../../client/mocks'; import { alertComment, comment, mockCaseComments, mockCases, multipleAlert } from '../../mocks'; import { CaseCommentModel } from './case_with_comments'; +import { MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES } from '../../../common/constants'; +import { + commentExternalReference, + commentFileExternalReference, + commentPersistableState, +} from '../../client/cases/mock'; describe('CaseCommentModel', () => { const theCase = mockCases[0]; @@ -267,6 +273,52 @@ describe('CaseCommentModel', () => { expect(clientArgs.services.attachmentService.create).not.toHaveBeenCalled(); }); + + describe('validation', () => { + clientArgs.services.attachmentService.countPersistableStateAndExternalReferenceAttachments.mockResolvedValue( + MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES + ); + + afterAll(() => { + jest.clearAllMocks(); + }); + + it('throws if limit is reached when creating persistable state attachment', async () => { + await expect( + model.createComment({ + id: 'comment-1', + commentReq: commentPersistableState, + createdDate, + }) + ).rejects.toThrow( + `Case has reached the maximum allowed number (${MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES}) of attached persistable state and external reference attachments.` + ); + }); + + it('throws if limit is reached when creating external reference', async () => { + await expect( + model.createComment({ + id: 'comment-1', + commentReq: commentExternalReference, + createdDate, + }) + ).rejects.toThrow( + `Case has reached the maximum allowed number (${MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES}) of attached persistable state and external reference attachments.` + ); + }); + + it('does not throw if creating a file external reference and the limit is reached', async () => { + clientArgs.fileService.find.mockResolvedValue({ total: 0, files: [] }); + + await expect( + model.createComment({ + id: 'comment-1', + commentReq: commentFileExternalReference, + createdDate, + }) + ).resolves.not.toThrow(); + }); + }); }); describe('bulkCreate', () => { @@ -526,5 +578,45 @@ describe('CaseCommentModel', () => { expect(multipleAlertsCall.attributes.alertId).toEqual(['test-id-3', 'test-id-5']); expect(multipleAlertsCall.attributes.index).toEqual(['test-index-3', 'test-index-5']); }); + + describe('validation', () => { + clientArgs.services.attachmentService.countPersistableStateAndExternalReferenceAttachments.mockResolvedValue( + MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES + ); + + afterAll(() => { + jest.clearAllMocks(); + }); + + it('throws if limit is reached when creating persistable state attachment', async () => { + await expect( + model.bulkCreate({ + attachments: [commentPersistableState], + }) + ).rejects.toThrow( + `Case has reached the maximum allowed number (${MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES}) of attached persistable state and external reference attachments.` + ); + }); + + it('throws if limit is reached when creating external reference', async () => { + await expect( + model.bulkCreate({ + attachments: [commentExternalReference], + }) + ).rejects.toThrow( + `Case has reached the maximum allowed number (${MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES}) of attached persistable state and external reference attachments.` + ); + }); + + it('does not throw if creating a file external reference and the limit is reached', async () => { + clientArgs.fileService.find.mockResolvedValue({ total: 0, files: [] }); + + await expect( + model.bulkCreate({ + attachments: [commentFileExternalReference], + }) + ).resolves.not.toThrow(); + }); + }); }); }); diff --git a/x-pack/plugins/cases/server/common/utils.test.ts b/x-pack/plugins/cases/server/common/utils.test.ts index 1c42d75be05d1..ce470b66080ca 100644 --- a/x-pack/plugins/cases/server/common/utils.test.ts +++ b/x-pack/plugins/cases/server/common/utils.test.ts @@ -33,6 +33,7 @@ import { getCaseViewPath, isSOError, countUserAttachments, + isPersistableStateOrExternalReference, } from './utils'; import { newCase } from '../routes/api/__mocks__/request_responses'; import { CASE_VIEW_PAGE_TABS } from '../../common/types'; @@ -40,6 +41,12 @@ import { mockCases, mockCaseComments } from '../mocks'; import { createAlertAttachment, createUserAttachment } from '../services/attachments/test_utils'; import type { CaseConnector } from '../../common/types/domain'; import { ConnectorTypes } from '../../common/types/domain'; +import { + createAlertRequests, + createExternalReferenceRequests, + createPersistableStateRequests, + createUserRequests, +} from './limiter_checker/test_utils'; interface CommentReference { ids: string[]; @@ -1353,4 +1360,25 @@ describe('common utils', () => { expect(countUserAttachments(attachments)).toBe(0); }); }); + + describe('isPersistableStateOrExternalReference', () => { + it('returns true for persistable state request', () => { + expect(isPersistableStateOrExternalReference(createPersistableStateRequests(1)[0])).toBe( + true + ); + }); + + it('returns true for external reference request', () => { + expect(isPersistableStateOrExternalReference(createExternalReferenceRequests(1)[0])).toBe( + true + ); + }); + + it('returns false for other request types', () => { + expect(isPersistableStateOrExternalReference(createUserRequests(1)[0])).toBe(false); + expect(isPersistableStateOrExternalReference(createAlertRequests(1, 'alert-id')[0])).toBe( + false + ); + }); + }); }); diff --git a/x-pack/plugins/cases/server/common/utils.ts b/x-pack/plugins/cases/server/common/utils.ts index 78a4ffeb7593f..64e25eb78ac7b 100644 --- a/x-pack/plugins/cases/server/common/utils.ts +++ b/x-pack/plugins/cases/server/common/utils.ts @@ -254,6 +254,16 @@ export const isCommentRequestTypeAlert = ( return context.type === CommentType.alert; }; +/** + * Returns true if a Comment Request is trying to create either a persistableState or an + * externalReference attachment. + */ +export const isPersistableStateOrExternalReference = (context: CommentRequest): boolean => { + return ( + context.type === CommentType.persistableState || context.type === CommentType.externalReference + ); +}; + /** * A type narrowing function for file attachments. */ diff --git a/x-pack/plugins/cases/server/services/attachments/index.test.ts b/x-pack/plugins/cases/server/services/attachments/index.test.ts index 54a48f0a53c67..610ce7df5bb9d 100644 --- a/x-pack/plugins/cases/server/services/attachments/index.test.ts +++ b/x-pack/plugins/cases/server/services/attachments/index.test.ts @@ -537,4 +537,111 @@ describe('AttachmentService', () => { }); }); }); + + describe('countPersistableStateAndExternalReferenceAttachments', () => { + it('does not throw and calls unsecuredSavedObjectsClient.find with the right parameters', async () => { + unsecuredSavedObjectsClient.find.mockResolvedValue( + createSOFindResponse([{ ...createUserAttachment(), score: 0 }]) + ); + + await expect( + service.countPersistableStateAndExternalReferenceAttachments({ caseId: 'test-id' }) + ).resolves.not.toThrow(); + + expect(unsecuredSavedObjectsClient.find.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "filter": Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "cases-comments.attributes.type", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "persistableState", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "cases-comments.attributes.type", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "externalReference", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "or", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "cases-comments.attributes.externalReferenceAttachmentTypeId", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": ".files", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "not", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + "hasReference": Object { + "id": "test-id", + "type": "cases", + }, + "page": 1, + "perPage": 1, + "sortField": "created_at", + "type": "cases-comments", + } + `); + }); + + it('returns the expected total', async () => { + const total = 3; + + unsecuredSavedObjectsClient.find.mockResolvedValue( + createSOFindResponse( + Array(total).fill({ ...createUserAttachment({ foo: 'bar' }), score: 0 }) + ) + ); + + const res = await service.countPersistableStateAndExternalReferenceAttachments({ + caseId: 'test-id', + }); + + expect(res).toBe(total); + }); + }); }); diff --git a/x-pack/plugins/cases/server/services/attachments/index.ts b/x-pack/plugins/cases/server/services/attachments/index.ts index b0d282e00aa96..8f5c9ee69c07c 100644 --- a/x-pack/plugins/cases/server/services/attachments/index.ts +++ b/x-pack/plugins/cases/server/services/attachments/index.ts @@ -14,8 +14,13 @@ import type { } from '@kbn/core/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { fromKueryExpression } from '@kbn/es-query'; import { CommentAttributesRt, CommentType, decodeOrThrow } from '../../../common/api'; -import { CASE_COMMENT_SAVED_OBJECT, CASE_SAVED_OBJECT } from '../../../common/constants'; +import { + CASE_COMMENT_SAVED_OBJECT, + CASE_SAVED_OBJECT, + FILE_ATTACHMENT_TYPE, +} from '../../../common/constants'; import { buildFilter, combineFilters } from '../../client/utils'; import { defaultSortField, isSOError } from '../../common/utils'; import type { AggregationResponse } from '../../client/metrics/types'; @@ -124,6 +129,50 @@ export class AttachmentService { } } + /** + * Counts the persistableState and externalReference attachments that are not .files + */ + public async countPersistableStateAndExternalReferenceAttachments({ + caseId, + }: { + caseId: string; + }): Promise { + try { + this.context.log.debug( + `Attempting to count persistableState and externalReference attachments for case id ${caseId}` + ); + + const typeFilter = buildFilter({ + filters: [CommentType.persistableState, CommentType.externalReference], + field: 'type', + operator: 'or', + type: CASE_COMMENT_SAVED_OBJECT, + }); + + const excludeFilesFilter = fromKueryExpression( + `not ${CASE_COMMENT_SAVED_OBJECT}.attributes.externalReferenceAttachmentTypeId: ${FILE_ATTACHMENT_TYPE}` + ); + + const combinedFilter = combineFilters([typeFilter, excludeFilesFilter]); + + const response = await this.context.unsecuredSavedObjectsClient.find<{ total: number }>({ + type: CASE_COMMENT_SAVED_OBJECT, + hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, + page: 1, + perPage: 1, + sortField: defaultSortField, + filter: combinedFilter, + }); + + return response.total; + } catch (error) { + this.context.log.error( + `Error while attempting to count persistableState and externalReference attachments for case id ${caseId}: ${error}` + ); + throw error; + } + } + /** * Executes the aggregations against the actions attached to a case. */ diff --git a/x-pack/plugins/cases/server/services/mocks.ts b/x-pack/plugins/cases/server/services/mocks.ts index e9cb492e39458..b43a3c226b1e4 100644 --- a/x-pack/plugins/cases/server/services/mocks.ts +++ b/x-pack/plugins/cases/server/services/mocks.ts @@ -177,6 +177,7 @@ export const createAttachmentServiceMock = (): AttachmentServiceMock => { countAlertsAttachedToCase: jest.fn(), executeCaseActionsAggregations: jest.fn(), executeCaseAggregations: jest.fn(), + countPersistableStateAndExternalReferenceAttachments: jest.fn(), }; // the cast here is required because jest.Mocked tries to include private members and would throw an error diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 9ef02f826f8ad..b12ad9416e514 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -25,6 +25,8 @@ import { UNINSTALL_TOKENS_SAVED_OBJECT_TYPE, } from '../constants'; +import { migratePackagePolicyEvictionsFromV8100 } from './migrations/security_solution/to_v8_10_0'; + import { migrateAgentPolicyToV7100, migratePackagePolicyToV7100, @@ -56,7 +58,10 @@ import { migrateInstallationToV860, migratePackagePolicyToV860, } from './migrations/to_v8_6_0'; -import { migratePackagePolicyToV870 } from './migrations/security_solution'; +import { + migratePackagePolicyToV8100, + migratePackagePolicyToV870, +} from './migrations/security_solution'; import { migratePackagePolicyToV880 } from './migrations/to_v8_8_0'; import { migrateAgentPolicyToV890 } from './migrations/to_v8_9_0'; @@ -269,6 +274,19 @@ const getSavedObjectTypes = (): { [key: string]: SavedObjectsType } => ({ created_by: { type: 'keyword' }, }, }, + modelVersions: { + '1': { + changes: [ + { + type: 'data_backfill', + backfillFn: migratePackagePolicyToV8100, + }, + ], + schemas: { + forwardCompatibility: migratePackagePolicyEvictionsFromV8100, + }, + }, + }, migrations: { '7.10.0': migratePackagePolicyToV7100, '7.11.0': migratePackagePolicyToV7110, diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/index.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/index.ts index 4dd924e832a22..8248c181405e5 100644 --- a/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/index.ts @@ -18,3 +18,4 @@ export { migratePackagePolicyToV850 } from './to_v8_5_0'; export { migratePackagePolicyToV860 } from './to_v8_6_0'; export { migratePackagePolicyToV870 } from './to_v8_7_0'; export { migratePackagePolicyToV880 } from './to_v8_8_0'; +export { migratePackagePolicyToV8100 } from './to_v8_10_0'; diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/to_v8_10_0.test.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/to_v8_10_0.test.ts new file mode 100644 index 0000000000000..e31653bd448e3 --- /dev/null +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/to_v8_10_0.test.ts @@ -0,0 +1,159 @@ +/* + * Copyright 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 { SavedObjectUnsanitizedDoc } from '@kbn/core/server'; + +import type { SavedObjectModelTransformationContext } from '@kbn/core-saved-objects-server'; + +import type { PackagePolicy } from '../../../../common'; + +import { migratePackagePolicyToV8100 as migration } from './to_v8_10_0'; +import { migratePackagePolicyEvictionsFromV8100 as eviction } from './to_v8_10_0'; + +describe('8.10.0 Endpoint Package Policy migration', () => { + const policyDoc = ({ behaviorProtection = {} }) => { + return { + id: 'mock-saved-object-id', + attributes: { + name: 'Some Policy Name', + package: { + name: 'endpoint', + title: '', + version: '', + }, + id: 'endpoint', + policy_id: '', + enabled: true, + namespace: '', + revision: 0, + updated_at: '', + updated_by: '', + created_at: '', + created_by: '', + inputs: [ + { + type: 'endpoint', + enabled: true, + streams: [], + config: { + policy: { + value: { + meta: {}, + windows: { + behavior_protection: { + ...behaviorProtection, + }, + }, + mac: { + behavior_protection: { + ...behaviorProtection, + }, + }, + linux: { + behavior_protection: { + ...behaviorProtection, + }, + }, + }, + }, + }, + }, + ], + }, + type: ' nested', + }; + }; + + it('adds reputation service field to behaviour protection, set to false', () => { + const initialDoc = policyDoc({}); + + const migratedDoc = policyDoc({ + behaviorProtection: { reputation_service: false }, + }); + + expect(migration(initialDoc, {} as SavedObjectModelTransformationContext)).toEqual({ + attributes: { + inputs: migratedDoc.attributes.inputs, + }, + }); + }); + + it('removes reputation service field from behaviour protection', () => { + const initialDoc = policyDoc({ + behaviorProtection: { reputation_service: true }, + }); + + const migratedDoc = policyDoc({}); + + expect(eviction(initialDoc.attributes)).toEqual(migratedDoc.attributes); + }); + + it('does not modify non-endpoint package policies', () => { + const doc: SavedObjectUnsanitizedDoc = { + id: 'mock-saved-object-id', + attributes: { + name: 'Some Policy Name', + package: { + name: 'notEndpoint', + title: '', + version: '', + }, + id: 'notEndpoint', + policy_id: '', + enabled: true, + namespace: '', + revision: 0, + updated_at: '', + updated_by: '', + created_at: '', + created_by: '', + inputs: [ + { + type: 'notEndpoint', + enabled: true, + streams: [], + config: {}, + }, + ], + }, + type: ' nested', + }; + + expect( + migration( + doc, + {} as SavedObjectModelTransformationContext + ) as SavedObjectUnsanitizedDoc + ).toEqual({ + attributes: { + name: 'Some Policy Name', + package: { + name: 'notEndpoint', + title: '', + version: '', + }, + id: 'notEndpoint', + policy_id: '', + enabled: true, + namespace: '', + revision: 0, + updated_at: '', + updated_by: '', + created_at: '', + created_by: '', + inputs: [ + { + type: 'notEndpoint', + enabled: true, + streams: [], + config: {}, + }, + ], + }, + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/to_v8_10_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/to_v8_10_0.ts new file mode 100644 index 0000000000000..d2cf56d26075c --- /dev/null +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/security_solution/to_v8_10_0.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectUnsanitizedDoc } from '@kbn/core/server'; + +import type { SavedObjectModelDataBackfillFn } from '@kbn/core-saved-objects-server'; + +import { omit } from 'lodash'; + +import type { SavedObjectModelVersionForwardCompatibilityFn } from '@kbn/core-saved-objects-server'; + +import type { PackagePolicy } from '../../../../common'; + +export const migratePackagePolicyToV8100: SavedObjectModelDataBackfillFn< + PackagePolicy, + PackagePolicy +> = (packagePolicyDoc) => { + if (packagePolicyDoc.attributes.package?.name !== 'endpoint') { + return { attributes: packagePolicyDoc.attributes }; + } + + const updatedPackagePolicyDoc: SavedObjectUnsanitizedDoc = packagePolicyDoc; + + const input = updatedPackagePolicyDoc.attributes.inputs[0]; + + if (input && input.config) { + const policy = input.config.policy.value; + + policy.windows.behavior_protection.reputation_service = false; + policy.mac.behavior_protection.reputation_service = false; + policy.linux.behavior_protection.reputation_service = false; + } + + return { + attributes: { + inputs: updatedPackagePolicyDoc.attributes.inputs, + }, + }; +}; + +export const migratePackagePolicyEvictionsFromV8100: SavedObjectModelVersionForwardCompatibilityFn = + (unknownAttributes) => { + const attributes = unknownAttributes as PackagePolicy; + if (attributes.package?.name !== 'endpoint') { + return attributes; + } + + const updatedAttributes = attributes; + + const input = updatedAttributes.inputs[0]; + + if (input && input.config) { + const policy = input.config.policy.value; + + policy.windows.behavior_protection = omit(policy.windows.behavior_protection, [ + 'reputation_service', + ]); + policy.linux.behavior_protection = omit(policy.linux.behavior_protection, [ + 'reputation_service', + ]); + policy.mac.behavior_protection = omit(policy.mac.behavior_protection, ['reputation_service']); + } + + return updatedAttributes; + }; diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 47962ad4e2f2a..beff6ee8525d0 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -26,7 +26,6 @@ import { useLensSelector, useLensDispatch, LensAppState, - DispatchSetState, selectSavedObjectFormat, updateIndexPatterns, updateDatasourceState, @@ -99,7 +98,7 @@ export function App({ const saveAndExit = useRef<() => void>(); const dispatch = useLensDispatch(); - const dispatchSetState: DispatchSetState = useCallback( + const dispatchSetState = useCallback( (state: Partial) => dispatch(setState(state)), [dispatch] ); diff --git a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx index 35346b4cdabd0..dc4707a809bc9 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx +++ b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx @@ -25,7 +25,6 @@ import { useLensSelector, useLensDispatch, LensAppState, - DispatchSetState, switchAndCleanDatasource, } from '../state_management'; import { @@ -314,7 +313,7 @@ export const LensTopNavMenu = ({ } = useLensSelector((state) => state.lens); const dispatch = useLensDispatch(); - const dispatchSetState: DispatchSetState = React.useCallback( + const dispatchSetState = React.useCallback( (state: Partial) => dispatch(setState(state)), [dispatch] ); diff --git a/x-pack/plugins/lens/public/app_plugin/mounter.tsx b/x-pack/plugins/lens/public/app_plugin/mounter.tsx index af53a34b2edc0..0742e48882748 100644 --- a/x-pack/plugins/lens/public/app_plugin/mounter.tsx +++ b/x-pack/plugins/lens/public/app_plugin/mounter.tsx @@ -6,7 +6,6 @@ */ import React, { FC, useCallback, useEffect, useState, useMemo } from 'react'; -import { PreloadedState } from '@reduxjs/toolkit'; import { AppMountParameters, CoreSetup, CoreStart } from '@kbn/core/public'; import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; import { RouteComponentProps } from 'react-router-dom'; @@ -48,10 +47,9 @@ import { navigateAway, LensRootStore, loadInitial, - LensAppState, - LensState, + setState, } from '../state_management'; -import { getPreloadedState, setState } from '../state_management/lens_slice'; +import { getPreloadedState } from '../state_management/lens_slice'; import { getLensInspectorService } from '../lens_inspector_service'; import { LensAppLocator, @@ -276,9 +274,7 @@ export async function mountApp( initialContext, initialStateFromLocator, }; - const lensStore: LensRootStore = makeConfigureStore(storeDeps, { - lens: getPreloadedState(storeDeps) as LensAppState, - } as unknown as PreloadedState); + const lensStore: LensRootStore = makeConfigureStore(storeDeps); const EditorRenderer = React.memo( (props: { id?: string; history: History; editByValue?: boolean }) => { @@ -322,7 +318,7 @@ export async function mountApp( data.query.filterManager.setAppFilters([]); data.query.queryString.clearQuery(); } - lensStore.dispatch(setState(getPreloadedState(storeDeps) as LensAppState)); + lensStore.dispatch(setState(getPreloadedState(storeDeps))); lensStore.dispatch(loadInitial({ redirectCallback, initialInput, history: props.history })); }, [initialInput, props.history, redirectCallback]); useEffect(() => { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx index 1ce4a777f9520..fe1e504637a66 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx @@ -5,30 +5,23 @@ * 2.0. */ -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { EuiFlyout, EuiLoadingSpinner, EuiOverlayMask } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Provider } from 'react-redux'; -import { PreloadedState } from '@reduxjs/toolkit'; +import { MiddlewareAPI, Dispatch, Action } from '@reduxjs/toolkit'; import { css } from '@emotion/react'; import type { CoreStart } from '@kbn/core/public'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { isEqual } from 'lodash'; import type { LensPluginStartDependencies } from '../../../plugin'; -import { - makeConfigureStore, - LensRootStore, - LensAppState, - LensState, - loadInitial, -} from '../../../state_management'; -import { getPreloadedState } from '../../../state_management/lens_slice'; +import { makeConfigureStore, LensRootStore, loadInitial } from '../../../state_management'; import { generateId } from '../../../id_generator'; import type { DatasourceMap, VisualizationMap } from '../../../types'; import { LensEditConfigurationFlyout, type EditConfigPanelProps, } from './lens_configuration_flyout'; -import type { LensAppServices } from '../../types'; export type EditLensConfigurationProps = Omit< EditConfigPanelProps, @@ -43,12 +36,39 @@ function LoadingSpinnerWithOverlay() { ); } -export function getEditLensConfiguration( +type UpdaterType = (datasourceState: unknown, visualizationState: unknown) => void; + +const updatingMiddleware = + (updater: UpdaterType) => (store: MiddlewareAPI) => (next: Dispatch) => (action: Action) => { + const { + datasourceStates: prevDatasourceStates, + visualization: prevVisualization, + activeDatasourceId: prevActiveDatasourceId, + } = store.getState().lens; + next(action); + const { datasourceStates, visualization, activeDatasourceId } = store.getState().lens; + if ( + !isEqual(prevDatasourceStates, datasourceStates) || + !isEqual(prevVisualization, visualization) || + prevActiveDatasourceId !== activeDatasourceId + ) { + updater(datasourceStates[activeDatasourceId].state, visualization.state); + } + }; + +export async function getEditLensConfiguration( coreStart: CoreStart, startDependencies: LensPluginStartDependencies, visualizationMap?: VisualizationMap, datasourceMap?: DatasourceMap ) { + const { getLensServices, getLensAttributeService } = await import('../../../async_services'); + const lensServices = await getLensServices( + coreStart, + startDependencies, + getLensAttributeService(coreStart, startDependencies) + ); + return ({ attributes, dataView, @@ -59,23 +79,6 @@ export function getEditLensConfiguration( adaptersTables, panelId, }: EditLensConfigurationProps) => { - const [lensServices, setLensServices] = useState(); - useEffect(() => { - async function loadLensService() { - const { getLensServices, getLensAttributeService } = await import( - '../../../async_services' - ); - const lensServicesT = await getLensServices( - coreStart, - startDependencies, - getLensAttributeService(coreStart, startDependencies) - ); - - setLensServices(lensServicesT); - } - loadLensService(); - }, []); - if (!lensServices || !datasourceMap || !visualizationMap || !dataView.id) { return ; } @@ -89,9 +92,11 @@ export function getEditLensConfiguration( ? datasourceState.initialContext : undefined, }; - const lensStore: LensRootStore = makeConfigureStore(storeDeps, { - lens: getPreloadedState(storeDeps) as LensAppState, - } as unknown as PreloadedState); + const lensStore: LensRootStore = makeConfigureStore( + storeDeps, + undefined, + updatingMiddleware(updateAll) + ); lensStore.dispatch( loadInitial({ initialInput: { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 24b84f7665c5a..4d7fd3bbf7031 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -93,7 +93,6 @@ export function LensEditConfigurationFlyout({ dataViews: startDependencies.dataViews, uiActions: startDependencies.uiActions, hideLayerHeader: datasourceId === 'textBased', - onUpdateStateCb: updateAll, }; return ( <> @@ -120,7 +119,6 @@ export function LensEditConfigurationFlyout({ diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx index 1d896d796edc1..c5ec748aa9bf0 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.test.tsx @@ -170,25 +170,18 @@ describe('ConfigPanel', () => { it('updates datasources and visualizations', async () => { const props = getDefaultProps(); - const onUpdateCbSpy = jest.fn(); - const newProps = { - ...props, - onUpdateStateCb: onUpdateCbSpy, - }; - const { instance, lensStore } = await prepareAndMountComponent(newProps); + const { instance, lensStore } = await prepareAndMountComponent(props); const { updateDatasource, updateAll } = instance.find(LayerPanel).props(); const newDatasourceState = 'updated'; updateDatasource('testDatasource', newDatasourceState); await waitMs(0); expect(lensStore.dispatch).toHaveBeenCalledTimes(1); - expect(onUpdateCbSpy).toHaveBeenCalled(); expect((lensStore.dispatch as jest.Mock).mock.calls[0][0].payload.newDatasourceState).toEqual( 'updated' ); updateAll('testDatasource', newDatasourceState, props.visualizationState); - expect(onUpdateCbSpy).toHaveBeenCalled(); // wait for one tick so async updater has a chance to trigger await waitMs(0); expect(lensStore.dispatch).toHaveBeenCalledTimes(3); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 523ce6dc856b8..2a7056c759fac 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -6,7 +6,6 @@ */ import React, { useMemo, memo, useCallback } from 'react'; -import { useStore } from 'react-redux'; import { EuiForm } from '@elastic/eui'; import { ActionExecutionContext } from '@kbn/ui-actions-plugin/public'; import { isOfAggregateQueryType } from '@kbn/es-query'; @@ -14,7 +13,7 @@ import { UPDATE_FILTER_REFERENCES_ACTION, UPDATE_FILTER_REFERENCES_TRIGGER, } from '@kbn/unified-search-plugin/public'; -import { isEqual } from 'lodash'; + import { DragDropIdentifier, DropType } from '@kbn/dom-drag-drop'; import { changeIndexPattern, @@ -58,8 +57,7 @@ export function LayerPanels( activeVisualization: Visualization; } ) { - const lensStore = useStore(); - const { activeVisualization, datasourceMap, indexPatternService, onUpdateStateCb } = props; + const { activeVisualization, datasourceMap, indexPatternService } = props; const { activeDatasourceId, visualization, datasourceStates, query } = useLensSelector( (state) => state.lens ); @@ -81,31 +79,19 @@ export function LayerPanels( newState, }) ); - if (onUpdateStateCb && activeDatasourceId) { - const dsState = datasourceStates[activeDatasourceId].state; - onUpdateStateCb?.(dsState, newState); - } }, - [activeDatasourceId, activeVisualization.id, datasourceStates, dispatchLens, onUpdateStateCb] + [activeVisualization.id, dispatchLens] ); const updateDatasource = useMemo( () => (datasourceId: string | undefined, newState: unknown, dontSyncLinkedDimensions?: boolean) => { if (datasourceId) { - const newDatasourceState = - typeof newState === 'function' - ? newState(datasourceStates[datasourceId].state) - : newState; - - if (isEqual(newDatasourceState, datasourceStates[datasourceId].state)) { - return; - } - - onUpdateStateCb?.(newDatasourceState, visualization.state); - dispatchLens( updateDatasourceState({ - newDatasourceState, + newDatasourceState: + typeof newState === 'function' + ? newState(datasourceStates[datasourceId].state) + : newState, datasourceId, clearStagedPreview: false, dontSyncLinkedDimensions, @@ -113,7 +99,7 @@ export function LayerPanels( ); } }, - [dispatchLens, onUpdateStateCb, visualization.state, datasourceStates] + [dispatchLens, datasourceStates] ); const updateDatasourceAsync = useMemo( () => (datasourceId: string | undefined, newState: unknown) => { @@ -148,8 +134,6 @@ export function LayerPanels( ? newVisualizationState(visualization.state) : newVisualizationState; - onUpdateStateCb?.(newDsState, newVisState); - dispatchLens( updateVisualizationState({ visualizationId: activeVisualization.id, @@ -166,7 +150,7 @@ export function LayerPanels( ); }, 0); }, - [dispatchLens, onUpdateStateCb, visualization.state, datasourceStates, activeVisualization.id] + [dispatchLens, visualization.state, datasourceStates, activeVisualization.id] ); const toggleFullscreen = useCallback(() => { @@ -207,24 +191,15 @@ export function LayerPanels( layerIds, }) ); - if (activeDatasourceId && onUpdateStateCb) { - const newState = lensStore.getState().lens; - onUpdateStateCb( - newState.datasourceStates[activeDatasourceId].state, - newState.visualization.state - ); - } + removeLayerRef(layerToRemoveId); }, [ - activeDatasourceId, activeVisualization.id, datasourceMap, datasourceStates, dispatchLens, layerIds, - lensStore, - onUpdateStateCb, props.framePublicAPI.datasourceLayers, props.uiActions, removeLayerRef, @@ -267,13 +242,6 @@ export function LayerPanels( dispatchLens(addLayerAction({ layerId, layerType, extraArg, ignoreInitialValues })); - if (activeDatasourceId && onUpdateStateCb) { - const newState = lensStore.getState().lens; - onUpdateStateCb( - newState.datasourceStates[activeDatasourceId].state, - newState.visualization.state - ); - } setNextFocusedLayerId(layerId); }; @@ -355,13 +323,6 @@ export function LayerPanels( const datasourcePublicAPI = props.framePublicAPI.datasourceLayers?.[layerId]; const datasourceId = datasourcePublicAPI?.datasourceId; dispatchLens(removeDimension({ ...dimensionProps, datasourceId })); - if (datasourceId && onUpdateStateCb) { - const newState = lensStore.getState().lens; - onUpdateStateCb( - newState.datasourceStates[datasourceId].state, - newState.visualization.state - ); - } }} toggleFullscreen={toggleFullscreen} indexPatternService={indexPatternService} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts index 994ba4b1b96cd..9b1ed7fde9382 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts @@ -29,7 +29,6 @@ export interface ConfigPanelWrapperProps { uiActions: UiActionsStart; getUserMessages?: UserMessagesGetter; hideLayerHeader?: boolean; - onUpdateStateCb?: (datasourceState: unknown, visualizationState: unknown) => void; } export interface LayerPanelProps { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx index 988bb0bb65592..3d90273ef0d14 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx @@ -383,15 +383,16 @@ describe('editor_frame', () => { hasDefaultTimeField: jest.fn(() => true), }; mockDatasource.getPublicAPI.mockReturnValue(updatedPublicAPI); + mockVisualization.getConfiguration.mockClear(); const setDatasourceState = (mockDatasource.DataPanelComponent as jest.Mock).mock.calls[0][0] .setState; act(() => { - setDatasourceState({}); + setDatasourceState('newState'); }); - expect(mockVisualization.getConfiguration).toHaveBeenCalledTimes(3); - expect(mockVisualization.getConfiguration).toHaveBeenLastCalledWith( + expect(mockVisualization.getConfiguration).toHaveBeenCalledTimes(1); + expect(mockVisualization.getConfiguration).toHaveBeenCalledWith( expect.objectContaining({ frame: expect.objectContaining({ datasourceLayers: { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx index 5695d746d69a2..18d0833ed4250 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx @@ -798,7 +798,7 @@ describe('workspace_panel', () => { lensStore.dispatch( updateDatasourceState({ datasourceId: 'testDatasource', - newDatasourceState: {}, + newDatasourceState: 'newState', }) ); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx index 9469a903131bd..ea2c8d27086fb 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx @@ -30,6 +30,7 @@ import { selectChangesApplied, applyChanges, selectAutoApplyEnabled, + selectVisualizationState, } from '../../../state_management'; import { WorkspaceTitle } from './title'; import { LensInspector } from '../../../lens_inspector_service'; @@ -52,13 +53,10 @@ export interface WorkspacePanelWrapperProps { export function VisualizationToolbar(props: { activeVisualization: Visualization | null; framePublicAPI: FramePublicAPI; - onUpdateStateCb?: (datasourceState: unknown, visualizationState: unknown) => void; }) { const dispatchLens = useLensDispatch(); - const { activeDatasourceId, visualization, datasourceStates } = useLensSelector( - (state) => state.lens - ); - const { activeVisualization, onUpdateStateCb } = props; + const visualization = useLensSelector(selectVisualizationState); + const { activeVisualization } = props; const setVisualizationState = useCallback( (newState: unknown) => { if (!activeVisualization) { @@ -70,12 +68,8 @@ export function VisualizationToolbar(props: { newState, }) ); - if (activeDatasourceId && onUpdateStateCb) { - const dsState = datasourceStates[activeDatasourceId].state; - onUpdateStateCb?.(dsState, newState); - } }, - [activeDatasourceId, datasourceStates, dispatchLens, activeVisualization, onUpdateStateCb] + [dispatchLens, activeVisualization] ); const ToolbarComponent = props.activeVisualization?.ToolbarComponent; diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index d586dd596f487..403ba51d72bc4 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -780,7 +780,7 @@ export class Embeddable async openConfingPanel(startDependencies: LensPluginStartDependencies) { const { getEditLensConfiguration } = await import('../async_services'); - const Component = getEditLensConfiguration( + const Component = await getEditLensConfiguration( this.deps.coreStart, startDependencies, this.deps.visualizationMap, diff --git a/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx b/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx index f526e46d8f5ec..dbac941720b4d 100644 --- a/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx +++ b/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx @@ -21,7 +21,9 @@ export const lensPluginMock = { SaveModalComponent: jest.fn(() => { return Lens Save Modal Component; }), - EditLensConfigPanelApi: jest.fn().mockResolvedValue(Lens Config Panel Component), + EditLensConfigPanelApi: jest + .fn() + .mockResolvedValue(() => Lens Config Panel Component), canUseEditor: jest.fn(() => true), navigateToPrefilledEditor: jest.fn(), getXyVisTypes: jest diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index 3f2559ce634be..14cd471a2a5bc 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -677,7 +677,13 @@ export class LensPlugin { this.editorFrameService!.loadVisualizations(), this.editorFrameService!.loadDatasources(), ]); - return getEditLensConfiguration(core, startDependencies, visualizationMap, datasourceMap); + const Component = await getEditLensConfiguration( + core, + startDependencies, + visualizationMap, + datasourceMap + ); + return Component; }, }; } diff --git a/x-pack/plugins/lens/public/state_management/context_middleware/index.test.ts b/x-pack/plugins/lens/public/state_management/context_middleware/index.test.ts index 19e40577acad6..24254f4469f54 100644 --- a/x-pack/plugins/lens/public/state_management/context_middleware/index.test.ts +++ b/x-pack/plugins/lens/public/state_management/context_middleware/index.test.ts @@ -57,7 +57,7 @@ describe('contextMiddleware', () => { }); const { next, invoke, store } = createMiddleware(data); const action = { - type: 'lens/setState', + type: 'lens/setExecutionContext', payload: { visualization: { state: {}, @@ -74,7 +74,7 @@ describe('contextMiddleware', () => { }, searchSessionId: 'sessionId-1', }, - type: 'lens/setState', + type: 'lens/setExecutionContext', }); expect(next).toHaveBeenCalledWith(action); }); @@ -92,7 +92,7 @@ describe('contextMiddleware', () => { }); const { next, invoke, store } = createMiddleware(data); const action = { - type: 'lens/setState', + type: 'lens/setExecutionContext', payload: { visualization: { state: {}, @@ -109,7 +109,7 @@ describe('contextMiddleware', () => { }, searchSessionId: 'sessionId-1', }, - type: 'lens/setState', + type: 'lens/setExecutionContext', }); expect(next).toHaveBeenCalledWith(action); }); @@ -136,7 +136,7 @@ describe('contextMiddleware', () => { // setState shouldn't trigger const setStateAction = { - type: 'lens/setState', + type: 'lens/setExecutionContext', payload: { visualization: { state: {}, @@ -146,14 +146,14 @@ describe('contextMiddleware', () => { }; invoke(setStateAction); expect(store.dispatch).not.toHaveBeenCalledWith( - expect.objectContaining({ type: 'lens/setState' }) + expect.objectContaining({ type: 'lens/setExecutionContext' }) ); // applyChanges should trigger const applyChangesAction = applyChanges(); invoke(applyChangesAction); expect(store.dispatch).toHaveBeenCalledWith( - expect.objectContaining({ type: 'lens/setState' }) + expect.objectContaining({ type: 'lens/setExecutionContext' }) ); }); }); @@ -171,7 +171,7 @@ describe('contextMiddleware', () => { }); const { next, invoke, store } = createMiddleware(data); const action = { - type: 'lens/setState', + type: 'lens/setExecutionContext', payload: { visualization: { state: {}, @@ -196,7 +196,7 @@ describe('contextMiddleware', () => { }); const { next, invoke, store } = createMiddleware(data); const action = { - type: 'lens/setState', + type: 'lens/setExecutionContext', payload: { visualization: { state: {}, diff --git a/x-pack/plugins/lens/public/state_management/context_middleware/index.ts b/x-pack/plugins/lens/public/state_management/context_middleware/index.ts index 7d1e6a0b48fba..f17863a25d42e 100644 --- a/x-pack/plugins/lens/public/state_management/context_middleware/index.ts +++ b/x-pack/plugins/lens/public/state_management/context_middleware/index.ts @@ -9,7 +9,7 @@ import { Dispatch, MiddlewareAPI, PayloadAction } from '@reduxjs/toolkit'; import moment from 'moment'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { - setState, + setExecutionContext, LensDispatch, LensStoreDeps, navigateAway, @@ -93,7 +93,7 @@ function updateTimeRange(data: DataPublicPluginStart, dispatch: LensDispatch) { // if the lag is significant, start a new session to clear the cache if (nowDiff > Math.max(timeRangeLength * TIME_LAG_PERCENTAGE_LIMIT, TIME_LAG_MIN_LIMIT)) { dispatch( - setState({ + setExecutionContext({ searchSessionId: data.search.session.start(), resolvedDateRange: getResolvedDateRange(timefilter), }) diff --git a/x-pack/plugins/lens/public/state_management/context_middleware/subscribe_to_external_context.ts b/x-pack/plugins/lens/public/state_management/context_middleware/subscribe_to_external_context.ts index abc3f388db5e9..3445e48df0a1b 100644 --- a/x-pack/plugins/lens/public/state_management/context_middleware/subscribe_to_external_context.ts +++ b/x-pack/plugins/lens/public/state_management/context_middleware/subscribe_to_external_context.ts @@ -8,7 +8,7 @@ import { delay, finalize, switchMap, tap } from 'rxjs/operators'; import { debounce, isEqual } from 'lodash'; import { waitUntilNextSessionCompletes$, DataPublicPluginStart } from '@kbn/data-plugin/public'; -import { setState, LensGetState, LensDispatch } from '..'; +import { setExecutionContext, LensGetState, LensDispatch } from '..'; import { getResolvedDateRange } from '../../utils'; /** @@ -21,14 +21,14 @@ export function subscribeToExternalContext( ) { const { query: queryService, search } = data; const { filterManager } = queryService; - const dispatchFromExternal = (searchSessionId = search.session.start()) => { const globalFilters = filterManager.getFilters(); const filters = isEqual(getState().lens.filters, globalFilters) ? null : { filters: globalFilters }; + dispatch( - setState({ + setExecutionContext({ searchSessionId, ...filters, resolvedDateRange: getResolvedDateRange(queryService.timefilter.timefilter), diff --git a/x-pack/plugins/lens/public/state_management/index.test.ts b/x-pack/plugins/lens/public/state_management/index.test.ts new file mode 100644 index 0000000000000..b38a9587eafdd --- /dev/null +++ b/x-pack/plugins/lens/public/state_management/index.test.ts @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Action, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit'; +import { makeConfigureStore, onActiveDataChange, setExecutionContext } from '.'; +import { mockStoreDeps } from '../mocks'; +import { TableInspectorAdapter } from '../editor_frame_service/types'; +import { Filter } from '@kbn/es-query'; + +describe('state management initialization and middlewares', () => { + let store: ReturnType; + const updaterFn = jest.fn(); + const customMiddleware = jest.fn( + (updater) => (_store: MiddlewareAPI) => (next: Dispatch) => (action: Action) => { + next(action); + updater(action); + } + ); + beforeEach(() => { + store = makeConfigureStore(mockStoreDeps(), undefined, customMiddleware(updaterFn)); + store.dispatch = jest.fn(store.dispatch); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('customMiddleware', () => { + test('customMiddleware is initialized on store creation', () => { + expect(customMiddleware).toHaveBeenCalled(); + expect(updaterFn).not.toHaveBeenCalled(); + }); + test('customMiddleware is run on action dispatch', () => { + store.dispatch({ type: 'ANY_TYPE' }); + expect(updaterFn).toHaveBeenCalledWith({ type: 'ANY_TYPE' }); + }); + }); + + describe('optimizingMiddleware', () => { + test('state is updating when the activeData changes', () => { + expect(store.getState().lens.activeData).toEqual(undefined); + store.dispatch( + onActiveDataChange({ activeData: { id: 1 } as unknown as TableInspectorAdapter }) + ); + expect(store.getState().lens.activeData).toEqual({ id: 1 }); + // this is a bit convoluted - we are checking that the updaterFn has been called because it's called (as the next middleware) + // before the reducer function but we're actually interested in the reducer function being called that's further down the pipeline + expect(updaterFn).toHaveBeenCalledTimes(1); + store.dispatch( + onActiveDataChange({ activeData: { id: 2 } as unknown as TableInspectorAdapter }) + ); + expect(store.getState().lens.activeData).toEqual({ id: 2 }); + expect(updaterFn).toHaveBeenCalledTimes(2); + }); + test('state is not updating when the payload activeData is the same as in state', () => { + store.dispatch( + onActiveDataChange({ activeData: { id: 1 } as unknown as TableInspectorAdapter }) + ); + expect(store.getState().lens.activeData).toEqual({ id: 1 }); + expect(updaterFn).toHaveBeenCalledTimes(1); + store.dispatch( + onActiveDataChange({ activeData: { id: 1 } as unknown as TableInspectorAdapter }) + ); + expect(store.getState().lens.activeData).toEqual({ id: 1 }); + expect(updaterFn).toHaveBeenCalledTimes(1); + }); + test('state is updating when the execution context changes', () => { + expect(store.getState().lens.filters).toEqual([]); + expect(store.getState().lens.query).toEqual({ language: 'lucene', query: '' }); + expect(store.getState().lens.searchSessionId).toEqual(''); + store.dispatch( + setExecutionContext({ + filters: ['filter'] as unknown as Filter[], + query: { language: 'lucene', query: 'query' }, + searchSessionId: 'searchSessionId', + }) + ); + expect(store.getState().lens.filters).toEqual(['filter']); + expect(store.getState().lens.query).toEqual({ language: 'lucene', query: 'query' }); + expect(store.getState().lens.searchSessionId).toEqual('searchSessionId'); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/state_management/index.ts b/x-pack/plugins/lens/public/state_management/index.ts index 6bfa0744fa54e..6f170219df744 100644 --- a/x-pack/plugins/lens/public/state_management/index.ts +++ b/x-pack/plugins/lens/public/state_management/index.ts @@ -5,10 +5,17 @@ * 2.0. */ -import { configureStore, getDefaultMiddleware, PreloadedState } from '@reduxjs/toolkit'; +import { + configureStore, + getDefaultMiddleware, + PreloadedState, + Action, + Dispatch, + MiddlewareAPI, +} from '@reduxjs/toolkit'; import { createLogger } from 'redux-logger'; import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux'; -import { makeLensReducer, lensActions } from './lens_slice'; +import { makeLensReducer, lensActions, getPreloadedState } from './lens_slice'; import { LensState, LensStoreDeps } from './types'; import { initMiddleware } from './init_middleware'; import { optimizingMiddleware } from './optimizing_middleware'; @@ -19,7 +26,10 @@ export * from './selectors'; export const { loadInitial, + initEmpty, + initExisting, navigateAway, + setExecutionContext, setState, enableAutoApply, disableAutoApply, @@ -36,7 +46,6 @@ export const { switchAndCleanDatasource, updateIndexPatterns, setToggleFullscreen, - initEmpty, editVisualizationAction, removeLayers, removeOrClearLayer, @@ -50,9 +59,12 @@ export const { changeIndexPattern, } = lensActions; +type CustomMiddleware = (store: MiddlewareAPI) => (next: Dispatch) => (action: Action) => void; + export const makeConfigureStore = ( storeDeps: LensStoreDeps, - preloadedState: PreloadedState + preloadedState?: PreloadedState | undefined, + customMiddleware?: CustomMiddleware ) => { const middleware = [ ...getDefaultMiddleware({ @@ -70,10 +82,13 @@ export const makeConfigureStore = ( }, }), initMiddleware(storeDeps), - optimizingMiddleware(), contextMiddleware(storeDeps), fullscreenMiddleware(storeDeps), + optimizingMiddleware(), ]; + if (customMiddleware) { + middleware.push(customMiddleware); + } if (process.env.NODE_ENV === 'development') { middleware.push( createLogger({ @@ -88,7 +103,9 @@ export const makeConfigureStore = ( lens: makeLensReducer(storeDeps), }, middleware, - preloadedState, + preloadedState: preloadedState ?? { + lens: getPreloadedState(storeDeps), + }, }); }; diff --git a/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts b/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts index 59e022345c603..df7da58cfa5e7 100644 --- a/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts +++ b/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts @@ -9,7 +9,7 @@ import { cloneDeep } from 'lodash'; import { MiddlewareAPI } from '@reduxjs/toolkit'; import { i18n } from '@kbn/i18n'; import { History } from 'history'; -import { setState, initEmpty, LensStoreDeps } from '..'; +import { setState, initExisting, initEmpty, LensStoreDeps } from '..'; import { disableAutoApply, getPreloadedState } from '../lens_slice'; import { SharingSavedObjectProps } from '../../types'; import { LensEmbeddableInput, LensByReferenceInput } from '../../embeddable/embeddable'; @@ -171,7 +171,7 @@ export function loadInitial( const currentSessionId = initialStateFromLocator?.searchSessionId || data.search.session.getSessionId(); store.dispatch( - setState({ + initExisting({ isSaveable: true, filters: initialStateFromLocator.filters || data.query.filterManager.getFilters(), query: initialStateFromLocator.query || emptyState.query, @@ -331,7 +331,7 @@ export function loadInitial( }) => { const currentSessionId = data.search.session.getSessionId(); store.dispatch( - setState({ + initExisting({ isSaveable: true, sharingSavedObjectProps, filters: data.query.filterManager.getFilters(), diff --git a/x-pack/plugins/lens/public/state_management/lens_slice.ts b/x-pack/plugins/lens/public/state_management/lens_slice.ts index d90f0d7a2a05e..ffc22d68f9e4c 100644 --- a/x-pack/plugins/lens/public/state_management/lens_slice.ts +++ b/x-pack/plugins/lens/public/state_management/lens_slice.ts @@ -8,7 +8,7 @@ import { createAction, createReducer, current, PayloadAction } from '@reduxjs/toolkit'; import { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; import { mapValues, uniq } from 'lodash'; -import { Query } from '@kbn/es-query'; +import { Filter, Query } from '@kbn/es-query'; import { History } from 'history'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; import { EventAnnotationGroupConfig } from '@kbn/event-annotation-common'; @@ -27,7 +27,7 @@ import { getInitialDatasourceId, getResolvedDateRange, getRemoveOperation } from import type { DataViewsState, LensAppState, LensStoreDeps, VisualizationState } from './types'; import type { Datasource, Visualization } from '../types'; import { generateId } from '../id_generator'; -import type { LayerType } from '../../common/types'; +import type { DateRange, LayerType } from '../../common/types'; import { getVisualizeFieldSuggestions } from '../editor_frame_service/editor_frame/suggestion_helpers'; import type { FramePublicAPI, LensEditContextMapping, LensEditEvent } from '../types'; import { selectDataViews, selectFramePublicAPI } from './selectors'; @@ -113,7 +113,7 @@ export const getPreloadedState = ({ ? data.query.queryString.getDefaultQuery() : getQueryFromContext(initialContext, data); - const state = { + const state: LensAppState = { ...initialState, isLoading: true, // Do not use app-specific filters from previous app, @@ -124,7 +124,7 @@ export const getPreloadedState = ({ : 'searchFilters' in initialContext && initialContext.searchFilters ? initialContext.searchFilters : data.query.filterManager.getFilters(), - searchSessionId: data.search.session.getSessionId(), + searchSessionId: data.search.session.getSessionId() || '', resolvedDateRange: getResolvedDateRange(data.query.timefilter.timefilter), isLinkedToOriginatingApp: Boolean( embeddableEditorIncomingState?.originatingApp || @@ -140,7 +140,18 @@ export const getPreloadedState = ({ return state; }; +export interface SetExecutionContextPayload { + query?: Query; + filters?: Filter[]; + searchSessionId?: string; + resolvedDateRange?: DateRange; +} + export const setState = createAction>('lens/setState'); +export const setExecutionContext = createAction( + 'lens/setExecutionContext' +); +export const initExisting = createAction>('lens/initExisting'); export const onActiveDataChange = createAction<{ activeData: TableInspectorAdapter; }>('lens/onActiveDataChange'); @@ -268,7 +279,9 @@ export const registerLibraryAnnotationGroup = createAction<{ }>('lens/registerLibraryAnnotationGroup'); export const lensActions = { + initExisting, setState, + setExecutionContext, onActiveDataChange, setSaveable, enableAutoApply, @@ -312,6 +325,18 @@ export const makeLensReducer = (storeDeps: LensStoreDeps) => { ...payload, }; }, + [setExecutionContext.type]: (state, { payload }: PayloadAction) => { + return { + ...state, + ...payload, + }; + }, + [initExisting.type]: (state, { payload }: PayloadAction>) => { + return { + ...state, + ...payload, + }; + }, [onActiveDataChange.type]: ( state, { payload: { activeData } }: PayloadAction<{ activeData: TableInspectorAdapter }> diff --git a/x-pack/plugins/lens/public/state_management/optimizing_middleware.ts b/x-pack/plugins/lens/public/state_management/optimizing_middleware.ts index 9c8fe99c38aea..7187419cb438b 100644 --- a/x-pack/plugins/lens/public/state_management/optimizing_middleware.ts +++ b/x-pack/plugins/lens/public/state_management/optimizing_middleware.ts @@ -7,7 +7,8 @@ import { Dispatch, MiddlewareAPI, Action } from '@reduxjs/toolkit'; import { isEqual } from 'lodash'; -import { onActiveDataChange } from '.'; +import { onActiveDataChange, updateDatasourceState, setExecutionContext } from '.'; +import { SetExecutionContextPayload } from './lens_slice'; /** cancels updates to the store that don't change the state */ export const optimizingMiddleware = () => (store: MiddlewareAPI) => { @@ -16,7 +17,30 @@ export const optimizingMiddleware = () => (store: MiddlewareAPI) => { if (isEqual(store.getState().lens.activeData, action.payload.activeData)) { return; } + } else if (updateDatasourceState.match(action)) { + const { datasourceId, newDatasourceState } = action.payload; + const { datasourceStates } = store.getState().lens; + if (isEqual(datasourceStates[datasourceId].state, newDatasourceState)) { + return; + } + } else if (setExecutionContext.match(action)) { + const payloadKeys = Object.keys(action.payload); + const prevState = store.getState().lens; + const stateSliceToUpdate = payloadKeys.reduce( + (acc, currentKey) => { + return { + ...acc, + [currentKey]: prevState[currentKey], + }; + }, + {} + ); + + if (isEqual(action.payload, stateSliceToUpdate)) { + return; + } } + next(action); }; }; diff --git a/x-pack/plugins/lens/public/state_management/types.ts b/x-pack/plugins/lens/public/state_management/types.ts index 2ba00df37d73b..c2d0e1ef2e386 100644 --- a/x-pack/plugins/lens/public/state_management/types.ts +++ b/x-pack/plugins/lens/public/state_management/types.ts @@ -67,11 +67,6 @@ export interface LensAppState extends EditorFrameState { annotationGroups: AnnotationGroups; } -export type DispatchSetState = (state: Partial) => { - payload: Partial; - type: string; -}; - export interface LensState { lens: LensAppState; } diff --git a/x-pack/plugins/reporting/common/constants/index.ts b/x-pack/plugins/reporting/common/constants/index.ts index 1a3cbde98f838..85ce65eb4691a 100644 --- a/x-pack/plugins/reporting/common/constants/index.ts +++ b/x-pack/plugins/reporting/common/constants/index.ts @@ -55,12 +55,12 @@ export const USES_HEADLESS_JOB_TYPES = [ export const DEPRECATED_JOB_TYPES = [CSV_JOB_TYPE_DEPRECATED]; // Licenses -export const LICENSE_TYPE_TRIAL = 'trial'; -export const LICENSE_TYPE_BASIC = 'basic'; -export const LICENSE_TYPE_CLOUD_STANDARD = 'standard'; -export const LICENSE_TYPE_GOLD = 'gold'; -export const LICENSE_TYPE_PLATINUM = 'platinum'; -export const LICENSE_TYPE_ENTERPRISE = 'enterprise'; +export const LICENSE_TYPE_TRIAL = 'trial' as const; +export const LICENSE_TYPE_BASIC = 'basic' as const; +export const LICENSE_TYPE_CLOUD_STANDARD = 'standard' as const; +export const LICENSE_TYPE_GOLD = 'gold' as const; +export const LICENSE_TYPE_PLATINUM = 'platinum' as const; +export const LICENSE_TYPE_ENTERPRISE = 'enterprise' as const; // Routes export const API_BASE_URL = '/api/reporting'; // "Generation URL" from share menu diff --git a/x-pack/plugins/reporting/server/core.ts b/x-pack/plugins/reporting/server/core.ts index 477fd4afab61b..76320405e9ebe 100644 --- a/x-pack/plugins/reporting/server/core.ts +++ b/x-pack/plugins/reporting/server/core.ts @@ -8,20 +8,16 @@ import type { CoreSetup, DocLinksServiceSetup, - FakeRawRequest, - Headers, IBasePath, IClusterClient, KibanaRequest, Logger, PackageInfo, PluginInitializerContext, - SavedObjectsClientContract, SavedObjectsServiceStart, StatusServiceSetup, UiSettingsServiceStart, } from '@kbn/core/server'; -import { CoreKibanaRequest } from '@kbn/core/server'; import type { PluginStart as DataPluginStart } from '@kbn/data-plugin/server'; import type { DiscoverServerPluginStart } from '@kbn/discover-plugin/server'; import type { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; @@ -34,7 +30,7 @@ import { ScreenshottingStart, } from '@kbn/screenshotting-plugin/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; -import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants'; +import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import type { SpacesPluginSetup } from '@kbn/spaces-plugin/server'; import type { TaskManagerSetupContract, @@ -46,11 +42,19 @@ import { map, switchMap, take } from 'rxjs/operators'; import type { ReportingSetup } from '.'; import { REPORTING_REDIRECT_LOCATOR_STORE_KEY } from '../common/constants'; import { createConfig, ReportingConfigType } from './config'; -import { checkLicense, getExportTypesRegistry } from './lib'; +import { CsvSearchSourceExportType } from './export_types/csv_searchsource'; +import { CsvV2ExportType } from './export_types/csv_v2'; +import { PdfV1ExportType } from './export_types/printable_pdf'; +import { PdfExportType } from './export_types/printable_pdf_v2'; +import { PngV1ExportType } from './export_types/png'; +import { PngExportType } from './export_types/png_v2'; +import { checkLicense, ExportTypesRegistry } from './lib'; import { reportingEventLoggerFactory } from './lib/event_logger/logger'; import type { IReport, ReportingStore } from './lib/store'; import { ExecuteReportTask, MonitorReportsTask, ReportTaskParams } from './lib/tasks'; import type { PdfScreenshotOptions, PngScreenshotOptions, ReportingPluginRouter } from './types'; +import { CsvSearchSourceImmediateExportType } from './export_types/csv_searchsource_immediate'; +import { ExportType } from './export_types/common'; export interface ReportingInternalSetup { basePath: Pick; @@ -102,11 +106,12 @@ export class ReportingCore { private readonly pluginSetup$ = new Rx.ReplaySubject(); // observe async background setupDeps each are done private readonly pluginStart$ = new Rx.ReplaySubject(); // observe async background startDeps private deprecatedAllowedRoles: string[] | false = false; // DEPRECATED. If `false`, the deprecated features have been disableed - private exportTypesRegistry = getExportTypesRegistry(); private executeTask: ExecuteReportTask; private monitorTask: MonitorReportsTask; private config: ReportingConfigType; private executing: Set; + private exportTypes: ExportType[] = []; + private exportTypesRegistry = new ExportTypesRegistry(); public getContract: () => ReportingSetup; @@ -121,6 +126,21 @@ export class ReportingCore { const config = createConfig(core, context.config.get(), logger); this.config = config; + // Export Type declarations + this.exportTypes.push( + new CsvSearchSourceExportType(this.core, this.config, this.logger, this.context) + ); + this.exportTypes.push(new CsvV2ExportType(this.core, this.config, this.logger, this.context)); + this.exportTypes.push(new PdfExportType(this.core, this.config, this.logger, this.context)); + this.exportTypes.push(new PngExportType(this.core, this.config, this.logger, this.context)); + // deprecated export types for tests + this.exportTypes.push(new PdfV1ExportType(this.core, this.config, this.logger, this.context)); + this.exportTypes.push(new PngV1ExportType(this.core, this.config, this.logger, this.context)); + + this.exportTypes.forEach((et) => { + this.exportTypesRegistry.register(et); + }); + this.deprecatedAllowedRoles = config.roles.enabled ? config.roles.allow : false; this.executeTask = new ExecuteReportTask(this, config, this.logger); this.monitorTask = new MonitorReportsTask(this, config, this.logger); @@ -128,6 +148,8 @@ export class ReportingCore { this.getContract = () => ({ usesUiCapabilities: () => config.roles.enabled === false, registerExportTypes: (id) => id, + getScreenshots: this.getScreenshots.bind(this), + getSpaceId: this.getSpaceId.bind(this), }); this.executing = new Set(); @@ -144,6 +166,10 @@ export class ReportingCore { this.pluginSetup$.next(true); // trigger the observer this.pluginSetupDeps = setupDeps; // cache + this.exportTypes.forEach((et) => { + et.setup(setupDeps); + }); + const { executeTask, monitorTask } = this; setupDeps.taskManager.registerTaskDefinitions({ [executeTask.TYPE]: executeTask.getTaskDefinition(), @@ -158,6 +184,10 @@ export class ReportingCore { this.pluginStart$.next(startDeps); // trigger the observer this.pluginStartDeps = startDeps; // cache + this.exportTypes.forEach((et) => { + et.start({ ...startDeps, reporting: this.getContract() }); + }); + const { taskManager } = startDeps; const { executeTask, monitorTask } = this; // enable this instance to generate reports and to monitor for pending reports @@ -322,63 +352,6 @@ export class ReportingCore { return this.pluginSetupDeps; } - private async getSavedObjectsClient(request: KibanaRequest) { - const { savedObjects } = await this.getPluginStartDeps(); - return savedObjects.getScopedClient(request) as SavedObjectsClientContract; - } - - public async getUiSettingsServiceFactory(savedObjectsClient: SavedObjectsClientContract) { - const { uiSettings: uiSettingsService } = await this.getPluginStartDeps(); - const scopedUiSettingsService = uiSettingsService.asScopedToClient(savedObjectsClient); - return scopedUiSettingsService; - } - - public getSpaceId(request: KibanaRequest, logger = this.logger): string | undefined { - const spacesService = this.getPluginSetupDeps().spaces?.spacesService; - if (spacesService) { - const spaceId = spacesService?.getSpaceId(request); - - if (spaceId !== DEFAULT_SPACE_ID) { - logger.info(`Request uses Space ID: ${spaceId}`); - return spaceId; - } else { - logger.debug(`Request uses default Space`); - } - } - } - - public getFakeRequest( - headers: Headers, - spaceId: string | undefined, - logger = this.logger - ): KibanaRequest { - const rawRequest: FakeRawRequest = { - headers, - path: '/', - }; - const fakeRequest = CoreKibanaRequest.from(rawRequest); - - const spacesService = this.getPluginSetupDeps().spaces?.spacesService; - if (spacesService) { - if (spaceId && spaceId !== DEFAULT_SPACE_ID) { - logger.info(`Generating request for space: ${spaceId}`); - this.getPluginSetupDeps().basePath.set(fakeRequest, `/s/${spaceId}`); - } - } - - return fakeRequest; - } - - public async getUiSettingsClient(request: KibanaRequest, logger = this.logger) { - const spacesService = this.getPluginSetupDeps().spaces?.spacesService; - const spaceId = this.getSpaceId(request, logger); - if (spacesService && spaceId) { - logger.info(`Creating UI Settings Client for space: ${spaceId}`); - } - const savedObjectsClient = await this.getSavedObjectsClient(request); - return await this.getUiSettingsServiceFactory(savedObjectsClient); - } - public async getDataViewsService(request: KibanaRequest) { const { savedObjects } = await this.getPluginStartDeps(); const savedObjectsClient = savedObjects.getScopedClient(request); @@ -399,6 +372,20 @@ export class ReportingCore { return startDeps.esClient; } + public getSpaceId(request: KibanaRequest, logger = this.logger): string | undefined { + const spacesService = this.getPluginSetupDeps().spaces?.spacesService; + if (spacesService) { + const spaceId = spacesService?.getSpaceId(request); + + if (spaceId !== DEFAULT_SPACE_ID) { + logger.info(`Request uses Space ID: ${spaceId}`); + return spaceId; + } else { + logger.debug(`Request uses default Space`); + } + } + } + public getScreenshots(options: PdfScreenshotOptions): Rx.Observable; public getScreenshots(options: PngScreenshotOptions): Rx.Observable; public getScreenshots( @@ -434,4 +421,18 @@ export class ReportingCore { const ReportingEventLogger = reportingEventLoggerFactory(this.logger); return new ReportingEventLogger(report, task); } + + public async getCsvSearchSourceImmediate() { + const startDeps = await this.getPluginStartDeps(); + + const csvImmediateExport = new CsvSearchSourceImmediateExportType( + this.core, + this.config, + this.logger, + this.context + ); + csvImmediateExport.setup(this.getPluginSetupDeps()); + csvImmediateExport.start({ ...startDeps, reporting: this.getContract() }); + return csvImmediateExport; + } } diff --git a/x-pack/plugins/reporting/server/export_types/common/export_type.ts b/x-pack/plugins/reporting/server/export_types/common/export_type.ts new file mode 100644 index 0000000000000..dd9ad3a5a20ab --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/common/export_type.ts @@ -0,0 +1,140 @@ +/* + * Copyright 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 { + IBasePath, + Headers, + Logger, + CoreKibanaRequest, + CoreSetup, + FakeRawRequest, + HttpServiceSetup, + KibanaRequest, + PluginInitializerContext, + SavedObjectsClientContract, + SavedObjectsServiceStart, + UiSettingsServiceStart, + IClusterClient, +} from '@kbn/core/server'; +import { LicenseType } from '@kbn/licensing-plugin/common/types'; +import { ScreenshottingStart } from '@kbn/screenshotting-plugin/server'; +import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; +import { SpacesPluginSetup } from '@kbn/spaces-plugin/server'; +import { ReportingConfigType } from '../../config'; +import { ReportingServerInfo } from '../../core'; +import { CreateJobFn, ReportingStart, RunTaskFn } from '../../types'; + +export interface BaseExportTypeSetupDeps { + basePath: Pick; + spaces?: SpacesPluginSetup; +} + +export interface BaseExportTypeStartDeps { + savedObjects: SavedObjectsServiceStart; + uiSettings: UiSettingsServiceStart; + esClient: IClusterClient; + screenshotting: ScreenshottingStart; + reporting: ReportingStart; +} + +export abstract class ExportType< + JobParamsType extends object = any, + TaskPayloadType extends object = any, + SetupDepsType extends BaseExportTypeSetupDeps = BaseExportTypeSetupDeps, + StartDepsType extends BaseExportTypeStartDeps = BaseExportTypeStartDeps +> { + abstract id: string; // ID for exportTypesRegistry.getById() + abstract name: string; // user-facing string + abstract jobType: string; // for job params + + abstract jobContentEncoding?: 'base64' | 'csv'; + abstract jobContentExtension: 'pdf' | 'png' | 'csv'; + + abstract createJob: CreateJobFn; + abstract runTask: RunTaskFn; + + abstract validLicenses: LicenseType[]; + + public setupDeps!: SetupDepsType; + public startDeps!: StartDepsType; + public http!: HttpServiceSetup; + + constructor( + core: CoreSetup, + public config: ReportingConfigType, + public logger: Logger, + public context: PluginInitializerContext + ) { + this.http = core.http; + } + + setup(setupDeps: SetupDepsType) { + this.setupDeps = setupDeps; + } + start(startDeps: StartDepsType) { + this.startDeps = startDeps; + } + + private async getSavedObjectsClient(request: KibanaRequest) { + const { savedObjects } = this.startDeps; + return savedObjects.getScopedClient(request) as SavedObjectsClientContract; + } + + // needed to be protected vs private for the csv search source immediate export type + protected getUiSettingsServiceFactory(savedObjectsClient: SavedObjectsClientContract) { + const { uiSettings: uiSettingsService } = this.startDeps; + const scopedUiSettingsService = uiSettingsService.asScopedToClient(savedObjectsClient); + return scopedUiSettingsService; + } + + protected async getUiSettingsClient(request: KibanaRequest, logger = this.logger) { + const spacesService = this.setupDeps.spaces?.spacesService; + const spaceId = this.startDeps.reporting.getSpaceId(request, logger); + + if (spacesService && spaceId) { + logger.info(`Creating UI Settings Client for space: ${spaceId}`); + } + const savedObjectsClient = await this.getSavedObjectsClient(request); + return this.getUiSettingsServiceFactory(savedObjectsClient); + } + + protected getFakeRequest( + headers: Headers, + spaceId: string | undefined, + logger = this.logger + ): KibanaRequest { + const rawRequest: FakeRawRequest = { + headers, + path: '/', + }; + const fakeRequest = CoreKibanaRequest.from(rawRequest); + + const spacesService = this.setupDeps.spaces?.spacesService; + if (spacesService) { + if (spaceId && spaceId !== DEFAULT_SPACE_ID) { + logger.info(`Generating request for space: ${spaceId}`); + this.setupDeps.basePath.set(fakeRequest, `/s/${spaceId}`); + } + } + return fakeRequest; + } + + /* + * Returns configurable server info + */ + protected getServerInfo(): ReportingServerInfo { + const serverInfo = this.http.getServerInfo(); + return { + basePath: this.http.basePath.serverBasePath, + hostname: serverInfo.hostname, + name: serverInfo.name, + port: serverInfo.port, + uuid: this.context.env.instanceUuid, + protocol: serverInfo.protocol, + }; + } +} diff --git a/x-pack/plugins/reporting/server/export_types/common/index.ts b/x-pack/plugins/reporting/server/export_types/common/index.ts index c9589d5262059..b81226b9c6112 100644 --- a/x-pack/plugins/reporting/server/export_types/common/index.ts +++ b/x-pack/plugins/reporting/server/export_types/common/index.ts @@ -10,6 +10,8 @@ export { getFullUrls } from './get_full_urls'; export { validateUrls } from './validate_urls'; export { generatePngObservable } from './generate_png'; export { getCustomLogo } from './get_custom_logo'; +export { ExportType } from './export_type'; +export type { BaseExportTypeSetupDeps, BaseExportTypeStartDeps } from './export_type'; export interface TimeRangeParams { min?: Date | string | number | null; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/create_job.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/create_job.ts deleted file mode 100644 index a2d89be1e0008..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/create_job.ts +++ /dev/null @@ -1,16 +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 { CreateJobFn, CreateJobFnFactory } from '../../types'; -import { JobParamsCSV, TaskPayloadCSV } from './types'; - -export const createJobFnFactory: CreateJobFnFactory> = - function createJobFactoryFn() { - return async function createJob(jobParams) { - return jobParams; - }; - }; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/csv_searchsource.test.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/csv_searchsource.test.ts new file mode 100644 index 0000000000000..6596fc41d66d8 --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/csv_searchsource.test.ts @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +jest.mock('@kbn/generate-csv', () => ({ + CsvGenerator: class CsvGeneratorMock { + generateData() { + return { + size: 123, + content_type: 'text/csv', + }; + } + }, +})); + +import nodeCrypto from '@elastic/node-crypto'; +import { coreMock, elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { Writable } from 'stream'; +import { ReportingCore } from '../..'; +import { CancellationToken } from '@kbn/reporting-common'; +import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; +import { CsvSearchSourceExportType } from './csv_searchsource'; +import { discoverPluginMock } from '@kbn/discover-plugin/server/mocks'; +import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; +import { createMockScreenshottingStart } from '@kbn/screenshotting-plugin/server/mock'; + +const mockLogger = loggingSystemMock.createLogger(); +const encryptionKey = 'tetkey'; +const headers = { sid: 'cooltestheaders' }; +let encryptedHeaders: string; +let mockReportingCore: ReportingCore; +let stream: jest.Mocked; +let mockCsvSearchSourceExportType: CsvSearchSourceExportType; + +beforeAll(async () => { + const crypto = nodeCrypto({ encryptionKey }); + + encryptedHeaders = await crypto.encrypt(headers); + const configType = createMockConfigSchema({ + encryptionKey, + csv: { + checkForFormulas: true, + escapeFormulaValues: true, + maxSizeBytes: 180000, + scroll: { size: 500, duration: '30s' }, + }, + }); + const mockCoreSetup = coreMock.createSetup(); + const mockCoreStart = coreMock.createStart(); + const context = coreMock.createPluginInitializerContext(configType); + + mockReportingCore = await createMockReportingCore(configType); + + mockCsvSearchSourceExportType = new CsvSearchSourceExportType( + mockCoreSetup, + configType, + mockLogger, + context + ); + + mockCsvSearchSourceExportType.setup({ + basePath: { set: jest.fn() }, + }); + + mockCsvSearchSourceExportType.start({ + esClient: elasticsearchServiceMock.createClusterClient(), + savedObjects: mockCoreStart.savedObjects, + uiSettings: mockCoreStart.uiSettings, + discover: discoverPluginMock.createStartContract(), + data: dataPluginMock.createStartContract(), + screenshotting: createMockScreenshottingStart(), + reporting: mockReportingCore.getContract(), + }); +}); + +beforeEach(() => { + stream = {} as typeof stream; +}); + +test('gets the csv content from job parameters', async () => { + const payload = await mockCsvSearchSourceExportType.runTask( + 'cool-job-id', + { + headers: encryptedHeaders, + browserTimezone: 'US/Alaska', + searchSource: {}, + objectType: 'search', + title: 'Test Search', + version: '7.13.0', + }, + new CancellationToken(), + stream + ); + + expect(payload).toMatchInlineSnapshot(` + Object { + "content_type": "text/csv", + "size": 123, + } + `); +}); diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/csv_searchsource.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/csv_searchsource.ts new file mode 100644 index 0000000000000..3847c9b45c197 --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/csv_searchsource.ts @@ -0,0 +1,100 @@ +/* + * Copyright 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 { DataPluginStart } from '@kbn/data-plugin/server/plugin'; +import { DiscoverServerPluginStart } from '@kbn/discover-plugin/server'; +import { CsvGenerator } from '@kbn/generate-csv'; +import { CancellationToken } from '@kbn/reporting-common'; +import { Writable } from 'stream'; +import { + CSV_JOB_TYPE, + LICENSE_TYPE_BASIC, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_TRIAL, +} from '../../../common/constants'; +import { getFieldFormats } from '../../services'; +import { ExportType, BaseExportTypeSetupDeps, BaseExportTypeStartDeps } from '../common'; +import { decryptJobHeaders } from '../common/decrypt_job_headers'; +import { JobParamsCSV, TaskPayloadCSV } from './types'; + +type CsvSearchSourceExportTypeSetupDeps = BaseExportTypeSetupDeps; +interface CsvSearchSourceExportTypeStartDeps extends BaseExportTypeStartDeps { + discover: DiscoverServerPluginStart; + data: DataPluginStart; +} + +export class CsvSearchSourceExportType extends ExportType< + JobParamsCSV, + TaskPayloadCSV, + CsvSearchSourceExportTypeSetupDeps, + CsvSearchSourceExportTypeStartDeps +> { + id = 'csv_searchsource'; + name = CSV_JOB_TYPE; + jobType = CSV_JOB_TYPE; + jobContentEncoding = 'base64' as const; + jobContentExtension = 'csv' as const; + validLicenses = [ + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_BASIC, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + ]; + + constructor(...args: ConstructorParameters) { + super(...args); + this.logger = this.logger.get('csv-searchsource-export'); + } + + public createJob = async (jobParams: JobParamsCSV) => { + return { ...jobParams }; + }; + + public runTask = async ( + jobId: string, + job: TaskPayloadCSV, + cancellationToken: CancellationToken, + stream: Writable + ) => { + const { encryptionKey, csv: csvConfig } = this.config; + const logger = this.logger.get(`execute-job:${jobId}`); + const headers = await decryptJobHeaders(encryptionKey, job.headers, logger); + const fakeRequest = this.getFakeRequest(headers, job.spaceId, logger); + const uiSettings = await this.getUiSettingsClient(fakeRequest, logger); + const dataPluginStart = this.startDeps.data; + const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); + + const es = this.startDeps.esClient.asScoped(fakeRequest); + const searchSourceStart = await dataPluginStart.search.searchSource.asScoped(fakeRequest); + + const clients = { + uiSettings, + data: dataPluginStart.search.asScoped(fakeRequest), + es, + }; + const dependencies = { + searchSourceStart, + fieldFormatsRegistry, + }; + + const csv = new CsvGenerator( + job, + csvConfig, + clients, + dependencies, + cancellationToken, + logger, + stream + ); + return await csv.generateData(); + }; +} diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/execute_job.test.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/execute_job.test.ts deleted file mode 100644 index dd59c07dc72c4..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/execute_job.test.ts +++ /dev/null @@ -1,78 +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. - */ - -jest.mock('@kbn/generate-csv', () => ({ - CsvGenerator: class CsvGeneratorMock { - generateData() { - return { - size: 123, - content_type: 'text/csv', - }; - } - }, -})); - -import nodeCrypto from '@elastic/node-crypto'; -import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { Writable } from 'stream'; -import { ReportingCore } from '../..'; -import { CancellationToken } from '@kbn/reporting-common'; -import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; -import { runTaskFnFactory } from './execute_job'; - -const logger = loggingSystemMock.createLogger(); -const encryptionKey = 'tetkey'; -const headers = { sid: 'cooltestheaders' }; -let encryptedHeaders: string; -let reportingCore: ReportingCore; -let stream: jest.Mocked; - -beforeAll(async () => { - const crypto = nodeCrypto({ encryptionKey }); - - encryptedHeaders = await crypto.encrypt(headers); - reportingCore = await createMockReportingCore( - createMockConfigSchema({ - encryptionKey, - csv: { - checkForFormulas: true, - escapeFormulaValues: true, - maxSizeBytes: 180000, - scroll: { size: 500, duration: '30s' }, - }, - }) - ); -}); - -beforeEach(() => { - stream = {} as typeof stream; -}); - -test('gets the csv content from job parameters', async () => { - const runTask = runTaskFnFactory(reportingCore, logger); - - const payload = await runTask( - 'cool-job-id', - { - headers: encryptedHeaders, - browserTimezone: 'US/Alaska', - searchSource: {}, - objectType: 'search', - title: 'Test Search', - version: '7.13.0', - }, - new CancellationToken(), - stream - ); - - expect(payload).toMatchInlineSnapshot(` - Object { - "content_type": "text/csv", - "size": 123, - } - `); -}); diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/execute_job.ts deleted file mode 100644 index 7d4728b3130f9..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/execute_job.ts +++ /dev/null @@ -1,54 +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 { CsvGenerator } from '@kbn/generate-csv'; -import { TaskPayloadCSV } from './types'; -import { getFieldFormats } from '../../services'; -import { RunTaskFn, RunTaskFnFactory } from '../../types'; -import { decryptJobHeaders } from '../common'; - -export const runTaskFnFactory: RunTaskFnFactory> = ( - reporting, - parentLogger -) => { - const { encryptionKey, csv: csvConfig } = reporting.getConfig(); - - return async function runTask(jobId, job, cancellationToken, stream) { - const logger = parentLogger.get(`execute-job:${jobId}`); - const headers = await decryptJobHeaders(encryptionKey, job.headers, logger); - const fakeRequest = reporting.getFakeRequest(headers, job.spaceId, logger); - const uiSettings = await reporting.getUiSettingsClient(fakeRequest, logger); - const dataPluginStart = await reporting.getDataService(); - const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); - - const [es, searchSourceStart] = await Promise.all([ - (await reporting.getEsClient()).asScoped(fakeRequest), - await dataPluginStart.search.searchSource.asScoped(fakeRequest), - ]); - - const clients = { - uiSettings, - data: dataPluginStart.search.asScoped(fakeRequest), - es, - }; - const dependencies = { - searchSourceStart, - fieldFormatsRegistry, - }; - - const csv = new CsvGenerator( - job, - csvConfig, - clients, - dependencies, - cancellationToken, - logger, - stream - ); - return await csv.generateData(); - }; -}; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/index.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/index.ts index 64c440b5a9ca2..0656f8593a514 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/index.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/index.ts @@ -5,36 +5,4 @@ * 2.0. */ -import { - CSV_JOB_TYPE as jobType, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_TRIAL, -} from '../../../common/constants'; -import { CreateJobFn, ExportTypeDefinition, RunTaskFn } from '../../types'; -import { createJobFnFactory } from './create_job'; -import { runTaskFnFactory } from './execute_job'; -import { metadata } from './metadata'; -import { JobParamsCSV, TaskPayloadCSV } from './types'; - -export const getExportType = (): ExportTypeDefinition< - CreateJobFn, - RunTaskFn -> => ({ - ...metadata, - jobType, - jobContentExtension: 'csv', - createJobFnFactory, - runTaskFnFactory, - validLicenses: [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ], -}); +export { CsvSearchSourceExportType } from './csv_searchsource'; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/csv_searchsource_immediate.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/csv_searchsource_immediate.ts new file mode 100644 index 0000000000000..2a53d138bfd92 --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/csv_searchsource_immediate.ts @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { KibanaRequest } from '@kbn/core-http-server'; +import { DataPluginStart } from '@kbn/data-plugin/server/plugin'; +import { DiscoverServerPluginStart } from '@kbn/discover-plugin/server'; +import { CsvGenerator } from '@kbn/generate-csv'; +import { CancellationToken, TaskRunResult } from '@kbn/reporting-common'; +import { Writable } from 'stream'; +import { + ExportType, + BaseExportTypeSetupDeps, + BaseExportTypeStartDeps, +} from '../common/export_type'; +import { + CSV_SEARCHSOURCE_IMMEDIATE_TYPE, + LICENSE_TYPE_BASIC, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_TRIAL, +} from '../../../common/constants'; +import { getFieldFormats } from '../../services'; +import { ReportingRequestHandlerContext } from '../../types'; +import { JobParamsDownloadCSV } from './types'; + +type CsvSearchSourceImmediateExportTypeSetupDeps = BaseExportTypeSetupDeps; +interface CsvSearchSourceImmediateExportTypeStartDeps extends BaseExportTypeStartDeps { + discover: DiscoverServerPluginStart; + data: DataPluginStart; +} + +/* + * ImmediateExecuteFn receives the job doc payload because the payload was + * generated in the ScheduleFn + */ +export type ImmediateExecuteFn = ( + jobId: null, + job: JobParamsDownloadCSV, + context: ReportingRequestHandlerContext, + stream: Writable, + req: KibanaRequest +) => Promise; + +export class CsvSearchSourceImmediateExportType extends ExportType< + JobParamsDownloadCSV, + ImmediateExecuteFn, + CsvSearchSourceImmediateExportTypeSetupDeps, + CsvSearchSourceImmediateExportTypeStartDeps +> { + id = CSV_SEARCHSOURCE_IMMEDIATE_TYPE; + name = CSV_SEARCHSOURCE_IMMEDIATE_TYPE; + jobType = CSV_SEARCHSOURCE_IMMEDIATE_TYPE; + jobContentEncoding = 'base64' as const; + jobContentExtension = 'csv' as const; + validLicenses = [ + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_BASIC, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + ]; + + constructor(...args: ConstructorParameters) { + super(...args); + this.logger = this.logger.get('csv-searchsource-export'); + } + + public createJob = async () => { + throw new Error(`immediate download has no create job handler!`); + }; + // @ts-ignore expected type failure from deprecated export type + public runTask = async ( + _jobId: string | null, + immediateJobParams: JobParamsDownloadCSV, + context: ReportingRequestHandlerContext, + stream: Writable, + req: KibanaRequest + ) => { + const job = { + objectType: 'immediate-search', + ...immediateJobParams, + }; + + const dataPluginStart = this.startDeps.data; + const savedObjectsClient = (await context.core).savedObjects.client; + const uiSettings = this.getUiSettingsServiceFactory(savedObjectsClient); + const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); + + const es = this.startDeps.esClient.asScoped(req); + const searchSourceStart = await dataPluginStart.search.searchSource.asScoped(req); + const clients = { + uiSettings, + data: dataPluginStart.search.asScoped(req), + es, + }; + const dependencies = { + fieldFormatsRegistry, + searchSourceStart, + }; + const cancellationToken = new CancellationToken(); + const csvConfig = this.config.csv; + const csv = new CsvGenerator( + job, + csvConfig, + clients, + dependencies, + cancellationToken, + this.logger, + stream + ); + const result = await csv.generateData(); + + if (result.csv_contains_formulas) { + this.logger.warn(`CSV may contain formulas whose values have been escaped`); + } + + if (result.max_size_reached) { + this.logger.warn(`Max size reached: CSV output truncated`); + } + + const { warnings } = result; + if (warnings) { + warnings.forEach((warning) => { + this.logger.warn(warning); + }); + } + + return result; + }; +} diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts deleted file mode 100644 index 0ef2d6421f40c..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts +++ /dev/null @@ -1,89 +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 { KibanaRequest } from '@kbn/core/server'; -import { Writable } from 'stream'; -import { CancellationToken, TaskRunResult } from '@kbn/reporting-common'; -import { CsvGenerator } from '@kbn/generate-csv'; -import { getFieldFormats } from '../../services'; -import { ReportingRequestHandlerContext, RunTaskFnFactory } from '../../types'; -import { JobParamsDownloadCSV } from './types'; - -/* - * ImmediateExecuteFn receives the job doc payload because the payload was - * generated in the ScheduleFn - */ -export type ImmediateExecuteFn = ( - jobId: null, - job: JobParamsDownloadCSV, - context: ReportingRequestHandlerContext, - stream: Writable, - req: KibanaRequest -) => Promise; - -export const runTaskFnFactory: RunTaskFnFactory = function executeJobFactoryFn( - reporting, - parentLogger -) { - const { csv: csvConfig } = reporting.getConfig(); - const logger = parentLogger.get('execute-job'); - - return async function runTask(_jobId, immediateJobParams, context, stream, req) { - const job = { - objectType: 'immediate-search', - ...immediateJobParams, - }; - - const dataPluginStart = await reporting.getDataService(); - const savedObjectsClient = (await context.core).savedObjects.client; - const uiSettings = await reporting.getUiSettingsServiceFactory(savedObjectsClient); - const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); - - const [es, searchSourceStart] = await Promise.all([ - (await reporting.getEsClient()).asScoped(req), - await dataPluginStart.search.searchSource.asScoped(req), - ]); - const clients = { - uiSettings, - data: dataPluginStart.search.asScoped(req), - es, - }; - const dependencies = { - fieldFormatsRegistry, - searchSourceStart, - }; - const cancellationToken = new CancellationToken(); - - const csv = new CsvGenerator( - job, - csvConfig, - clients, - dependencies, - cancellationToken, - logger, - stream - ); - const result = await csv.generateData(); - - if (result.csv_contains_formulas) { - logger.warn(`CSV may contain formulas whose values have been escaped`); - } - - if (result.max_size_reached) { - logger.warn(`Max size reached: CSV output truncated`); - } - - const { warnings } = result; - if (warnings) { - warnings.forEach((warning) => { - logger.warn(warning); - }); - } - - return result; - }; -}; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/index.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/index.ts index 116b69225a243..e17fa75f8e7f9 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/index.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/index.ts @@ -5,37 +5,4 @@ * 2.0. */ -import { - CSV_SEARCHSOURCE_IMMEDIATE_TYPE, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_TRIAL, -} from '../../../common/constants'; -import { ExportTypeDefinition } from '../../types'; -import { ImmediateExecuteFn, runTaskFnFactory } from './execute_job'; -import { metadata } from './metadata'; - -/* - * These functions are exported to share with the API route handler that - * generates csv from saved object immediately on request. - */ -export { runTaskFnFactory } from './execute_job'; - -export const getExportType = (): ExportTypeDefinition => ({ - ...metadata, - jobType: CSV_SEARCHSOURCE_IMMEDIATE_TYPE, - jobContentExtension: 'csv', - createJobFnFactory: null, - runTaskFnFactory, - validLicenses: [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ], -}); +export { CsvSearchSourceImmediateExportType } from './csv_searchsource_immediate'; diff --git a/x-pack/plugins/reporting/server/export_types/csv_v2/create_job.ts b/x-pack/plugins/reporting/server/export_types/csv_v2/create_job.ts deleted file mode 100644 index b0c886137eddc..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/csv_v2/create_job.ts +++ /dev/null @@ -1,42 +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 Boom from '@hapi/boom'; -import { JobParamsCsvFromSavedObject, TaskPayloadCsvFromSavedObject } from '../../../common/types'; -import { CreateJobFn, CreateJobFnFactory } from '../../types'; - -type CreateJobFnType = CreateJobFn; - -export const createJobFnFactory: CreateJobFnFactory = function createJobFactoryFn( - reporting -) { - return async function createJob(jobParams, _context, req) { - // 1. Validation of locatorParams - const { locatorParams } = jobParams; - const { id, params } = locatorParams[0]; - if ( - !locatorParams || - !Array.isArray(locatorParams) || - locatorParams.length !== 1 || - id !== 'DISCOVER_APP_LOCATOR' || - !params - ) { - throw Boom.badRequest('Invalid Job params: must contain a single Discover App locator'); - } - - if (!params || !params.savedSearchId || typeof params.savedSearchId !== 'string') { - throw Boom.badRequest('Invalid Discover App locator: must contain a savedSearchId'); - } - - // use Discover contract to get the title of the report from job params - const { discover: discoverPluginStart } = await reporting.getPluginStartDeps(); - const locatorClient = await discoverPluginStart.locator.asScopedClient(req); - const title = await locatorClient.titleFromLocator(params); - - return { ...jobParams, title }; - }; -}; diff --git a/x-pack/plugins/reporting/server/export_types/csv_v2/csv_v2.ts b/x-pack/plugins/reporting/server/export_types/csv_v2/csv_v2.ts new file mode 100644 index 0000000000000..921c0724d8439 --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/csv_v2/csv_v2.ts @@ -0,0 +1,138 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import Boom from '@hapi/boom'; +import { KibanaRequest } from '@kbn/core/server'; +import { DiscoverServerPluginStart } from '@kbn/discover-plugin/server'; +import { DataPluginStart } from '@kbn/data-plugin/server/plugin'; +import { CsvGenerator } from '@kbn/generate-csv'; +import { Writable } from 'stream'; +import { CancellationToken } from '@kbn/reporting-common'; +import { JobParamsCsvFromSavedObject, TaskPayloadCsvFromSavedObject } from '../../../common/types'; +import { + CSV_REPORT_TYPE_V2, + LICENSE_TYPE_BASIC, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_TRIAL, +} from '../../../common/constants'; +import { ExportType, BaseExportTypeSetupDeps, BaseExportTypeStartDeps } from '../common'; +import { ReportingRequestHandlerContext } from '../../types'; +import { getFieldFormats } from '../../services'; +import { decryptJobHeaders } from '../common/decrypt_job_headers'; + +type CsvV2ExportTypeSetupDeps = BaseExportTypeSetupDeps; +export interface CsvV2ExportTypeStartDeps extends BaseExportTypeStartDeps { + discover: DiscoverServerPluginStart; + data: DataPluginStart; +} + +export class CsvV2ExportType extends ExportType< + JobParamsCsvFromSavedObject, + TaskPayloadCsvFromSavedObject, + CsvV2ExportTypeSetupDeps, + CsvV2ExportTypeStartDeps +> { + id = CSV_REPORT_TYPE_V2; + name = CSV_REPORT_TYPE_V2; + jobType = CSV_REPORT_TYPE_V2; + jobContentEncoding = 'base64' as const; + jobContentExtension = 'csv' as const; + validLicenses = [ + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_BASIC, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + ]; + + constructor(...args: ConstructorParameters) { + super(...args); + const logger = args[2]; + this.logger = logger.get('csv-export-v2'); + } + + public createJob = async ( + jobParams: JobParamsCsvFromSavedObject, + _context: ReportingRequestHandlerContext, + req: KibanaRequest + ) => { + // 1. Validation of locatorParams + const { locatorParams } = jobParams; + const { id, params } = locatorParams[0]; + if ( + !locatorParams || + !Array.isArray(locatorParams) || + locatorParams.length !== 1 || + id !== 'DISCOVER_APP_LOCATOR' || + !params + ) { + throw Boom.badRequest('Invalid Job params: must contain a single Discover App locator'); + } + + if (!params || !params.savedSearchId || typeof params.savedSearchId !== 'string') { + throw Boom.badRequest('Invalid Discover App locator: must contain a savedSearchId'); + } + + // use Discover contract to get the title of the report from job params + const { discover: discoverPluginStart } = this.startDeps; + const locatorClient = await discoverPluginStart.locator.asScopedClient(req); + const title = await locatorClient.titleFromLocator(params); + + return { ...jobParams, title, objectType: 'search', isDeprecated: false }; + }; + + public runTask = async ( + jobId: string, + job: TaskPayloadCsvFromSavedObject, + cancellationToken: CancellationToken, + stream: Writable + ) => { + const config = this.config; + const { encryptionKey, csv: csvConfig } = config; + const logger = this.logger.get(`execute:${jobId}`); + + const headers = await decryptJobHeaders(encryptionKey, job.headers, logger); + const fakeRequest = this.getFakeRequest(headers, job.spaceId, logger); + const uiSettings = await this.getUiSettingsClient(fakeRequest, logger); + const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); + const { data: dataPluginStart, discover: discoverPluginStart } = this.startDeps; + const data = dataPluginStart.search.asScoped(fakeRequest); + + const { locatorParams } = job; + const { params } = locatorParams[0]; + + // use Discover contract to convert the job params into inputs for CsvGenerator + const locatorClient = await discoverPluginStart.locator.asScopedClient(fakeRequest); + const columns = await locatorClient.columnsFromLocator(params); + const searchSource = await locatorClient.searchSourceFromLocator(params); + + const es = this.startDeps.esClient.asScoped(fakeRequest); + const searchSourceStart = await dataPluginStart.search.searchSource.asScoped(fakeRequest); + + const clients = { uiSettings, data, es }; + const dependencies = { searchSourceStart, fieldFormatsRegistry }; + + const csv = new CsvGenerator( + { + columns, + searchSource: searchSource.getSerializedFields(true), + ...job, + }, + csvConfig, + clients, + dependencies, + cancellationToken, + logger, + stream + ); + return await csv.generateData(); + }; +} diff --git a/x-pack/plugins/reporting/server/export_types/csv_v2/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv_v2/execute_job.ts deleted file mode 100644 index 10c64e97d9fd1..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/csv_v2/execute_job.ts +++ /dev/null @@ -1,62 +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 { CsvGenerator } from '@kbn/generate-csv'; -import type { TaskPayloadCsvFromSavedObject } from '../../../common/types'; -import { getFieldFormats } from '../../services'; -import type { RunTaskFn, RunTaskFnFactory } from '../../types'; -import { decryptJobHeaders } from '../common'; - -type RunTaskFnType = RunTaskFn; - -export const runTaskFnFactory: RunTaskFnFactory = (reporting, _logger) => { - const config = reporting.getConfig(); - const { encryptionKey, csv: csvConfig } = config; - - return async function runTask(jobId, job, cancellationToken, stream) { - const logger = _logger.get(`execute:${jobId}`); - - const headers = await decryptJobHeaders(encryptionKey, job.headers, logger); - const fakeRequest = reporting.getFakeRequest(headers, job.spaceId, logger); - const uiSettings = await reporting.getUiSettingsClient(fakeRequest, logger); - const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); - const { data: dataPluginStart, discover: discoverPluginStart } = - await reporting.getPluginStartDeps(); - const data = dataPluginStart.search.asScoped(fakeRequest); - - const { locatorParams } = job; - const { params } = locatorParams[0]; - - // use Discover contract to convert the job params into inputs for CsvGenerator - const locatorClient = await discoverPluginStart.locator.asScopedClient(fakeRequest); - const columns = await locatorClient.columnsFromLocator(params); - const searchSource = await locatorClient.searchSourceFromLocator(params); - - const [es, searchSourceStart] = await Promise.all([ - (await reporting.getEsClient()).asScoped(fakeRequest), - await dataPluginStart.search.searchSource.asScoped(fakeRequest), - ]); - - const clients = { uiSettings, data, es }; - const dependencies = { searchSourceStart, fieldFormatsRegistry }; - - const csv = new CsvGenerator( - { - columns, - searchSource: searchSource.getSerializedFields(true), - ...job, - }, - csvConfig, - clients, - dependencies, - cancellationToken, - logger, - stream - ); - return await csv.generateData(); - }; -}; diff --git a/x-pack/plugins/reporting/server/export_types/csv_v2/index.ts b/x-pack/plugins/reporting/server/export_types/csv_v2/index.ts index 0e914affbf149..e54b2e3a5b33c 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_v2/index.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_v2/index.ts @@ -5,36 +5,4 @@ * 2.0. */ -import { - CSV_REPORT_TYPE_V2 as CSV_JOB_TYPE, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_TRIAL, -} from '../../../common/constants'; -import { JobParamsCsvFromSavedObject, TaskPayloadCsvFromSavedObject } from '../../../common/types'; -import { CreateJobFn, ExportTypeDefinition, RunTaskFn } from '../../types'; -import { createJobFnFactory } from './create_job'; -import { runTaskFnFactory } from './execute_job'; - -export const getExportType = (): ExportTypeDefinition< - CreateJobFn, - RunTaskFn -> => ({ - id: CSV_JOB_TYPE, - name: CSV_JOB_TYPE, - jobType: CSV_JOB_TYPE, - jobContentExtension: 'csv', - createJobFnFactory, - runTaskFnFactory, - validLicenses: [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ], -}); +export { CsvV2ExportType } from './csv_v2'; diff --git a/x-pack/plugins/reporting/server/export_types/png/create_job/index.ts b/x-pack/plugins/reporting/server/export_types/png/create_job/index.ts deleted file mode 100644 index 70822c29119d5..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/png/create_job/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CreateJobFn, CreateJobFnFactory } from '../../../types'; -import { validateUrls } from '../../common'; -import { JobParamsPNGDeprecated, TaskPayloadPNG } from '../types'; - -export const createJobFnFactory: CreateJobFnFactory< - CreateJobFn -> = function createJobFactoryFn() { - return async function createJob(jobParams) { - validateUrls([jobParams.relativeUrl]); - - return { - ...jobParams, - isDeprecated: true, - forceNow: new Date().toISOString(), - }; - }; -}; diff --git a/x-pack/plugins/reporting/server/export_types/png/execute_job/index.ts b/x-pack/plugins/reporting/server/export_types/png/execute_job/index.ts deleted file mode 100644 index a1188317c03d1..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/png/execute_job/index.ts +++ /dev/null @@ -1,67 +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 { TaskRunResult } from '@kbn/reporting-common'; -import apm from 'elastic-apm-node'; -import * as Rx from 'rxjs'; -import { finalize, map, mergeMap, takeUntil, tap } from 'rxjs/operators'; -import { REPORTING_TRANSACTION_TYPE } from '../../../../common/constants'; -import { RunTaskFn, RunTaskFnFactory } from '../../../types'; -import { decryptJobHeaders, generatePngObservable, getFullUrls } from '../../common'; -import { TaskPayloadPNG } from '../types'; - -export const runTaskFnFactory: RunTaskFnFactory> = - function executeJobFactoryFn(reporting, parentLogger) { - const { encryptionKey } = reporting.getConfig(); - - return function runTask(jobId, job, cancellationToken, stream) { - const apmTrans = apm.startTransaction('execute-job-png', REPORTING_TRANSACTION_TYPE); - const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); - let apmGeneratePng: { end: () => void } | null | undefined; - - const jobLogger = parentLogger.get(`execute:${jobId}`); - const process$: Rx.Observable = Rx.of(1).pipe( - mergeMap(() => decryptJobHeaders(encryptionKey, job.headers, jobLogger)), - mergeMap((headers) => { - const [url] = getFullUrls(reporting.getServerInfo(), reporting.getConfig(), job); - - apmGetAssets?.end(); - apmGeneratePng = apmTrans?.startSpan('generate-png-pipeline', 'execute'); - const screenshotFn = () => - reporting.getScreenshots({ - headers, - urls: [url], - browserTimezone: job.browserTimezone, - layout: { - ...job.layout, - id: 'preserve_layout', - }, - }); - return generatePngObservable(screenshotFn, jobLogger, { - headers, - urls: [url], - browserTimezone: job.browserTimezone, - layout: { - ...job.layout, - id: 'preserve_layout', - }, - }); - }), - tap(({ buffer }) => stream.write(buffer)), - map(({ metrics, warnings }) => ({ - content_type: 'image/png', - metrics: { png: metrics }, - warnings, - })), - tap({ error: (error) => jobLogger.error(error) }), - finalize(() => apmGeneratePng?.end()) - ); - - const stop$ = Rx.fromEventPattern(cancellationToken.on); - return Rx.lastValueFrom(process$.pipe(takeUntil(stop$))); - }; - }; diff --git a/x-pack/plugins/reporting/server/export_types/png/index.ts b/x-pack/plugins/reporting/server/export_types/png/index.ts index e547cb31c7498..abb0900db3fcd 100644 --- a/x-pack/plugins/reporting/server/export_types/png/index.ts +++ b/x-pack/plugins/reporting/server/export_types/png/index.ts @@ -5,35 +5,4 @@ * 2.0. */ -import { - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_TRIAL, - PNG_JOB_TYPE as jobType, -} from '../../../common/constants'; -import { CreateJobFn, ExportTypeDefinition, RunTaskFn } from '../../types'; -import { createJobFnFactory } from './create_job'; -import { runTaskFnFactory } from './execute_job'; -import { metadata } from './metadata'; -import { JobParamsPNGDeprecated, TaskPayloadPNG } from './types'; - -export const getExportType = (): ExportTypeDefinition< - CreateJobFn, - RunTaskFn -> => ({ - ...metadata, - jobType, - jobContentEncoding: 'base64', - jobContentExtension: 'PNG', - createJobFnFactory, - runTaskFnFactory, - validLicenses: [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ], -}); +export { PngV1ExportType } from './png'; diff --git a/x-pack/plugins/reporting/server/export_types/png/execute_job/index.test.ts b/x-pack/plugins/reporting/server/export_types/png/png.test.ts similarity index 64% rename from x-pack/plugins/reporting/server/export_types/png/execute_job/index.test.ts rename to x-pack/plugins/reporting/server/export_types/png/png.test.ts index 154b843bbee16..d0be5ee9b2b4e 100644 --- a/x-pack/plugins/reporting/server/export_types/png/execute_job/index.test.ts +++ b/x-pack/plugins/reporting/server/export_types/png/png.test.ts @@ -6,27 +6,27 @@ */ import * as Rx from 'rxjs'; -import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { coreMock, elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { Writable } from 'stream'; -import { ReportingCore } from '../../..'; import { CancellationToken } from '@kbn/reporting-common'; -import { cryptoFactory } from '../../../lib'; -import { createMockConfigSchema, createMockReportingCore } from '../../../test_helpers'; -import { generatePngObservable } from '../../common'; -import { TaskPayloadPNG } from '../types'; -import { runTaskFnFactory } from '.'; +import { cryptoFactory } from '../../lib'; +import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; +import { generatePngObservable } from '../common'; +import { TaskPayloadPNG } from './types'; +import { PngV1ExportType } from './png'; +import { ScreenshottingStart } from '@kbn/screenshotting-plugin/server'; -jest.mock('../../common/generate_png'); +jest.mock('../common/generate_png'); let content: string; -let mockReporting: ReportingCore; +let mockPngExportType: PngV1ExportType; let stream: jest.Mocked; const cancellationToken = { on: jest.fn(), } as unknown as CancellationToken; -const getMockLogger = () => loggingSystemMock.createLogger(); +const mockLogger = loggingSystemMock.createLogger(); const mockEncryptionKey = 'abcabcsecuresecret'; const encryptHeaders = async (headers: Record) => { @@ -40,15 +40,25 @@ beforeEach(async () => { content = ''; stream = { write: jest.fn((chunk) => (content += chunk)) } as unknown as typeof stream; - const mockReportingConfig = createMockConfigSchema({ - encryptionKey: mockEncryptionKey, - queue: { - indexInterval: 'daily', - timeout: Infinity, - }, - }); + const configType = createMockConfigSchema({ encryptionKey: mockEncryptionKey }); + const context = coreMock.createPluginInitializerContext(configType); + + const mockCoreSetup = coreMock.createSetup(); + const mockCoreStart = coreMock.createStart(); + const mockReportingCore = await createMockReportingCore(createMockConfigSchema()); + + mockPngExportType = new PngV1ExportType(mockCoreSetup, configType, mockLogger, context); - mockReporting = await createMockReportingCore(mockReportingConfig); + mockPngExportType.setup({ + basePath: { set: jest.fn() }, + }); + mockPngExportType.start({ + esClient: elasticsearchServiceMock.createClusterClient(), + savedObjects: mockCoreStart.savedObjects, + uiSettings: mockCoreStart.uiSettings, + screenshotting: {} as unknown as ScreenshottingStart, + reporting: mockReportingCore.getContract(), + }); }); afterEach(() => (generatePngObservable as jest.Mock).mockReset()); @@ -57,9 +67,8 @@ test(`passes browserTimezone to generatePng`, async () => { const encryptedHeaders = await encryptHeaders({}); (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from('') })); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const browserTimezone = 'UTC'; - await runTask( + await mockPngExportType.runTask( 'pngJobId', getBasePayload({ relativeUrl: '/app/kibana#/something', @@ -82,12 +91,11 @@ test(`passes browserTimezone to generatePng`, async () => { }); test(`returns content_type of application/png`, async () => { - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from('foo') })); - const { content_type: contentType } = await runTask( + const { content_type: contentType } = await mockPngExportType.runTask( 'pngJobId', getBasePayload({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }), cancellationToken, @@ -100,9 +108,8 @@ test(`returns content of generatePng`, async () => { const testContent = 'raw string from get_screenhots'; (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) })); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); - await runTask( + await mockPngExportType.runTask( 'pngJobId', getBasePayload({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }), cancellationToken, diff --git a/x-pack/plugins/reporting/server/export_types/png/png.ts b/x-pack/plugins/reporting/server/export_types/png/png.ts new file mode 100644 index 0000000000000..59933346c5e0a --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/png/png.ts @@ -0,0 +1,122 @@ +/* + * Copyright 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 { LicenseType } from '@kbn/licensing-plugin/server'; +import { CancellationToken, TaskRunResult } from '@kbn/reporting-common'; +import apm from 'elastic-apm-node'; +import { Writable } from 'stream'; +import { + fromEventPattern, + mergeMap, + finalize, + takeUntil, + tap, + map, + Observable, + of, + lastValueFrom, +} from 'rxjs'; +import { JobParamsPNGDeprecated, TaskPayloadPNG } from './types'; +import { decryptJobHeaders, ExportType, generatePngObservable, getFullUrls } from '../common'; +import { validateUrls } from '../common/validate_urls'; +import { + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + PNG_JOB_TYPE, + REPORTING_TRANSACTION_TYPE, +} from '../../../common/constants'; + +/** + * @deprecated + * Used for the Reporting Diagnostic + */ +export class PngV1ExportType extends ExportType { + id = 'png'; + name = 'PNG'; + jobType = PNG_JOB_TYPE; + jobContentEncoding? = 'base64' as const; + jobContentExtension = 'png' as const; + validLicenses: LicenseType[] = [ + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + ]; + + constructor(...args: ConstructorParameters) { + super(...args); + this.logger = this.logger.get('png-export-v1'); + } + + public createJob = async (jobParams: JobParamsPNGDeprecated) => { + validateUrls([jobParams.relativeUrl]); + return { + ...jobParams, + isDeprecated: true, + forceNow: new Date().toISOString(), + }; + }; + + public runTask = ( + jobId: string, + job: TaskPayloadPNG, + cancellationToken: CancellationToken, + stream: Writable + ) => { + const apmTrans = apm.startTransaction('execute-job-png', REPORTING_TRANSACTION_TYPE); + const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); + let apmGeneratePng: { end: () => void } | null | undefined; + const { encryptionKey } = this.config; + const jobLogger = this.logger.get(`execute:${jobId}`); + + const process$: Observable = of(1).pipe( + mergeMap(() => decryptJobHeaders(encryptionKey, job.headers, jobLogger)), + mergeMap((headers) => { + const [url] = getFullUrls(this.getServerInfo(), this.config, job); + + apmGetAssets?.end(); + apmGeneratePng = apmTrans?.startSpan('generate-png-pipeline', 'execute'); + return generatePngObservable( + () => + this.startDeps.reporting.getScreenshots({ + headers, + urls: [url], + browserTimezone: job.browserTimezone, + layout: { + ...job.layout, + id: 'preserve_layout', + }, + }), + jobLogger, + { + headers, + urls: [url], + browserTimezone: job.browserTimezone, + layout: { + ...job.layout, + id: 'preserve_layout', + }, + } + ); + }), + tap(({ buffer }) => stream.write(buffer)), + map(({ metrics, warnings }) => ({ + content_type: 'image/png', + metrics: { png: metrics }, + warnings, + })), + tap({ error: (error) => jobLogger.error(error) }), + finalize(() => apmGeneratePng?.end()) + ); + + const stop$ = fromEventPattern(cancellationToken.on); + return lastValueFrom(process$.pipe(takeUntil(stop$))); + }; +} diff --git a/x-pack/plugins/reporting/server/export_types/png_v2/create_job.ts b/x-pack/plugins/reporting/server/export_types/png_v2/create_job.ts deleted file mode 100644 index ea2c4ed5910c9..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/png_v2/create_job.ts +++ /dev/null @@ -1,20 +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 { CreateJobFn, CreateJobFnFactory } from '../../types'; -import { JobParamsPNGV2, TaskPayloadPNGV2 } from './types'; - -export const createJobFnFactory: CreateJobFnFactory> = - function createJobFactoryFn() { - return async function createJob({ locatorParams, ...jobParams }) { - return { - ...jobParams, - locatorParams: [locatorParams], - forceNow: new Date().toISOString(), - }; - }; - }; diff --git a/x-pack/plugins/reporting/server/export_types/png_v2/execute_job.ts b/x-pack/plugins/reporting/server/export_types/png_v2/execute_job.ts deleted file mode 100644 index 472711794706b..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/png_v2/execute_job.ts +++ /dev/null @@ -1,70 +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 { TaskRunResult } from '@kbn/reporting-common'; -import apm from 'elastic-apm-node'; -import * as Rx from 'rxjs'; -import { finalize, map, mergeMap, takeUntil, tap } from 'rxjs/operators'; -import { REPORTING_TRANSACTION_TYPE } from '../../../common/constants'; -import { RunTaskFn, RunTaskFnFactory } from '../../types'; -import { decryptJobHeaders, generatePngObservable } from '../common'; -import { getFullRedirectAppUrl } from '../common/v2/get_full_redirect_app_url'; -import { TaskPayloadPNGV2 } from './types'; - -export const runTaskFnFactory: RunTaskFnFactory> = - function executeJobFactoryFn(reporting, parentLogger) { - const { encryptionKey } = reporting.getConfig(); - - return function runTask(jobId, job, cancellationToken, stream) { - const apmTrans = apm.startTransaction('execute-job-png-v2', REPORTING_TRANSACTION_TYPE); - const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); - let apmGeneratePng: { end: () => void } | null | undefined; - - const jobLogger = parentLogger.get(`execute:${jobId}`); - const process$: Rx.Observable = Rx.of(1).pipe( - mergeMap(() => decryptJobHeaders(encryptionKey, job.headers, jobLogger)), - mergeMap((headers) => { - const url = getFullRedirectAppUrl( - reporting.getConfig(), - reporting.getServerInfo(), - job.spaceId, - job.forceNow - ); - const [locatorParams] = job.locatorParams; - - apmGetAssets?.end(); - apmGeneratePng = apmTrans?.startSpan('generate-png-pipeline', 'execute'); - - const screenshotFn = () => - reporting.getScreenshots({ - headers, - browserTimezone: job.browserTimezone, - layout: { ...job.layout, id: 'preserve_layout' }, - urls: [[url, locatorParams]], - }); - - return generatePngObservable(screenshotFn, jobLogger, { - headers, - browserTimezone: job.browserTimezone, - layout: { ...job.layout, id: 'preserve_layout' }, - urls: [[url, locatorParams]], - }); - }), - tap(({ buffer }) => stream.write(buffer)), - map(({ metrics, warnings }) => ({ - content_type: 'image/png', - metrics: { png: metrics }, - warnings, - })), - tap({ error: (error) => jobLogger.error(error) }), - finalize(() => apmGeneratePng?.end()) - ); - - const stop$ = Rx.fromEventPattern(cancellationToken.on); - return Rx.lastValueFrom(process$.pipe(takeUntil(stop$))); - }; - }; diff --git a/x-pack/plugins/reporting/server/export_types/png_v2/index.ts b/x-pack/plugins/reporting/server/export_types/png_v2/index.ts index 64cbf9d8d96f4..301395447f3c8 100644 --- a/x-pack/plugins/reporting/server/export_types/png_v2/index.ts +++ b/x-pack/plugins/reporting/server/export_types/png_v2/index.ts @@ -5,35 +5,4 @@ * 2.0. */ -import { - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_TRIAL, - PNG_JOB_TYPE_V2 as jobType, -} from '../../../common/constants'; -import { CreateJobFn, ExportTypeDefinition, RunTaskFn } from '../../types'; -import { createJobFnFactory } from './create_job'; -import { runTaskFnFactory } from './execute_job'; -import { metadata } from './metadata'; -import { JobParamsPNGV2, TaskPayloadPNGV2 } from './types'; - -export const getExportType = (): ExportTypeDefinition< - CreateJobFn, - RunTaskFn -> => ({ - ...metadata, - jobType, - jobContentEncoding: 'base64', - jobContentExtension: 'PNG', - createJobFnFactory, - runTaskFnFactory, - validLicenses: [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ], -}); +export { PngExportType } from './png_v2'; diff --git a/x-pack/plugins/reporting/server/export_types/png_v2/execute_job.test.ts b/x-pack/plugins/reporting/server/export_types/png_v2/png_v2.test.ts similarity index 73% rename from x-pack/plugins/reporting/server/export_types/png_v2/execute_job.test.ts rename to x-pack/plugins/reporting/server/export_types/png_v2/png_v2.test.ts index ae13156b2496f..8b142b7ba765a 100644 --- a/x-pack/plugins/reporting/server/export_types/png_v2/execute_job.test.ts +++ b/x-pack/plugins/reporting/server/export_types/png_v2/png_v2.test.ts @@ -6,28 +6,30 @@ */ import * as Rx from 'rxjs'; -import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { coreMock, elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { Writable } from 'stream'; -import { ReportingCore } from '../..'; import { CancellationToken } from '@kbn/reporting-common'; +import { ScreenshottingStart } from '@kbn/screenshotting-plugin/server'; +import { ReportingCore } from '../..'; import { LocatorParams } from '../../../common/types'; import { cryptoFactory } from '../../lib'; import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; import { generatePngObservable } from '../common'; -import { runTaskFnFactory } from './execute_job'; import { TaskPayloadPNGV2 } from './types'; +import { PngExportType } from './png_v2'; jest.mock('../common/generate_png'); let content: string; -let mockReporting: ReportingCore; +let mockReportingCore: ReportingCore; +let mockPngExportType: PngExportType; let stream: jest.Mocked; const cancellationToken = { on: jest.fn(), } as unknown as CancellationToken; -const getMockLogger = () => loggingSystemMock.createLogger(); +const mockLogger = loggingSystemMock.createLogger(); const mockEncryptionKey = 'abcabcsecuresecret'; const encryptHeaders = async (headers: Record) => { @@ -41,7 +43,7 @@ beforeEach(async () => { content = ''; stream = { write: jest.fn((chunk) => (content += chunk)) } as unknown as typeof stream; - const mockReportingConfig = createMockConfigSchema({ + const configType = createMockConfigSchema({ encryptionKey: mockEncryptionKey, queue: { indexInterval: 'daily', @@ -49,7 +51,23 @@ beforeEach(async () => { }, }); - mockReporting = await createMockReportingCore(mockReportingConfig); + mockReportingCore = await createMockReportingCore(configType); + const context = coreMock.createPluginInitializerContext(configType); + + const mockCoreSetup = coreMock.createSetup(); + const mockCoreStart = coreMock.createStart(); + + mockPngExportType = new PngExportType(mockCoreSetup, configType, mockLogger, context); + mockPngExportType.setup({ + basePath: { set: jest.fn() }, + }); + mockPngExportType.start({ + savedObjects: mockCoreStart.savedObjects, + uiSettings: mockCoreStart.uiSettings, + screenshotting: {} as unknown as ScreenshottingStart, + esClient: elasticsearchServiceMock.createClusterClient(), + reporting: mockReportingCore.getContract(), + }); }); afterEach(() => (generatePngObservable as jest.Mock).mockReset()); @@ -58,9 +76,8 @@ test(`passes browserTimezone to generatePng`, async () => { const encryptedHeaders = await encryptHeaders({}); (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from('') })); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const browserTimezone = 'UTC'; - await runTask( + await mockPngExportType.runTask( 'pngJobId', getBasePayload({ forceNow: 'test', @@ -89,12 +106,11 @@ test(`passes browserTimezone to generatePng`, async () => { }); test(`returns content_type of application/png`, async () => { - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from('foo') })); - const { content_type: contentType } = await runTask( + const { content_type: contentType } = await mockPngExportType.runTask( 'pngJobId', getBasePayload({ locatorParams: [{ version: 'test', id: 'test' }] as LocatorParams[], @@ -110,9 +126,8 @@ test(`returns content of generatePng getBuffer base64 encoded`, async () => { const testContent = 'raw string from get_screenhots'; (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) })); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); - await runTask( + await mockPngExportType.runTask( 'pngJobId', getBasePayload({ locatorParams: [{ version: 'test', id: 'test' }] as LocatorParams[], diff --git a/x-pack/plugins/reporting/server/export_types/png_v2/png_v2.ts b/x-pack/plugins/reporting/server/export_types/png_v2/png_v2.ts new file mode 100644 index 0000000000000..c5ae429bca304 --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/png_v2/png_v2.ts @@ -0,0 +1,135 @@ +/* + * Copyright 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 apm from 'elastic-apm-node'; +import { LicenseType } from '@kbn/licensing-plugin/server'; +import { CancellationToken, TaskRunResult } from '@kbn/reporting-common'; +import { Writable } from 'stream'; +import { + finalize, + fromEventPattern, + lastValueFrom, + map, + mergeMap, + Observable, + of, + takeUntil, + tap, +} from 'rxjs'; +import { SerializableRecord } from '@kbn/utility-types'; +import { LocatorParams } from '../../../common'; +import { + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_TRIAL, + PNG_JOB_TYPE_V2, + PNG_REPORT_TYPE_V2, + REPORTING_TRANSACTION_TYPE, +} from '../../../common/constants'; +import { decryptJobHeaders, ExportType, generatePngObservable } from '../common'; +import { JobParamsPNGV2, TaskPayloadPNGV2 } from './types'; +import { getFullRedirectAppUrl } from '../common/v2/get_full_redirect_app_url'; + +export class PngExportType extends ExportType { + id = PNG_REPORT_TYPE_V2; + name = 'PNG'; + jobType = PNG_JOB_TYPE_V2; + jobContentEncoding = 'base64' as const; + jobContentExtension = 'png' as const; + validLicenses: LicenseType[] = [ + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + ]; + + constructor(...args: ConstructorParameters) { + super(...args); + this.logger = this.logger.get('png-export-v2'); + } + + /** + * @params JobParamsPNGV2 + * @returns jobParams + */ + public createJob = async ({ locatorParams, ...jobParams }: JobParamsPNGV2) => { + return { + ...jobParams, + locatorParams: [locatorParams] as unknown as LocatorParams, + isDeprecated: false, + browserTimezone: jobParams.browserTimezone, + forceNow: new Date().toISOString(), + }; + }; + + /** + * + * @param jobId + * @param payload + * @param cancellationToken + * @param stream + */ + public runTask = ( + jobId: string, + payload: TaskPayloadPNGV2, + cancellationToken: CancellationToken, + stream: Writable + ) => { + const jobLogger = this.logger.get(`execute-job:${jobId}`); + const apmTrans = apm.startTransaction('execute-job-pdf-v2', REPORTING_TRANSACTION_TYPE); + const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); + let apmGeneratePng: { end: () => void } | null | undefined; + const { encryptionKey } = this.config; + + const process$: Observable = of(1).pipe( + mergeMap(() => decryptJobHeaders(encryptionKey, payload.headers, jobLogger)), + mergeMap((headers) => { + const url = getFullRedirectAppUrl( + this.config, + this.getServerInfo(), + payload.spaceId, + payload.forceNow + ); + + const [locatorParams] = payload.locatorParams; + + apmGetAssets?.end(); + apmGeneratePng = apmTrans?.startSpan('generate-png-pipeline', 'execute'); + + return generatePngObservable( + () => + this.startDeps.reporting.getScreenshots({ + format: 'png', + headers, + layout: { ...payload.layout, id: 'preserve_layout' }, + urls: [[url, locatorParams]], + }), + jobLogger, + { + headers, + browserTimezone: payload.browserTimezone, + layout: { ...payload.layout, id: 'preserve_layout' }, + urls: [[url, locatorParams]], + } + ); + }), + tap(({ buffer }) => stream.write(buffer)), + map(({ metrics, warnings }) => ({ + content_type: 'image/png', + metrics: { png: metrics }, + warnings, + })), + tap({ error: (error) => jobLogger.error(error) }), + finalize(() => apmGeneratePng?.end()) + ); + + const stop$ = fromEventPattern(cancellationToken.on); + return lastValueFrom(process$.pipe(takeUntil(stop$))); + }; +} diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/create_job/index.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/create_job/index.ts deleted file mode 100644 index eeaf0f82f1698..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/create_job/index.ts +++ /dev/null @@ -1,28 +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 { CreateJobFn, CreateJobFnFactory } from '../../../types'; -import { validateUrls } from '../../common'; -import { JobParamsPDFDeprecated, TaskPayloadPDF } from '../types'; - -export const createJobFnFactory: CreateJobFnFactory< - CreateJobFn -> = function createJobFactoryFn() { - return async function createJobFn( - { relativeUrls, ...jobParams }: JobParamsPDFDeprecated // relativeUrls does not belong in the payload of PDFV1 - ) { - validateUrls(relativeUrls); - - // return the payload - return { - ...jobParams, - isDeprecated: true, - forceNow: new Date().toISOString(), - objects: relativeUrls.map((u) => ({ relativeUrl: u })), - }; - }; -}; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/execute_job/index.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/execute_job/index.ts deleted file mode 100644 index 86a476c84e155..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/execute_job/index.ts +++ /dev/null @@ -1,85 +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 { TaskRunResult } from '@kbn/reporting-common'; -import apm from 'elastic-apm-node'; -import * as Rx from 'rxjs'; -import { catchError, map, mergeMap, takeUntil, tap } from 'rxjs/operators'; -import { REPORTING_TRANSACTION_TYPE } from '../../../../common/constants'; -import { RunTaskFn, RunTaskFnFactory } from '../../../types'; -import { decryptJobHeaders, getCustomLogo, getFullUrls } from '../../common'; -import { generatePdfObservable } from '../lib/generate_pdf'; -import { TaskPayloadPDF } from '../types'; - -export const runTaskFnFactory: RunTaskFnFactory> = - function executeJobFactoryFn(reporting, parentLogger) { - const { encryptionKey } = reporting.getConfig(); - - return async function runTask(jobId, job, cancellationToken, stream) { - const jobLogger = parentLogger.get(`execute-job:${jobId}`); - const apmTrans = apm.startTransaction('execute-job-pdf', REPORTING_TRANSACTION_TYPE); - const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); - let apmGeneratePdf: { end: () => void } | null | undefined; - - const process$: Rx.Observable = Rx.of(1).pipe( - mergeMap(() => decryptJobHeaders(encryptionKey, job.headers, jobLogger)), - mergeMap(async (headers) => { - const fakeRequest = reporting.getFakeRequest(headers, job.spaceId, jobLogger); - const uiSettingsClient = await reporting.getUiSettingsClient(fakeRequest); - return getCustomLogo(uiSettingsClient, headers); - }), - mergeMap(({ headers, logo }) => { - const urls = getFullUrls(reporting.getServerInfo(), reporting.getConfig(), job); - - const { browserTimezone, layout, title } = job; - apmGetAssets?.end(); - - apmGeneratePdf = apmTrans?.startSpan('generate-pdf-pipeline', 'execute'); - // make a new function that will call reporting.getScreenshots - const snapshotFn = () => - reporting.getScreenshots({ - format: 'pdf', - title, - logo, - urls, - browserTimezone, - headers, - layout, - }); - return generatePdfObservable(snapshotFn, { - format: 'pdf', - title, - logo, - urls, - browserTimezone, - headers, - layout, - }); - }), - tap(({ buffer }) => { - apmGeneratePdf?.end(); - if (buffer) { - stream.write(buffer); - } - }), - map(({ metrics, warnings }) => ({ - content_type: 'application/pdf', - metrics: { pdf: metrics }, - warnings, - })), - catchError((err) => { - jobLogger.error(err); - return Rx.throwError(err); - }) - ); - - const stop$ = Rx.fromEventPattern(cancellationToken.on); - - apmTrans?.end(); - return Rx.lastValueFrom(process$.pipe(takeUntil(stop$))); - }; - }; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts index 8b94981bc46ae..39f055c707db1 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts @@ -5,35 +5,4 @@ * 2.0. */ -import { - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_TRIAL, - PDF_JOB_TYPE as jobType, -} from '../../../common/constants'; -import { CreateJobFn, ExportTypeDefinition, RunTaskFn } from '../../types'; -import { createJobFnFactory } from './create_job'; -import { runTaskFnFactory } from './execute_job'; -import { metadata } from './metadata'; -import { JobParamsPDFDeprecated, TaskPayloadPDF } from './types'; - -export const getExportType = (): ExportTypeDefinition< - CreateJobFn, - RunTaskFn -> => ({ - ...metadata, - jobType, - jobContentEncoding: 'base64', - jobContentExtension: 'pdf', - createJobFnFactory, - runTaskFnFactory, - validLicenses: [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ], -}); +export { PdfV1ExportType } from './printable_pdf'; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/execute_job/index.test.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/printable_pdf.test.ts similarity index 63% rename from x-pack/plugins/reporting/server/export_types/printable_pdf/execute_job/index.test.ts rename to x-pack/plugins/reporting/server/export_types/printable_pdf/printable_pdf.test.ts index cf10b29c328aa..79031cd4db925 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/execute_job/index.test.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/printable_pdf.test.ts @@ -6,27 +6,27 @@ */ import * as Rx from 'rxjs'; -import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { coreMock, elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { Writable } from 'stream'; -import { ReportingCore } from '../../..'; import { CancellationToken } from '@kbn/reporting-common'; -import { cryptoFactory } from '../../../lib'; -import { createMockConfigSchema, createMockReportingCore } from '../../../test_helpers'; -import { generatePdfObservable } from '../lib/generate_pdf'; -import { TaskPayloadPDF } from '../types'; -import { runTaskFnFactory } from '.'; +import { generatePdfObservable } from './lib/generate_pdf'; +import { cryptoFactory } from '../../lib/crypto'; +import { TaskPayloadPDF } from './types'; +import { PdfV1ExportType } from './printable_pdf'; +import { ScreenshottingStart } from '@kbn/screenshotting-plugin/server'; +import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; -jest.mock('../lib/generate_pdf'); +jest.mock('./lib/generate_pdf'); let content: string; -let mockReporting: ReportingCore; +let mockPdfExportType: PdfV1ExportType; let stream: jest.Mocked; const cancellationToken = { on: jest.fn(), } as unknown as CancellationToken; -const getMockLogger = () => loggingSystemMock.createLogger(); +const mockLogger = loggingSystemMock.createLogger(); const mockEncryptionKey = 'testencryptionkey'; const encryptHeaders = async (headers: Record) => { @@ -39,17 +39,25 @@ const getBasePayload = (baseObj: any) => baseObj as TaskPayloadPDF; beforeEach(async () => { content = ''; stream = { write: jest.fn((chunk) => (content += chunk)) } as unknown as typeof stream; - - const reportingConfig = { - 'server.basePath': '/sbp', - index: '.reports-test', - encryptionKey: mockEncryptionKey, - 'kibanaServer.hostname': 'localhost', - 'kibanaServer.port': 5601, - 'kibanaServer.protocol': 'http', - }; - const mockSchema = createMockConfigSchema(reportingConfig); - mockReporting = await createMockReportingCore(mockSchema); + const configType = createMockConfigSchema({ encryptionKey: mockEncryptionKey }); + const context = coreMock.createPluginInitializerContext(configType); + + const mockCoreSetup = coreMock.createSetup(); + const mockCoreStart = coreMock.createStart(); + const mockReportingCore = await createMockReportingCore(createMockConfigSchema()); + + mockPdfExportType = new PdfV1ExportType(mockCoreSetup, configType, mockLogger, context); + + mockPdfExportType.setup({ + basePath: { set: jest.fn() }, + }); + mockPdfExportType.start({ + esClient: elasticsearchServiceMock.createClusterClient(), + savedObjects: mockCoreStart.savedObjects, + uiSettings: mockCoreStart.uiSettings, + screenshotting: {} as unknown as ScreenshottingStart, + reporting: mockReportingCore.getContract(), + }); }); afterEach(() => (generatePdfObservable as jest.Mock).mockReset()); @@ -58,9 +66,8 @@ test(`passes browserTimezone to generatePdf`, async () => { const encryptedHeaders = await encryptHeaders({}); (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from('') })); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const browserTimezone = 'UTC'; - await runTask( + await mockPdfExportType.runTask( 'pdfJobId', getBasePayload({ title: 'PDF Params Timezone Test', @@ -79,13 +86,11 @@ test(`passes browserTimezone to generatePdf`, async () => { }); test(`returns content_type of application/pdf`, async () => { - const logger = getMockLogger(); - const runTask = runTaskFnFactory(mockReporting, logger); const encryptedHeaders = await encryptHeaders({}); (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from('') })); - const { content_type: contentType } = await runTask( + const { content_type: contentType } = await mockPdfExportType.runTask( 'pdfJobId', getBasePayload({ objects: [], headers: encryptedHeaders }), cancellationToken, @@ -98,9 +103,8 @@ test(`returns content of generatePdf getBuffer base64 encoded`, async () => { const testContent = 'test content'; (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) })); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); - await runTask( + await mockPdfExportType.runTask( 'pdfJobId', getBasePayload({ objects: [], headers: encryptedHeaders }), cancellationToken, diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/printable_pdf.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/printable_pdf.ts new file mode 100644 index 0000000000000..d5dce43deac84 --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/printable_pdf.ts @@ -0,0 +1,129 @@ +/* + * Copyright 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 { LicenseType } from '@kbn/licensing-plugin/server'; +import { CancellationToken, TaskRunResult } from '@kbn/reporting-common'; +import { Writable } from 'stream'; +import apm from 'elastic-apm-node'; +import { catchError, map, mergeMap, takeUntil, tap } from 'rxjs/operators'; +import { fromEventPattern, lastValueFrom, Observable, of, throwError } from 'rxjs'; +import { JobParamsPDFDeprecated } from '../../../common/types'; +import { + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_TRIAL, + PDF_JOB_TYPE, + REPORTING_TRANSACTION_TYPE, +} from '../../../common/constants'; +import { decryptJobHeaders, ExportType, getCustomLogo, getFullUrls, validateUrls } from '../common'; +import { TaskPayloadPDF } from './types'; +import { generatePdfObservable } from './lib/generate_pdf'; + +export class PdfV1ExportType extends ExportType { + id = 'printablePdf'; + name = 'PDF'; + jobType = PDF_JOB_TYPE; + jobContentEncoding? = 'base64' as const; + jobContentExtension = 'pdf' as const; + validLicenses: LicenseType[] = [ + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + ]; + + constructor(...args: ConstructorParameters) { + super(...args); + this.logger = this.logger.get('png-export-v1'); + } + + public createJob = async ( + { relativeUrls, ...jobParams }: JobParamsPDFDeprecated // relativeUrls does not belong in the payload of PDFV1 + ) => { + validateUrls(relativeUrls); + + // return the payload + return { + ...jobParams, + isDeprecated: true, + forceNow: new Date().toISOString(), + objects: relativeUrls.map((u) => ({ relativeUrl: u })), + }; + }; + + public runTask = async ( + jobId: string, + job: TaskPayloadPDF, + cancellationToken: CancellationToken, + stream: Writable + ) => { + const jobLogger = this.logger.get(`execute-job:${jobId}`); + const apmTrans = apm.startTransaction('execute-job-pdf', REPORTING_TRANSACTION_TYPE); + const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); + let apmGeneratePdf: { end: () => void } | null | undefined; + + const process$: Observable = of(1).pipe( + mergeMap(() => decryptJobHeaders(this.config.encryptionKey, job.headers, jobLogger)), + mergeMap(async (headers) => { + const fakeRequest = this.getFakeRequest(headers, job.spaceId, jobLogger); + const uiSettingsClient = await this.getUiSettingsClient(fakeRequest); + return getCustomLogo(uiSettingsClient, headers); + }), + mergeMap(({ headers, logo }) => { + const urls = getFullUrls(this.getServerInfo(), this.config, job); + + const { browserTimezone, layout, title } = job; + apmGetAssets?.end(); + + apmGeneratePdf = apmTrans?.startSpan('generate-pdf-pipeline', 'execute'); + // make a new function that will call reporting.getScreenshots + const snapshotFn = () => + this.startDeps.reporting.getScreenshots({ + format: 'pdf', + title, + logo, + urls, + browserTimezone, + headers, + layout, + }); + return generatePdfObservable(snapshotFn, { + format: 'pdf', + title, + logo, + urls, + browserTimezone, + headers, + layout, + }); + }), + tap(({ buffer }) => { + apmGeneratePdf?.end(); + if (buffer) { + stream.write(buffer); + } + }), + map(({ metrics, warnings }) => ({ + content_type: 'application/pdf', + metrics: { pdf: metrics }, + warnings, + })), + catchError((err: any) => { + jobLogger.error(err); + return throwError(err); + }) + ); + + const stop$ = fromEventPattern(cancellationToken.on); + + apmTrans?.end(); + return lastValueFrom(process$.pipe(takeUntil(stop$))); + }; +} diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/create_job.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/create_job.ts deleted file mode 100644 index 427b29765080e..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/create_job.ts +++ /dev/null @@ -1,19 +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 { CreateJobFn, CreateJobFnFactory } from '../../types'; -import { JobParamsPDFV2, TaskPayloadPDFV2 } from './types'; - -export const createJobFnFactory: CreateJobFnFactory> = - function createJobFactoryFn() { - return async function createJob(jobParams) { - return { - ...jobParams, - forceNow: new Date().toISOString(), - }; - }; - }; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/execute_job.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/execute_job.ts deleted file mode 100644 index 57d290fa41a5c..0000000000000 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/execute_job.ts +++ /dev/null @@ -1,102 +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 apm from 'elastic-apm-node'; -import * as Rx from 'rxjs'; -import { catchError, map, mergeMap, takeUntil, tap } from 'rxjs/operators'; -import { TaskRunResult } from '@kbn/reporting-common'; -import { getFullRedirectAppUrl } from '../common/v2/get_full_redirect_app_url'; -import { UrlOrUrlLocatorTuple } from '../../../common/types'; -import { REPORTING_TRANSACTION_TYPE } from '../../../common/constants'; -import { RunTaskFn, RunTaskFnFactory } from '../../types'; -import { decryptJobHeaders, getCustomLogo } from '../common'; -import { generatePdfObservable } from './lib/generate_pdf'; -import { TaskPayloadPDFV2 } from './types'; - -export const runTaskFnFactory: RunTaskFnFactory> = - function executeJobFactoryFn(reporting, parentLogger) { - const { encryptionKey } = reporting.getConfig(); - - return async function runTask(jobId, job, cancellationToken, stream) { - const jobLogger = parentLogger.get(`execute-job:${jobId}`); - const apmTrans = apm.startTransaction('execute-job-pdf-v2', REPORTING_TRANSACTION_TYPE); - const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); - let apmGeneratePdf: { end: () => void } | null | undefined; - - const process$: Rx.Observable = Rx.of(1).pipe( - mergeMap(() => decryptJobHeaders(encryptionKey, job.headers, jobLogger)), - mergeMap(async (headers) => { - const fakeRequest = reporting.getFakeRequest(headers, job.spaceId, jobLogger); - const uiSettingsClient = await reporting.getUiSettingsClient(fakeRequest); - return getCustomLogo(uiSettingsClient, headers); - }), - mergeMap(({ logo, headers }) => { - const { browserTimezone, layout, title, locatorParams } = job; - - const urls = locatorParams.map((locator) => [ - getFullRedirectAppUrl( - reporting.getConfig(), - reporting.getServerInfo(), - job.spaceId, - job.forceNow - ), - locator, - ]) as UrlOrUrlLocatorTuple[]; - - const screenshotFn = () => - reporting.getScreenshots({ - format: 'pdf', - title, - logo, - browserTimezone, - headers, - layout, - urls, - }); - apmGetAssets?.end(); - - apmGeneratePdf = apmTrans?.startSpan('generate-pdf-pipeline', 'execute'); - return generatePdfObservable( - reporting.getConfig(), - reporting.getServerInfo(), - screenshotFn, - job, - locatorParams, - { - format: 'pdf', - title, - logo, - browserTimezone, - headers, - layout, - } - ); - }), - tap(({ buffer }) => { - apmGeneratePdf?.end(); - - if (buffer) { - stream.write(buffer); - } - }), - map(({ metrics, warnings }) => ({ - content_type: 'application/pdf', - metrics: { pdf: metrics }, - warnings, - })), - catchError((err) => { - jobLogger.error(err); - return Rx.throwError(err); - }) - ); - - const stop$ = Rx.fromEventPattern(cancellationToken.on); - - apmTrans?.end(); - return Rx.lastValueFrom(process$.pipe(takeUntil(stop$))); - }; - }; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/index.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/index.ts index e97c3aa98c137..f27635ae6fc49 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/index.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/index.ts @@ -5,35 +5,4 @@ * 2.0. */ -import { - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_TRIAL, - PDF_JOB_TYPE_V2 as jobType, -} from '../../../common/constants'; -import { CreateJobFn, ExportTypeDefinition, RunTaskFn } from '../../types'; -import { createJobFnFactory } from './create_job'; -import { runTaskFnFactory } from './execute_job'; -import { metadata } from './metadata'; -import { JobParamsPDFV2, TaskPayloadPDFV2 } from './types'; - -export const getExportType = (): ExportTypeDefinition< - CreateJobFn, - RunTaskFn -> => ({ - ...metadata, - jobType, - jobContentEncoding: 'base64', - jobContentExtension: 'pdf', - createJobFnFactory, - runTaskFnFactory, - validLicenses: [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ], -}); +export { PdfExportType } from './printable_pdf_v2'; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts index 6ba79d007ddd1..7ab96553f3cd8 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/lib/generate_pdf.ts @@ -8,13 +8,13 @@ import * as Rx from 'rxjs'; import { mergeMap, tap } from 'rxjs/operators'; import { PdfScreenshotResult } from '@kbn/screenshotting-plugin/server'; +import { TaskPayloadPDFV2 } from '../../../../common/types/export_types/printable_pdf_v2'; import { ReportingServerInfo } from '../../../core'; import { ReportingConfigType } from '../../../config'; import type { LocatorParams, PdfMetrics, UrlOrUrlLocatorTuple } from '../../../../common/types'; import type { PdfScreenshotOptions } from '../../../types'; import { getFullRedirectAppUrl } from '../../common/v2/get_full_redirect_app_url'; import { getTracker } from '../../common/pdf_tracker'; -import type { TaskPayloadPDFV2 } from '../types'; interface PdfResult { buffer: Uint8Array | null; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/execute_job.test.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/printable_pdf_v2.test.ts similarity index 66% rename from x-pack/plugins/reporting/server/export_types/printable_pdf_v2/execute_job.test.ts rename to x-pack/plugins/reporting/server/export_types/printable_pdf_v2/printable_pdf_v2.test.ts index 6df4d573b0a60..fd6e6ace45d8f 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/execute_job.test.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/printable_pdf_v2.test.ts @@ -7,27 +7,27 @@ jest.mock('./lib/generate_pdf'); -import * as Rx from 'rxjs'; -import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { Writable } from 'stream'; -import { ReportingCore } from '../..'; +import { coreMock, elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { CancellationToken } from '@kbn/reporting-common'; -import { LocatorParams } from '../../../common/types'; +import type { ScreenshottingStart } from '@kbn/screenshotting-plugin/server'; +import * as Rx from 'rxjs'; +import type { Writable } from 'stream'; +import { PdfExportType } from '.'; +import type { LocatorParams } from '../../../common'; +import type { TaskPayloadPDFV2 } from '../../../common/types/export_types/printable_pdf_v2'; import { cryptoFactory } from '../../lib'; -import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; -import { runTaskFnFactory } from './execute_job'; import { generatePdfObservable } from './lib/generate_pdf'; -import { TaskPayloadPDFV2 } from './types'; +import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; let content: string; -let mockReporting: ReportingCore; +let mockPdfExportType: PdfExportType; let stream: jest.Mocked; const cancellationToken = { on: jest.fn(), } as unknown as CancellationToken; -const getMockLogger = () => loggingSystemMock.createLogger(); +const mockLogger = loggingSystemMock.createLogger(); const mockEncryptionKey = 'testencryptionkey'; const encryptHeaders = async (headers: Record) => { @@ -45,16 +45,25 @@ beforeEach(async () => { content = ''; stream = { write: jest.fn((chunk) => (content += chunk)) } as unknown as typeof stream; - const reportingConfig = { - 'server.basePath': '/sbp', - index: '.reports-test', - encryptionKey: mockEncryptionKey, - 'kibanaServer.hostname': 'localhost', - 'kibanaServer.port': 5601, - 'kibanaServer.protocol': 'http', - }; - const mockSchema = createMockConfigSchema(reportingConfig); - mockReporting = await createMockReportingCore(mockSchema); + const configType = createMockConfigSchema({ encryptionKey: mockEncryptionKey }); + const context = coreMock.createPluginInitializerContext(configType); + + const mockCoreSetup = coreMock.createSetup(); + const mockCoreStart = coreMock.createStart(); + const mockReportingCore = await createMockReportingCore(createMockConfigSchema()); + + mockPdfExportType = new PdfExportType(mockCoreSetup, configType, mockLogger, context); + + mockPdfExportType.setup({ + basePath: { set: jest.fn() }, + }); + mockPdfExportType.start({ + esClient: elasticsearchServiceMock.createClusterClient(), + savedObjects: mockCoreStart.savedObjects, + uiSettings: mockCoreStart.uiSettings, + screenshotting: {} as unknown as ScreenshottingStart, + reporting: mockReportingCore.getContract(), + }); }); afterEach(() => (generatePdfObservable as jest.Mock).mockReset()); @@ -63,9 +72,8 @@ test(`passes browserTimezone to generatePdf`, async () => { const encryptedHeaders = await encryptHeaders({}); (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of(Buffer.from(''))); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const browserTimezone = 'UTC'; - await runTask( + await mockPdfExportType.runTask( 'pdfJobId', getBasePayload({ forceNow: 'test', @@ -89,13 +97,11 @@ test(`passes browserTimezone to generatePdf`, async () => { }); test(`returns content_type of application/pdf`, async () => { - const logger = getMockLogger(); - const runTask = runTaskFnFactory(mockReporting, logger); const encryptedHeaders = await encryptHeaders({}); (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from('') })); - const { content_type: contentType } = await runTask( + const { content_type: contentType } = await mockPdfExportType.runTask( 'pdfJobId', getBasePayload({ locatorParams: [], headers: encryptedHeaders }), cancellationToken, @@ -108,9 +114,8 @@ test(`returns content of generatePdf getBuffer base64 encoded`, async () => { const testContent = 'test content'; (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) })); - const runTask = runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); - await runTask( + await mockPdfExportType.runTask( 'pdfJobId', getBasePayload({ locatorParams: [], headers: encryptedHeaders }), cancellationToken, diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/printable_pdf_v2.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/printable_pdf_v2.ts new file mode 100644 index 0000000000000..788807fab1f24 --- /dev/null +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf_v2/printable_pdf_v2.ts @@ -0,0 +1,155 @@ +/* + * Copyright 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 { Headers } from '@kbn/core/server'; +import { CancellationToken, TaskRunResult } from '@kbn/reporting-common'; +import apm from 'elastic-apm-node'; +import * as Rx from 'rxjs'; +import { catchError, map, mergeMap, takeUntil, tap } from 'rxjs'; +import { Writable } from 'stream'; +import { + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_ENTERPRISE, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_TRIAL, + PDF_JOB_TYPE_V2, + PDF_REPORT_TYPE_V2, + REPORTING_TRANSACTION_TYPE, +} from '../../../common/constants'; +import { JobParamsPDFV2, UrlOrUrlLocatorTuple } from '../../../common/types'; +import { TaskPayloadPDFV2 } from '../../../common/types/export_types/printable_pdf_v2'; +import { decryptJobHeaders, ExportType, getCustomLogo } from '../common'; +import { getFullRedirectAppUrl } from '../common/v2/get_full_redirect_app_url'; +import { generatePdfObservable } from './lib/generate_pdf'; + +export class PdfExportType extends ExportType { + id = PDF_REPORT_TYPE_V2; + name = 'PDF'; + jobType = PDF_JOB_TYPE_V2; + jobContentEncoding = 'base64' as const; + jobContentExtension = 'pdf' as const; + validLicenses = [ + LICENSE_TYPE_TRIAL, + LICENSE_TYPE_CLOUD_STANDARD, + LICENSE_TYPE_GOLD, + LICENSE_TYPE_PLATINUM, + LICENSE_TYPE_ENTERPRISE, + ]; + + constructor(...args: ConstructorParameters) { + super(...args); + this.logger = this.logger.get('pdf-export-v2'); + } + + /** + * @param JobParamsPDFV2 + * @returns jobParams + */ + public createJob = async ({ locatorParams, ...jobParams }: JobParamsPDFV2) => { + return { + ...jobParams, + locatorParams, + isDeprecated: false, + browserTimezone: jobParams.browserTimezone, + forceNow: new Date().toISOString(), + }; + }; + + /** + * + * @param jobId + * @param payload + * @param cancellationToken + * @param stream + */ + public runTask = ( + jobId: string, + payload: TaskPayloadPDFV2, + cancellationToken: CancellationToken, + stream: Writable + ) => { + const jobLogger = this.logger.get(`execute-job:${jobId}`); + const apmTrans = apm.startTransaction('execute-job-pdf-v2', REPORTING_TRANSACTION_TYPE); + const apmGetAssets = apmTrans?.startSpan('get-assets', 'setup'); + let apmGeneratePdf: { end: () => void } | null | undefined; + const { encryptionKey } = this.config; + + const process$: Rx.Observable = Rx.of(1).pipe( + mergeMap(() => decryptJobHeaders(encryptionKey, payload.headers, jobLogger)), + mergeMap(async (headers: Headers) => { + const fakeRequest = this.getFakeRequest(headers, payload.spaceId, jobLogger); + const uiSettingsClient = await this.getUiSettingsClient(fakeRequest); + return await getCustomLogo(uiSettingsClient, headers); + }), + mergeMap(({ logo, headers }) => { + const { browserTimezone, layout, title, locatorParams } = payload; + let urls: UrlOrUrlLocatorTuple[]; + if (locatorParams) { + urls = locatorParams.map((locator) => [ + getFullRedirectAppUrl( + this.config, + this.getServerInfo(), + payload.spaceId, + payload.forceNow + ), + locator, + ]) as unknown as UrlOrUrlLocatorTuple[]; + } + + apmGetAssets?.end(); + + apmGeneratePdf = apmTrans?.startSpan('generate-pdf-pipeline', 'execute'); + return generatePdfObservable( + this.config, + this.getServerInfo(), + () => + this.startDeps.reporting.getScreenshots({ + format: 'pdf', + title, + logo, + browserTimezone, + headers, + layout, + urls, + }), + payload, + locatorParams, + { + format: 'pdf', + title, + logo, + browserTimezone, + headers, + layout, + } + ); + }), + tap(({ buffer }) => { + apmGeneratePdf?.end(); + + if (buffer) { + stream.write(buffer); + } + }), + map(({ metrics, warnings }) => ({ + content_type: 'application/pdf', + metrics: { pdf: metrics }, + warnings, + })), + catchError((err) => { + jobLogger.error(err); + return Rx.throwError(() => err); + }) + ); + + const stop$ = Rx.fromEventPattern(cancellationToken.on); + + apmTrans?.end(); + return Rx.firstValueFrom(process$.pipe(takeUntil(stop$))); + }; +} diff --git a/x-pack/plugins/reporting/server/lib/check_license.ts b/x-pack/plugins/reporting/server/lib/check_license.ts index 107b683cd621b..9b603a83597b7 100644 --- a/x-pack/plugins/reporting/server/lib/check_license.ts +++ b/x-pack/plugins/reporting/server/lib/check_license.ts @@ -6,7 +6,7 @@ */ import { ILicense } from '@kbn/licensing-plugin/server'; -import { ExportTypeDefinition } from '../types'; +import { ExportType } from '../export_types/common'; import { ExportTypesRegistry } from './export_types_registry'; export interface LicenseCheckResult { @@ -25,7 +25,7 @@ const messages = { }, }; -const makeManagementFeature = (exportTypes: ExportTypeDefinition[]) => { +const makeManagementFeature = (exportTypes: ExportType[]) => { return { id: 'management', checkLicense: (license?: ILicense) => { @@ -46,7 +46,7 @@ const makeManagementFeature = (exportTypes: ExportTypeDefinition[]) => { } const validJobTypes = exportTypes - .filter((exportType) => exportType.validLicenses.includes(license.type || '')) + .filter((exportType) => exportType.validLicenses.includes(license.type!)) .map((exportType) => exportType.jobType); return { @@ -58,7 +58,7 @@ const makeManagementFeature = (exportTypes: ExportTypeDefinition[]) => { }; }; -const makeExportTypeFeature = (exportType: ExportTypeDefinition) => { +const makeExportTypeFeature = (exportType: ExportType) => { return { id: exportType.id, checkLicense: (license?: ILicense) => { diff --git a/x-pack/plugins/reporting/server/lib/export_types_registry.test.js b/x-pack/plugins/reporting/server/lib/export_types_registry.test.js index 9925697ba8c32..cecb6a23aba49 100644 --- a/x-pack/plugins/reporting/server/lib/export_types_registry.test.js +++ b/x-pack/plugins/reporting/server/lib/export_types_registry.test.js @@ -122,4 +122,33 @@ describe('ExportTypesRegistry', function () { }).toThrow(); }); }); + + describe('getByJobType', function () { + it('returns obj that matches the predicate', function () { + const prop = 'fooProp'; + const match = { id: 'foo', jobType: prop }; + [match, { id: 'bar' }, { id: 'baz' }].forEach((obj) => exportTypesRegistry.register(obj)); + expect(exportTypesRegistry.getByJobType(prop)).toBe(match); + }); + + it('throws Error if multiple items match predicate', function () { + const prop = 'fooProp'; + [ + { id: 'foo', jobType: prop }, + { id: 'bar', jobType: prop }, + ].forEach((obj) => exportTypesRegistry.register(obj)); + expect(() => { + exportTypesRegistry.getByJobType(prop); + }).toThrow(); + }); + + it('throws Error if no items match predicate', function () { + const prop = 'fooProp'; + [ + { id: 'foo', jobtType: prop }, + { id: 'bar', jobType: prop }, + ].forEach((obj) => exportTypesRegistry.register(obj)); + expect(() => exportTypesRegistry.getByJobType('foo')).toThrow(); + }); + }); }); diff --git a/x-pack/plugins/reporting/server/lib/export_types_registry.ts b/x-pack/plugins/reporting/server/lib/export_types_registry.ts index 96456ea93926c..4c93410347bb1 100644 --- a/x-pack/plugins/reporting/server/lib/export_types_registry.ts +++ b/x-pack/plugins/reporting/server/lib/export_types_registry.ts @@ -6,24 +6,16 @@ */ import { isString } from 'lodash'; -import { getExportType as getTypeCsvFromSavedObject } from '../export_types/csv_v2'; -import { getExportType as getTypeCsvFromSavedObjectImmediate } from '../export_types/csv_searchsource_immediate'; -import { getExportType as getTypeCsv } from '../export_types/csv_searchsource'; -import { getExportType as getTypePng } from '../export_types/png'; -import { getExportType as getTypePngV2 } from '../export_types/png_v2'; -import { getExportType as getTypePrintablePdf } from '../export_types/printable_pdf'; -import { getExportType as getTypePrintablePdfV2 } from '../export_types/printable_pdf_v2'; +import { ExportType } from '../export_types/common'; -import { CreateJobFn, ExportTypeDefinition } from '../types'; - -type GetCallbackFn = (item: ExportTypeDefinition) => boolean; +type GetCallbackFn = (item: ExportType) => boolean; export class ExportTypesRegistry { - private _map: Map = new Map(); + private _map: Map = new Map(); constructor() {} - register(item: ExportTypeDefinition): void { + register(item: ExportType): void { if (!isString(item.id)) { throw new Error(`'item' must have a String 'id' property `); } @@ -43,21 +35,43 @@ export class ExportTypesRegistry { return this._map.size; } - getById(id: string): ExportTypeDefinition { + getById(id: string): ExportType { if (!this._map.has(id)) { throw new Error(`Unknown id ${id}`); } - return this._map.get(id) as ExportTypeDefinition; + return this._map.get(id) as ExportType; } - get(findType: GetCallbackFn): ExportTypeDefinition { + getByJobType(jobType: ExportType['jobType']): ExportType { + let result; + for (const value of this._map.values()) { + if (value.jobType !== jobType) { + continue; + } + const foundJobType = value; + + if (result) { + throw new Error('Found multiple items matching predicate.'); + } + + result = foundJobType; + } + + if (!result) { + throw new Error('Found no items matching predicate'); + } + + return result; + } + + get(findType: GetCallbackFn): ExportType { let result; for (const value of this._map.values()) { if (!findType(value)) { continue; // try next value } - const foundResult: ExportTypeDefinition = value; + const foundResult: ExportType = value; if (result) { throw new Error('Found multiple items matching predicate.'); @@ -73,30 +87,3 @@ export class ExportTypesRegistry { return result; } } - -// TODO: Define a 2nd ExportTypeRegistry instance for "immediate execute" report job types only. -// It should not require a `CreateJobFn` for its ExportTypeDefinitions, which only makes sense for async. -// Once that is done, the `any` types below can be removed. - -/* - * @return ExportTypeRegistry: the ExportTypeRegistry instance that should be - * used to register async export type definitions - */ -export function getExportTypesRegistry(): ExportTypesRegistry { - const registry = new ExportTypesRegistry(); - type CreateFnType = CreateJobFn; // can not specify params types because different type of params are not assignable to each other - type RunFnType = any; // can not specify because ImmediateExecuteFn is not assignable to RunTaskFn - const getTypeFns: Array<() => ExportTypeDefinition> = [ - getTypeCsv, - getTypeCsvFromSavedObject, - getTypeCsvFromSavedObjectImmediate, - getTypePng, - getTypePngV2, - getTypePrintablePdf, - getTypePrintablePdfV2, - ]; - getTypeFns.forEach((getType) => { - registry.register(getType()); - }); - return registry; -} diff --git a/x-pack/plugins/reporting/server/lib/index.ts b/x-pack/plugins/reporting/server/lib/index.ts index 36d310fcd131b..be26675f05e88 100644 --- a/x-pack/plugins/reporting/server/lib/index.ts +++ b/x-pack/plugins/reporting/server/lib/index.ts @@ -9,7 +9,7 @@ export { checkLicense } from './check_license'; export { checkParamsVersion } from './check_params_version'; export { ContentStream, getContentStream } from './content_stream'; export { cryptoFactory } from './crypto'; -export { ExportTypesRegistry, getExportTypesRegistry } from './export_types_registry'; +export { ExportTypesRegistry } from './export_types_registry'; export { PassThroughStream } from './passthrough_stream'; export { statuses } from './statuses'; export { ReportingStore, IlmPolicyManager } from './store'; diff --git a/x-pack/plugins/reporting/server/lib/tasks/execute_report.test.ts b/x-pack/plugins/reporting/server/lib/tasks/execute_report.test.ts index d753ed1612a6e..314fffd3527b5 100644 --- a/x-pack/plugins/reporting/server/lib/tasks/execute_report.test.ts +++ b/x-pack/plugins/reporting/server/lib/tasks/execute_report.test.ts @@ -7,11 +7,12 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { KibanaShuttingDownError } from '@kbn/reporting-common'; -import { RunContext } from '@kbn/task-manager-plugin/server'; +import type { RunContext } from '@kbn/task-manager-plugin/server'; import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; import { ExecuteReportTask } from '.'; -import { ReportingCore } from '../..'; -import { ReportingConfigType } from '../../config'; +import type { ReportingCore } from '../..'; +import type { ReportingConfigType } from '../../config'; +import type { ExportType } from '../../export_types/common'; import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; import type { SavedReport } from '../store'; @@ -86,12 +87,14 @@ describe('Execute Report Task', () => { mockReporting.getExportTypesRegistry().register({ id: 'noop', name: 'Noop', - createJobFnFactory: () => async () => new Promise(() => {}), - runTaskFnFactory: () => async () => new Promise(() => {}), - jobContentExtension: 'none', + setup: jest.fn(), + start: jest.fn(), + createJob: () => new Promise(() => {}), + runTask: () => new Promise(() => {}), + jobContentExtension: 'pdf', jobType: 'noop', validLicenses: [], - }); + } as unknown as ExportType); const store = await mockReporting.getStore(); store.setReportFailed = jest.fn(() => Promise.resolve({} as any)); const task = new ExecuteReportTask(mockReporting, configType, logger); diff --git a/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts b/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts index ebfbd59e5f6e5..61818fe00ef2b 100644 --- a/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts +++ b/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts @@ -26,12 +26,11 @@ import { TaskRunResult, } from '@kbn/reporting-common'; import { mapToReportingError } from '../../../common/errors/map_to_reporting_error'; -import { getContentStream } from '..'; +import { ExportTypesRegistry, getContentStream } from '..'; import type { ReportingCore } from '../..'; import { durationToNumber, numberToDuration } from '../../../common/schema_utils'; import type { ReportOutput } from '../../../common/types'; import type { ReportingConfigType } from '../../config'; -import type { BasePayload, ExportTypeDefinition, RunTaskFn } from '../../types'; import type { ReportDocument, ReportingStore } from '../store'; import { Report, SavedReport } from '../store'; import type { ReportFailedFields, ReportProcessingFields } from '../store/store'; @@ -47,10 +46,6 @@ interface ReportingExecuteTaskInstance { runAt?: Date; } -interface TaskExecutor extends Pick { - jobExecutor: RunTaskFn; -} - function isOutput(output: CompletedReportOutput | Error): output is CompletedReportOutput { return (output as CompletedReportOutput).size != null; } @@ -80,10 +75,10 @@ export class ExecuteReportTask implements ReportingTask { private logger: Logger; private taskManagerStart?: TaskManagerStartContract; - private taskExecutors?: Map; private kibanaId?: string; private kibanaName?: string; private store?: ReportingStore; + private exportTypesRegistry: ExportTypesRegistry; constructor( private reporting: ReportingCore, @@ -91,6 +86,7 @@ export class ExecuteReportTask implements ReportingTask { logger: Logger ) { this.logger = logger.get('runTask'); + this.exportTypesRegistry = this.reporting.getExportTypesRegistry(); } /* @@ -100,22 +96,6 @@ export class ExecuteReportTask implements ReportingTask { this.taskManagerStart = taskManager; const { reporting } = this; - - const exportTypesRegistry = reporting.getExportTypesRegistry(); - const executors = new Map(); - for (const exportType of exportTypesRegistry.getAll()) { - const exportTypeLogger = this.logger.get(exportType.jobType); - const jobExecutor = exportType.runTaskFnFactory(reporting, exportTypeLogger); - // The task will run the function with the job type as a param. - // This allows us to retrieve the specific export type runFn when called to run an export - executors.set(exportType.jobType, { - jobExecutor, - jobContentEncoding: exportType.jobContentEncoding, - }); - } - - this.taskExecutors = executors; - const { uuid, name } = reporting.getServerInfo(); this.kibanaId = uuid; this.kibanaName = name; @@ -141,7 +121,8 @@ export class ExecuteReportTask implements ReportingTask { } private getJobContentEncoding(jobType: string) { - return this.taskExecutors?.get(jobType)?.jobContentEncoding; + const exportType = this.exportTypesRegistry.getByJobType(jobType); + return exportType.jobContentEncoding; } public async _claimJob(task: ReportTaskParams): Promise { @@ -262,21 +243,16 @@ export class ExecuteReportTask implements ReportingTask { cancellationToken: CancellationToken, stream: Writable ): Promise { - if (!this.taskExecutors) { - throw new Error(`Task run function factories have not been called yet!`); - } + const exportType = this.exportTypesRegistry.getByJobType(task.jobtype); - // get the run_task function - const runner = this.taskExecutors.get(task.jobtype); - if (!runner) { - throw new Error(`No defined task runner function for ${task.jobtype}!`); + if (!exportType) { + throw new Error(`No export type from ${task.jobtype} found to execute report`); } - // run the report // if workerFn doesn't finish before timeout, call the cancellationToken and throw an error const queueTimeout = durationToNumber(this.config.queue.timeout); return Rx.lastValueFrom( - Rx.from(runner.jobExecutor(task.id, task.payload, cancellationToken, stream)).pipe( + Rx.from(exportType.runTask(task.id, task.payload, cancellationToken, stream)).pipe( timeout(queueTimeout) ) // throw an error if a value is not emitted before timeout ); @@ -301,6 +277,7 @@ export class ExecuteReportTask implements ReportingTask { docId = `/${report._index}/_doc/${report._id}`; const resp = await store.setReportCompleted(report, doc); + this.logger.info(`Saved ${report.jobtype} job ${docId}`); report._seq_no = resp._seq_no; report._primary_term = resp._primary_term; @@ -383,7 +360,6 @@ export class ExecuteReportTask implements ReportingTask { encoding: jobContentEncoding === 'base64' ? 'base64' : 'raw', } ); - eventLog.logExecutionStart(); const output = await Promise.race([ diff --git a/x-pack/plugins/reporting/server/mocks/index.ts b/x-pack/plugins/reporting/server/mocks/index.ts new file mode 100644 index 0000000000000..a6626be6ce791 --- /dev/null +++ b/x-pack/plugins/reporting/server/mocks/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ReportingStart } from '../types'; + +export const reportingMock = { + createStart: (): ReportingStart => ({ + usesUiCapabilities: () => false, + registerExportTypes: () => {}, + getSpaceId: jest.fn(), + getScreenshots: jest.fn(), + }), +}; diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/browser.test.ts b/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/browser.test.ts index 262353071f677..77034c15495fc 100644 --- a/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/browser.test.ts +++ b/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/browser.test.ts @@ -18,6 +18,7 @@ import { } from '../../../test_helpers'; import type { ReportingRequestHandlerContext } from '../../../types'; import { registerDiagnoseBrowser } from '../browser'; +import { reportingMock } from '../../../mocks'; type SetupServerReturn = Awaited>; @@ -44,7 +45,7 @@ describe('POST /diagnose/browser', () => { httpSetup.registerRouteHandlerContext( reportingSymbol, 'reporting', - () => ({ usesUiCapabilities: () => false, registerExportTypes: jest.fn() }) + () => reportingMock.createStart() ); const docLinksSetupMock = docLinksServiceMock.createSetupContract(); diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/screenshot.test.ts b/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/screenshot.test.ts index b4a6e638a4dee..812f3d64eb2d5 100644 --- a/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/screenshot.test.ts +++ b/x-pack/plugins/reporting/server/routes/diagnostic/integration_tests/screenshot.test.ts @@ -18,6 +18,7 @@ import { import type { ReportingRequestHandlerContext } from '../../../types'; import { registerDiagnoseScreenshot } from '../screenshot'; import { defer } from 'rxjs'; +import { reportingMock } from '../../../mocks'; jest.mock('../../../export_types/common/generate_png'); @@ -45,7 +46,7 @@ describe('POST /diagnose/screenshot', () => { httpSetup.registerRouteHandlerContext( reportingSymbol, 'reporting', - () => ({ usesUiCapabilities: () => false, registerExportTypes: jest.fn() }) + () => reportingMock.createStart() ); core = await createMockReportingCore( diff --git a/x-pack/plugins/reporting/server/routes/generate/csv_searchsource_immediate.ts b/x-pack/plugins/reporting/server/routes/generate/csv_searchsource_immediate.ts index 7c4886be207b3..ed8cad2fbb2d0 100644 --- a/x-pack/plugins/reporting/server/routes/generate/csv_searchsource_immediate.ts +++ b/x-pack/plugins/reporting/server/routes/generate/csv_searchsource_immediate.ts @@ -11,8 +11,7 @@ import type { KibanaRequest, Logger } from '@kbn/core/server'; import moment from 'moment'; import type { ReportingCore } from '../..'; import { CSV_SEARCHSOURCE_IMMEDIATE_TYPE } from '../../../common/constants'; -import { runTaskFnFactory } from '../../export_types/csv_searchsource_immediate/execute_job'; -import type { JobParamsDownloadCSV } from '../../export_types/csv_searchsource_immediate/types'; +import { JobParamsDownloadCSV } from '../../export_types/csv_searchsource_immediate/types'; import { PassThroughStream } from '../../lib'; import { authorizedUserPreRouting, getCounters } from '../lib'; @@ -73,7 +72,8 @@ export function registerGenerateCsvFromSavedObjectImmediate( const counters = getCounters(req.route.method, path, reporting.getUsageCounter()); const logger = parentLogger.get(CSV_SEARCHSOURCE_IMMEDIATE_TYPE); - const runTaskFn = runTaskFnFactory(reporting, logger); + const csvSearchSourceImmediateExport = await reporting.getCsvSearchSourceImmediate(); + const stream = new PassThroughStream(); const eventLog = reporting.getEventLogger({ jobtype: CSV_SEARCHSOURCE_IMMEDIATE_TYPE, @@ -87,7 +87,9 @@ export function registerGenerateCsvFromSavedObjectImmediate( try { eventLog.logExecutionStart(); - const taskPromise = runTaskFn(null, req.body, context, stream, req) + + const taskPromise = csvSearchSourceImmediateExport + .runTask(null, req.body, context, stream, req) .then((output) => { logger.info(`Job output size: ${stream.bytesWritten} bytes.`); diff --git a/x-pack/plugins/reporting/server/routes/generate/integration_tests/generation_from_jobparams.test.ts b/x-pack/plugins/reporting/server/routes/generate/integration_tests/generation_from_jobparams.test.ts index 627e2210dac37..039a0054a1b45 100644 --- a/x-pack/plugins/reporting/server/routes/generate/integration_tests/generation_from_jobparams.test.ts +++ b/x-pack/plugins/reporting/server/routes/generate/integration_tests/generation_from_jobparams.test.ts @@ -7,7 +7,7 @@ import rison from '@kbn/rison'; import { BehaviorSubject } from 'rxjs'; -import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { coreMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { setupServer } from '@kbn/core-test-helpers-test-utils'; import supertest from 'supertest'; import { ReportingCore } from '../../..'; @@ -23,6 +23,8 @@ import { } from '../../../test_helpers'; import type { ReportingRequestHandlerContext } from '../../../types'; import { registerJobGenerationRoutes } from '../generate_from_jobparams'; +import { PdfExportType } from '../../../export_types/printable_pdf_v2'; +import { reportingMock } from '../../../mocks'; type SetupServerReturn = Awaited>; @@ -39,13 +41,21 @@ describe('POST /api/reporting/generate', () => { }); const mockLogger = loggingSystemMock.createLogger(); + const mockCoreSetup = coreMock.createSetup(); + + const mockPdfExportType = new PdfExportType( + mockCoreSetup, + mockConfigSchema, + mockLogger, + coreMock.createPluginInitializerContext(mockConfigSchema) + ); beforeEach(async () => { ({ server, httpSetup } = await setupServer(reportingSymbol)); httpSetup.registerRouteHandlerContext( reportingSymbol, 'reporting', - () => ({ usesUiCapabilities: jest.fn(), registerExportTypes: jest.fn() }) + () => reportingMock.createStart() ); const mockSetupDeps = createMockPluginSetup({ @@ -77,17 +87,7 @@ describe('POST /api/reporting/generate', () => { ); mockExportTypesRegistry = new ExportTypesRegistry(); - mockExportTypesRegistry.register({ - id: 'printablePdf', - name: 'not sure why this field exists', - jobType: 'printable_pdf', - jobContentEncoding: 'base64', - jobContentExtension: 'pdf', - validLicenses: ['basic', 'gold'], - createJobFnFactory: () => async () => ({ createJobTest: { test1: 'yes' } } as any), - runTaskFnFactory: () => async () => ({ runParamsTest: { test2: 'yes' } } as any), - }); - mockReportingCore.getExportTypesRegistry = () => mockExportTypesRegistry; + mockExportTypesRegistry.register(mockPdfExportType); store = await mockReportingCore.getStore(); store.addReport = jest.fn().mockImplementation(async (opts) => { @@ -189,7 +189,14 @@ describe('POST /api/reporting/generate', () => { await supertest(httpSetup.server.listener) .post('/api/reporting/generate/printablePdf') - .send({ jobParams: rison.encode({ title: `abc` }) }) + .send({ + jobParams: rison.encode({ + title: `abc`, + relativeUrls: ['test'], + layout: { id: 'test' }, + objectType: 'canvas workpad', + }), + }) .expect(200) .then(({ body }) => { expect(body).toMatchObject({ @@ -200,9 +207,19 @@ describe('POST /api/reporting/generate', () => { index: 'foo-index', jobtype: 'printable_pdf', payload: { - createJobTest: { - test1: 'yes', + forceNow: expect.any(String), + isDeprecated: true, + layout: { + id: 'test', }, + objectType: 'canvas workpad', + objects: [ + { + relativeUrl: 'test', + }, + ], + title: 'abc', + version: '7.14.0', }, status: 'pending', }, diff --git a/x-pack/plugins/reporting/server/routes/lib/get_document_payload.test.ts b/x-pack/plugins/reporting/server/routes/lib/get_document_payload.test.ts index efe22f0111c63..b8091e09027a2 100644 --- a/x-pack/plugins/reporting/server/routes/lib/get_document_payload.test.ts +++ b/x-pack/plugins/reporting/server/routes/lib/get_document_payload.test.ts @@ -6,7 +6,7 @@ */ import { Readable } from 'stream'; -import { CSV_JOB_TYPE, PDF_JOB_TYPE } from '../../../common/constants'; +import { CSV_JOB_TYPE, PDF_JOB_TYPE, PDF_JOB_TYPE_V2 } from '../../../common/constants'; import { ReportApiJSON } from '../../../common/types'; import { ContentStream, getContentStream, statuses } from '../../lib'; import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; @@ -104,7 +104,7 @@ describe('getDocumentPayload', () => { id: 'id1', index: '.reporting-12345', status: statuses.JOB_STATUS_FAILED, - jobtype: PDF_JOB_TYPE, + jobtype: PDF_JOB_TYPE_V2, output: {}, payload: {}, } as ReportApiJSON) @@ -128,7 +128,7 @@ describe('getDocumentPayload', () => { id: 'id1', index: '.reporting-12345', status: statuses.JOB_STATUS_PENDING, - jobtype: PDF_JOB_TYPE, + jobtype: PDF_JOB_TYPE_V2, output: {}, payload: {}, } as ReportApiJSON) diff --git a/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts b/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts index 58f878e7a29d7..158d42b6e94e3 100644 --- a/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts +++ b/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts @@ -10,8 +10,8 @@ import { Stream } from 'stream'; import { ReportingCore } from '../..'; import { CSV_JOB_TYPE, CSV_JOB_TYPE_DEPRECATED } from '../../../common/constants'; import { ReportApiJSON } from '../../../common/types'; +import { ExportType } from '../../export_types/common'; import { getContentStream, statuses } from '../../lib'; -import { ExportTypeDefinition } from '../../types'; import { jobsQueryFactory } from './jobs_query'; export interface ErrorFromPayload { @@ -33,10 +33,10 @@ type TaskRunResult = Required['output']; const DEFAULT_TITLE = 'report'; -const getTitle = (exportType: ExportTypeDefinition, title?: string): string => +const getTitle = (exportType: ExportType, title?: string): string => `${title || DEFAULT_TITLE}.${exportType.jobContentExtension}`; -const getReportingHeaders = (output: TaskRunResult, exportType: ExportTypeDefinition) => { +const getReportingHeaders = (output: TaskRunResult, exportType: ExportType) => { const metaDataHeaders: Record = {}; if (exportType.jobType === CSV_JOB_TYPE || exportType.jobType === CSV_JOB_TYPE_DEPRECATED) { @@ -60,9 +60,7 @@ export function getDocumentPayloadFactory(reporting: ReportingCore) { jobtype: jobType, payload: { title }, }: Required): Promise { - const exportType = exportTypesRegistry.get( - (item: ExportTypeDefinition) => item.jobType === jobType - ); + const exportType = exportTypesRegistry.getByJobType(jobType); const encoding = exportType.jobContentEncoding === 'base64' ? 'base64' : 'raw'; const content = await getContentStream(reporting, { id, index }, { encoding }); const filename = getTitle(exportType, title); diff --git a/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts b/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts index 69fb16831d557..eeb0aa1ada393 100644 --- a/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts +++ b/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts @@ -7,8 +7,9 @@ import { KibanaRequest, KibanaResponseFactory } from '@kbn/core/server'; import { coreMock, httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { TaskPayloadPDFV2 } from '../../../common/types/export_types/printable_pdf_v2'; import { ReportingCore } from '../..'; -import { JobParamsPDFDeprecated, TaskPayloadPDF } from '../../export_types/printable_pdf/types'; +import { JobParamsPDFDeprecated } from '../../export_types/printable_pdf/types'; import { Report, ReportingStore } from '../../lib/store'; import { ReportApiJSON } from '../../lib/store/report'; import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; @@ -94,7 +95,7 @@ describe('Handle request to generate', () => { describe('Enqueue Job', () => { test('creates a report object to queue', async () => { - const report = await requestHandler.enqueueJob('printablePdf', mockJobParams); + const report = await requestHandler.enqueueJob('printablePdfV2', mockJobParams); const { _id, created_at: _created_at, payload, ...snapObj } = report; expect(snapObj).toMatchInlineSnapshot(` @@ -106,12 +107,12 @@ describe('Handle request to generate', () => { "completed_at": undefined, "created_by": "testymcgee", "execution_time_ms": undefined, - "jobtype": "printable_pdf", + "jobtype": "printable_pdf_v2", "kibana_id": undefined, "kibana_name": undefined, "max_attempts": undefined, "meta": Object { - "isDeprecated": true, + "isDeprecated": false, "layout": "preserve_layout", "objectType": "cool_object_type", }, @@ -125,17 +126,18 @@ describe('Handle request to generate', () => { "timeout": undefined, } `); - const { forceNow, ...snapPayload } = payload as TaskPayloadPDF; + const { forceNow, ...snapPayload } = payload as TaskPayloadPDFV2; expect(snapPayload).toMatchInlineSnapshot(` Object { "browserTimezone": "UTC", "headers": "hello mock cypher text", - "isDeprecated": true, + "isDeprecated": false, "layout": Object { "id": "preserve_layout", }, + "locatorParams": undefined, "objectType": "cool_object_type", - "objects": Array [], + "relativeUrls": Array [], "spaceId": undefined, "title": "cool_title", "version": "unknown", @@ -144,6 +146,7 @@ describe('Handle request to generate', () => { }); test('provides a default kibana version field for older POST URLs', async () => { + // how do we handle the printable_pdf endpoint that isn't migrating to the class instance of export types? (mockJobParams as unknown as { version?: string }).version = undefined; const report = await requestHandler.enqueueJob('printablePdf', mockJobParams); diff --git a/x-pack/plugins/reporting/server/routes/lib/request_handler.ts b/x-pack/plugins/reporting/server/routes/lib/request_handler.ts index 234048e5b2221..0811eae3be7ea 100644 --- a/x-pack/plugins/reporting/server/routes/lib/request_handler.ts +++ b/x-pack/plugins/reporting/server/routes/lib/request_handler.ts @@ -45,7 +45,7 @@ export class RequestHandler { } public async enqueueJob(exportTypeId: string, jobParams: BaseParams) { - const { reporting, logger, context, req: request, user } = this; + const { reporting, logger, context, req, user } = this; const exportType = reporting.getExportTypesRegistry().getById(exportTypeId); @@ -53,33 +53,29 @@ export class RequestHandler { throw new Error(`Export type ${exportTypeId} does not exist in the registry!`); } - if (!exportType.createJobFnFactory) { - throw new Error(`Export type ${exportTypeId} is not an async job type!`); - } - - const [createJob, store] = await Promise.all([ - exportType.createJobFnFactory(reporting, logger.get(exportType.id)), - reporting.getStore(), - ]); + const store = await reporting.getStore(); - if (!createJob) { - throw new Error(`Export type ${exportTypeId} is not an async job type!`); + if (!exportType.createJob) { + throw new Error(`Export type ${exportTypeId} is not a valid instance!`); } - // 1. ensure the incoming params have a version field (should be set by the UI) + // 1. Ensure the incoming params have a version field (should be set by the UI) jobParams.version = checkParamsVersion(jobParams, logger); - // 2. encrypt request headers for the running report job to authenticate itself with Kibana - // 3. call the export type's createJobFn to create the job payload - const [headers, job] = await Promise.all([ - this.encryptHeaders(), - createJob(jobParams, context, this.req), - ]); + // 2. Encrypt request headers to store for the running report job to authenticate itself with Kibana + const headers = await this.encryptHeaders(); + + // 3. Create a payload object by calling exportType.createJob(), and adding some automatic parameters + const job = await exportType.createJob(jobParams, context, req); const payload = { ...job, headers, - spaceId: reporting.getSpaceId(request, logger), + title: job.title, + objectType: jobParams.objectType, + browserTimezone: jobParams.browserTimezone, + version: jobParams.version, + spaceId: reporting.getSpaceId(req, logger), }; // 4. Add the report to ReportingStore to show as pending @@ -88,6 +84,7 @@ export class RequestHandler { jobtype: exportType.jobType, created_by: user ? user.username : false, payload, + migration_version: jobParams.version, meta: { // telemetry fields objectType: jobParams.objectType, @@ -106,7 +103,6 @@ export class RequestHandler { // 6. Log the action with event log reporting.getEventLogger(report, task).logScheduleTask(); - return report; } @@ -140,10 +136,8 @@ export class RequestHandler { let report: Report | undefined; try { report = await this.enqueueJob(exportTypeId, jobParams); - // return task manager's task information and the download URL const downloadBaseUrl = getDownloadBaseUrl(this.reporting); - counters.usageCounter(); return this.res.ok({ diff --git a/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts b/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts index 7a31f44ba4f14..a8a1bf36a02b7 100644 --- a/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts +++ b/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts @@ -24,8 +24,10 @@ import { createMockPluginStart, createMockReportingCore, } from '../../../test_helpers'; -import { ExportTypeDefinition, ReportingRequestHandlerContext } from '../../../types'; +import { ReportingRequestHandlerContext } from '../../../types'; import { registerJobInfoRoutes } from '../jobs'; +import { ExportType } from '../../../export_types/common'; +import { reportingMock } from '../../../mocks'; type SetupServerReturn = Awaited>; @@ -55,7 +57,7 @@ describe('GET /api/reporting/jobs/download', () => { httpSetup.registerRouteHandlerContext( reportingSymbol, 'reporting', - () => ({ usesUiCapabilities: jest.fn(), registerExportTypes: jest.fn() }) + () => reportingMock.createStart() ); mockSetupDeps = createMockPluginSetup({ @@ -88,14 +90,14 @@ describe('GET /api/reporting/jobs/download', () => { jobType: 'unencodedJobType', jobContentExtension: 'csv', validLicenses: ['basic', 'gold'], - } as ExportTypeDefinition); + } as ExportType); exportTypesRegistry.register({ id: 'base64Encoded', jobType: 'base64EncodedJobType', jobContentEncoding: 'base64', jobContentExtension: 'pdf', validLicenses: ['basic', 'gold'], - } as ExportTypeDefinition); + } as ExportType); core.getExportTypesRegistry = () => exportTypesRegistry; mockEsClient = (await core.getEsClient()).asInternalUser as typeof mockEsClient; diff --git a/x-pack/plugins/reporting/server/types.ts b/x-pack/plugins/reporting/server/types.ts index 891fa29fffa9d..c836fb0cce6b9 100644 --- a/x-pack/plugins/reporting/server/types.ts +++ b/x-pack/plugins/reporting/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { CustomRequestHandlerContext, IRouter, KibanaRequest, Logger } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, IRouter, KibanaRequest } from '@kbn/core/server'; import type { DataPluginStart } from '@kbn/data-plugin/server/plugin'; import { DiscoverServerPluginStart } from '@kbn/discover-plugin/server'; import type { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; @@ -32,19 +32,20 @@ import type { Writable } from 'stream'; import type { CancellationToken, TaskRunResult } from '@kbn/reporting-common'; import type { BaseParams, BasePayload, UrlOrUrlLocatorTuple } from '../common/types'; import type { ReportingConfigType } from './config'; -import type { ReportingCore } from './core'; -import type { ReportTaskParams } from './lib/tasks'; import { ExportTypesRegistry } from './lib'; +import { ReportingCore } from './core'; /** * Plugin Setup Contract */ export interface ReportingSetup { + registerExportTypes: ExportTypesRegistry['register']; + getSpaceId: ReportingCore['getSpaceId']; + getScreenshots: ReportingCore['getScreenshots']; /** * Used to inform plugins if Reporting config is compatible with UI Capabilities / Application Sub-Feature Controls */ usesUiCapabilities: () => boolean; - registerExportTypes: ExportTypesRegistry['register']; } /** @@ -58,46 +59,21 @@ export type ScrollConfig = ReportingConfigType['csv']['scroll']; /** * Internal Types */ - -// default fn type for CreateJobFnFactory +// standard type for create job function of any ExportType implementation export type CreateJobFn = ( jobParams: JobParamsType, context: ReportingRequestHandlerContext, req: KibanaRequest ) => Promise>; -// default fn type for RunTaskFnFactory +// standard type for run task function of any ExportType implementation export type RunTaskFn = ( jobId: string, - payload: ReportTaskParams['payload'], + payload: TaskPayloadType, cancellationToken: CancellationToken, stream: Writable ) => Promise; -export type CreateJobFnFactory = ( - reporting: ReportingCore, - logger: Logger -) => CreateJobFnType; - -export type RunTaskFnFactory = ( - reporting: ReportingCore, - logger: Logger -) => RunTaskFnType; - -export interface ExportTypeDefinition< - CreateJobFnType = CreateJobFn | null, - RunTaskFnType = RunTaskFn -> { - id: string; - name: string; - jobType: string; - jobContentEncoding?: string; - jobContentExtension: string; - createJobFnFactory: CreateJobFnFactory | null; // immediate job does not have a "create" phase - runTaskFnFactory: RunTaskFnFactory; - validLicenses: string[]; -} - export interface ReportingSetupDeps { features: FeaturesPluginSetup; screenshotMode: ScreenshotModePluginSetup; diff --git a/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap b/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap index 732bbf7c43ef0..47529e5ed3177 100644 --- a/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap +++ b/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap @@ -2829,37 +2829,6 @@ Object { }, "total": 4, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -2999,37 +2968,6 @@ Object { }, "total": 4, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -3388,37 +3326,6 @@ Object { }, "total": 0, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -3558,37 +3465,6 @@ Object { }, "total": 0, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -3935,37 +3811,6 @@ Object { }, "total": 0, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -4105,37 +3950,6 @@ Object { }, "total": 0, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -4516,37 +4330,6 @@ Object { }, "total": 1, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -4686,37 +4469,6 @@ Object { }, "total": 1, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -5085,37 +4837,6 @@ Object { }, "total": 1, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, @@ -5255,37 +4976,6 @@ Object { }, "total": 0, }, - "csv_searchsource_immediate": Object { - "app": Object { - "canvas workpad": 0, - "dashboard": 0, - "search": 0, - "visualization": 0, - }, - "available": true, - "deprecated": 0, - "error_codes": undefined, - "execution_times": undefined, - "layout": undefined, - "metrics": Object { - "csv_rows": Object { - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - }, - "output_size": Object { - "1.0": null, - "25.0": null, - "5.0": null, - "50.0": null, - "75.0": null, - "95.0": null, - "99.0": null, - }, - "total": 0, - }, "csv_v2": Object { "app": Object { "canvas workpad": 0, diff --git a/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts b/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts index 84f4c4ba425ae..f9a7dd1b9ac58 100644 --- a/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts +++ b/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { getExportTypesRegistry } from '../lib'; +import { ExportTypesRegistry } from '../lib'; +import { createMockReportingCore, createMockConfigSchema } from '../test_helpers'; import { getExportStats } from './get_export_stats'; import { getExportTypesHandler } from './get_export_type_handler'; import { ErrorCodeStats, FeatureAvailabilityMap, MetricsStats } from './types'; @@ -20,13 +21,16 @@ const sizesAggResponse = { '95.0': 1.1935594e7, '99.0': 1.1935594e7, }; +let exportTypesRegistry: ExportTypesRegistry; +let exportTypesHandler: ReturnType; -beforeEach(() => { +beforeEach(async () => { + const mockReporting = await createMockReportingCore(createMockConfigSchema()); + exportTypesRegistry = mockReporting.getExportTypesRegistry(); + exportTypesHandler = getExportTypesHandler(exportTypesRegistry); featureMap = { PNG: true, csv_searchsource: true, printable_pdf: true }; }); -const exportTypesHandler = getExportTypesHandler(getExportTypesRegistry()); - test('Model of job status and status-by-pdf-app', () => { const result = getExportStats( { @@ -414,19 +418,6 @@ test('Incorporate error code stats', () => { invalid_layout_parameters_error: 0, }, }, - csv_searchsource_immediate: { - available: true, - total: 3, - output_size: sizesAggResponse, - metrics: { png_cpu: {}, png_memory: {} } as MetricsStats, - app: { dashboard: 3, visualization: 0, 'canvas workpad': 0 }, - error_codes: { - authentication_expired_error: 5, - queue_timeout_error: 1, - unknown_error: 0, - kibana_shutting_down_error: 1, - }, - }, }, featureMap, exportTypesHandler @@ -459,13 +450,4 @@ test('Incorporate error code stats', () => { "visual_reporting_soft_disabled_error": 1, } `); - - expect(result.csv_searchsource_immediate.error_codes).toMatchInlineSnapshot(` - Object { - "authentication_expired_error": 5, - "kibana_shutting_down_error": 1, - "queue_timeout_error": 1, - "unknown_error": 0, - } - `); }); diff --git a/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts b/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts index 4de780fd77f5b..55111f2338877 100644 --- a/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts +++ b/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts @@ -12,15 +12,13 @@ import { createCollectorFetchContextMock, usageCollectionPluginMock, } from '@kbn/usage-collection-plugin/server/mocks'; -import { getExportTypesRegistry } from '../lib/export_types_registry'; import { createMockConfigSchema, createMockReportingCore } from '../test_helpers'; import { FeaturesAvailability } from '.'; import { getReportingUsageCollector, registerReportingUsageCollector, } from './reporting_usage_collector'; - -const exportTypesRegistry = getExportTypesRegistry(); +import { ExportTypesRegistry } from '../lib'; const getLicenseMock = (licenseType = 'gold') => @@ -40,11 +38,15 @@ const getMockFetchClients = (resp: any) => { }; const usageCollectionSetup = usageCollectionPluginMock.createSetupContract(); +let exportTypesRegistry: ExportTypesRegistry; describe('license checks', () => { describe('with a basic license', () => { let usageStats: any; beforeAll(async () => { + const mockReporting = await createMockReportingCore(createMockConfigSchema()); + exportTypesRegistry = mockReporting.getExportTypesRegistry(); + const collector = getReportingUsageCollector( usageCollectionSetup, getLicenseMock('basic'), diff --git a/x-pack/plugins/security_solution/common/endpoint/models/policy_config.ts b/x-pack/plugins/security_solution/common/endpoint/models/policy_config.ts index 06c7eda0785a7..fab5a165ad47d 100644 --- a/x-pack/plugins/security_solution/common/endpoint/models/policy_config.ts +++ b/x-pack/plugins/security_solution/common/endpoint/models/policy_config.ts @@ -42,6 +42,7 @@ export const policyFactory = (license = '', cloud = false): PolicyConfig => { }, behavior_protection: { mode: ProtectionModes.prevent, + reputation_service: false, supported: true, }, popup: { @@ -86,6 +87,7 @@ export const policyFactory = (license = '', cloud = false): PolicyConfig => { }, behavior_protection: { mode: ProtectionModes.prevent, + reputation_service: false, supported: true, }, memory_protection: { @@ -127,6 +129,7 @@ export const policyFactory = (license = '', cloud = false): PolicyConfig => { }, behavior_protection: { mode: ProtectionModes.prevent, + reputation_service: false, supported: true, }, memory_protection: { @@ -200,6 +203,7 @@ export const policyFactoryWithoutPaidFeatures = ( }, behavior_protection: { mode: ProtectionModes.off, + reputation_service: false, supported: false, }, attack_surface_reduction: { @@ -231,6 +235,7 @@ export const policyFactoryWithoutPaidFeatures = ( ...policy.mac, behavior_protection: { mode: ProtectionModes.off, + reputation_service: false, supported: false, }, memory_protection: { @@ -257,6 +262,7 @@ export const policyFactoryWithoutPaidFeatures = ( ...policy.linux, behavior_protection: { mode: ProtectionModes.off, + reputation_service: false, supported: false, }, memory_protection: { diff --git a/x-pack/plugins/security_solution/common/endpoint/models/policy_config_helpers.test.ts b/x-pack/plugins/security_solution/common/endpoint/models/policy_config_helpers.test.ts index c59844f70ead9..e6e8efc21ee25 100644 --- a/x-pack/plugins/security_solution/common/endpoint/models/policy_config_helpers.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/models/policy_config_helpers.test.ts @@ -24,23 +24,29 @@ describe('Policy Config helpers', () => { supported: false, }; + const notSupportedBehaviorProtection: PolicyConfig['windows']['behavior_protection'] = { + mode: ProtectionModes.off, + supported: false, + reputation_service: false, + }; + const inputPolicyWithoutSupportedProtections: PolicyConfig = { ...defaultPolicy, windows: { ...defaultPolicy.windows, memory_protection: notSupported, - behavior_protection: notSupported, + behavior_protection: notSupportedBehaviorProtection, ransomware: notSupported, }, mac: { ...defaultPolicy.mac, memory_protection: notSupported, - behavior_protection: notSupported, + behavior_protection: notSupportedBehaviorProtection, }, linux: { ...defaultPolicy.linux, memory_protection: notSupported, - behavior_protection: notSupported, + behavior_protection: notSupportedBehaviorProtection, }, }; @@ -49,18 +55,18 @@ describe('Policy Config helpers', () => { windows: { ...eventsOnlyPolicy.windows, memory_protection: notSupported, - behavior_protection: notSupported, + behavior_protection: notSupportedBehaviorProtection, ransomware: notSupported, }, mac: { ...eventsOnlyPolicy.mac, memory_protection: notSupported, - behavior_protection: notSupported, + behavior_protection: notSupportedBehaviorProtection, }, linux: { ...eventsOnlyPolicy.linux, memory_protection: notSupported, - behavior_protection: notSupported, + behavior_protection: notSupportedBehaviorProtection, }, }; @@ -134,7 +140,7 @@ export const eventsOnlyPolicy: PolicyConfig = { malware: { mode: ProtectionModes.off, blocklist: false }, ransomware: { mode: ProtectionModes.off, supported: true }, memory_protection: { mode: ProtectionModes.off, supported: true }, - behavior_protection: { mode: ProtectionModes.off, supported: true }, + behavior_protection: { mode: ProtectionModes.off, supported: true, reputation_service: false }, popup: { malware: { message: '', enabled: false }, ransomware: { message: '', enabled: false }, @@ -148,7 +154,7 @@ export const eventsOnlyPolicy: PolicyConfig = { mac: { events: { process: true, file: true, network: true }, malware: { mode: ProtectionModes.off, blocklist: false }, - behavior_protection: { mode: ProtectionModes.off, supported: true }, + behavior_protection: { mode: ProtectionModes.off, supported: true, reputation_service: false }, memory_protection: { mode: ProtectionModes.off, supported: true }, popup: { malware: { message: '', enabled: false }, @@ -169,7 +175,7 @@ export const eventsOnlyPolicy: PolicyConfig = { tty_io: false, }, malware: { mode: ProtectionModes.off, blocklist: false }, - behavior_protection: { mode: ProtectionModes.off, supported: true }, + behavior_protection: { mode: ProtectionModes.off, supported: true, reputation_service: false }, memory_protection: { mode: ProtectionModes.off, supported: true }, popup: { malware: { message: '', enabled: false }, diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index 3e48770cd5b39..d3359e8389aae 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -967,7 +967,7 @@ export interface PolicyConfig { }; malware: ProtectionFields & BlocklistFields; memory_protection: ProtectionFields & SupportedFields; - behavior_protection: ProtectionFields & SupportedFields; + behavior_protection: BehaviorProtectionFields & SupportedFields; ransomware: ProtectionFields & SupportedFields; logging: { file: string; @@ -1007,7 +1007,7 @@ export interface PolicyConfig { network: boolean; }; malware: ProtectionFields & BlocklistFields; - behavior_protection: ProtectionFields & SupportedFields; + behavior_protection: BehaviorProtectionFields & SupportedFields; memory_protection: ProtectionFields & SupportedFields; popup: { malware: { @@ -1037,7 +1037,7 @@ export interface PolicyConfig { tty_io: boolean; }; malware: ProtectionFields & BlocklistFields; - behavior_protection: ProtectionFields & SupportedFields; + behavior_protection: BehaviorProtectionFields & SupportedFields; memory_protection: ProtectionFields & SupportedFields; popup: { malware: { @@ -1099,6 +1099,10 @@ export interface ProtectionFields { mode: ProtectionModes; } +export interface BehaviorProtectionFields extends ProtectionFields { + reputation_service: boolean; +} + /** Policy: Supported fields */ export interface SupportedFields { supported: boolean; diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index f12e31724f8f1..b2e1cae53d97e 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -111,6 +111,12 @@ export const allowedExperimentalValues = Object.freeze({ * Enables experimental Entity Analytics HTTP endpoints */ riskScoringRoutesEnabled: false, + /* + * + * Enables Discover embedded within timeline + * + * */ + discoverInTimeline: true, }); type ExperimentalConfigKeys = Array; diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index 15c4028dcb8e2..7148009246dcd 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -37,6 +37,7 @@ export enum TimelineTabs { eql = 'eql', session = 'session', securityAssistant = 'securityAssistant', + discover = 'discover', } /* diff --git a/x-pack/plugins/security_solution/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts index fe056192b62dc..96cd4da1d8130 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts @@ -13,6 +13,7 @@ import { USER_RISK_PREVIEW_TABLE_ROWS, RISK_PREVIEW_ERROR, RISK_PREVIEW_ERROR_BUTTON, + LOCAL_QUERY_BAR_SELECTOR, } from '../../screens/entity_analytics_management'; import { login, visit, visitWithoutDateRange } from '../../tasks/login'; @@ -52,7 +53,7 @@ describe('Entity analytics management page', () => { cy.get(HOST_RISK_PREVIEW_TABLE_ROWS).should('have.length', 5); cy.get(USER_RISK_PREVIEW_TABLE_ROWS).should('have.length', 5); - updateDateRangeInLocalDatePickers(START_DATE, END_DATE); + updateDateRangeInLocalDatePickers(LOCAL_QUERY_BAR_SELECTOR, START_DATE, END_DATE); cy.get(HOST_RISK_PREVIEW_TABLE).contains('No items found'); cy.get(USER_RISK_PREVIEW_TABLE).contains('No items found'); @@ -63,7 +64,7 @@ describe('Entity analytics management page', () => { cy.get(USER_RISK_PREVIEW_TABLE_ROWS).should('have.length', 5); fillLocalSearchBar('host.name: "test-host1"'); - submitLocalSearch(); + submitLocalSearch(LOCAL_QUERY_BAR_SELECTOR); cy.get(HOST_RISK_PREVIEW_TABLE_ROWS).should('have.length', 1); cy.get(HOST_RISK_PREVIEW_TABLE_ROWS).contains('test-host1'); diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts.ts b/x-pack/plugins/security_solution/cypress/screens/alerts.ts index 4677f3b6d9ad4..6578ddabf1f4d 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts.ts @@ -6,6 +6,7 @@ */ import { getDataTestSubjectSelector } from '../helpers/common'; +import { GLOBAL_FILTERS_CONTAINER } from './date_picker'; export const ADD_EXCEPTION_BTN = '[data-test-subj="add-exception-menu-item"]'; @@ -65,7 +66,7 @@ export const MANAGE_ALERT_DETECTION_RULES_BTN = '[data-test-subj="manage-alert-d export const MARK_ALERT_ACKNOWLEDGED_BTN = '[data-test-subj="acknowledged-alert-status"]'; -export const ALERTS_REFRESH_BTN = '[data-test-subj="querySubmitButton"]'; +export const ALERTS_REFRESH_BTN = `${GLOBAL_FILTERS_CONTAINER} [data-test-subj="querySubmitButton"]`; export const ALERTS_HISTOGRAM_PANEL_LOADER = '[data-test-subj="loadingPanelAlertsHistogram"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/date_picker.ts b/x-pack/plugins/security_solution/cypress/screens/date_picker.ts index bbb21f03d6eb0..5f5a39b96beb9 100644 --- a/x-pack/plugins/security_solution/cypress/screens/date_picker.ts +++ b/x-pack/plugins/security_solution/cypress/screens/date_picker.ts @@ -9,7 +9,9 @@ export const DATE_PICKER_ABSOLUTE_INPUT = '[data-test-subj="superDatePickerAbsol export const LOCAL_DATE_PICKER_APPLY_BUTTON = 'button[data-test-subj="querySubmitButton"]'; -export const DATE_PICKER_APPLY_BUTTON = `[data-test-subj="globalDatePicker"] ${LOCAL_DATE_PICKER_APPLY_BUTTON}`; +export const GLOBAL_FILTERS_CONTAINER = `[data-test-subj="filters-global-container"]`; + +export const DATE_PICKER_APPLY_BUTTON = `${GLOBAL_FILTERS_CONTAINER} ${LOCAL_DATE_PICKER_APPLY_BUTTON}`; export const LOCAL_DATE_PICKER_APPLY_BUTTON_TIMELINE = 'button[data-test-subj="superDatePickerApplyTimeButton"]'; @@ -25,7 +27,9 @@ export const DATE_PICKER_NOW_BUTTON = '[data-test-subj="superDatePickerNowButton export const LOCAL_DATE_PICKER_END_DATE_POPOVER_BUTTON = '[data-test-subj="superDatePickerendDatePopoverButton"]'; -export const DATE_PICKER_END_DATE_POPOVER_BUTTON = `[data-test-subj="globalDatePicker"] ${LOCAL_DATE_PICKER_END_DATE_POPOVER_BUTTON}`; +export const DATE_PICKER_END_DATE_POPOVER_BUTTON = `${GLOBAL_FILTERS_CONTAINER} ${LOCAL_DATE_PICKER_END_DATE_POPOVER_BUTTON}`; + +export const DATE_PICKER_CONTAINER = `${GLOBAL_FILTERS_CONTAINER} .euiSuperDatePicker`; export const DATE_PICKER_END_DATE_POPOVER_BUTTON_TIMELINE = '[data-test-subj="timeline-date-picker-container"] [data-test-subj="superDatePickerendDatePopoverButton"]'; @@ -33,11 +37,12 @@ export const DATE_PICKER_END_DATE_POPOVER_BUTTON_TIMELINE = export const LOCAL_DATE_PICKER_START_DATE_POPOVER_BUTTON = 'button[data-test-subj="superDatePickerstartDatePopoverButton"]'; -export const DATE_PICKER_START_DATE_POPOVER_BUTTON = `div[data-test-subj="globalDatePicker"] ${LOCAL_DATE_PICKER_START_DATE_POPOVER_BUTTON}`; +export const DATE_PICKER_START_DATE_POPOVER_BUTTON = `${GLOBAL_FILTERS_CONTAINER} ${LOCAL_DATE_PICKER_START_DATE_POPOVER_BUTTON}`; -export const GLOBAL_FILTERS_CONTAINER = '[data-test-subj="globalDatePicker"]'; +export const SHOW_DATES_BUTTON = `${GLOBAL_FILTERS_CONTAINER} [data-test-subj="superDatePickerShowDatesButton"]`; -export const SHOW_DATES_BUTTON = '[data-test-subj="superDatePickerShowDatesButton"]'; +export const GET_LOCAL_SHOW_DATES_BUTTON = (localQueryBarSelector: string) => + `${localQueryBarSelector} [data-test-subj="superDatePickerShowDatesButton"]`; export const DATE_PICKER_SHOW_DATE_POPOVER_BUTTON = `${GLOBAL_FILTERS_CONTAINER} ${SHOW_DATES_BUTTON}`; diff --git a/x-pack/plugins/security_solution/cypress/screens/entity_analytics_management.ts b/x-pack/plugins/security_solution/cypress/screens/entity_analytics_management.ts index 660c20a960de6..f4c0fa83db1ea 100644 --- a/x-pack/plugins/security_solution/cypress/screens/entity_analytics_management.ts +++ b/x-pack/plugins/security_solution/cypress/screens/entity_analytics_management.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { getDataTestSubjectSelector } from '../helpers/common'; + export const PAGE_TITLE = '[data-test-subj="entityAnalyticsManagmentPageTitle"]'; export const HOST_RISK_PREVIEW_TABLE = '[data-test-subj="host-risk-preview-table"]'; @@ -18,3 +20,5 @@ export const USER_RISK_PREVIEW_TABLE_ROWS = '[data-test-subj="user-risk-preview- export const RISK_PREVIEW_ERROR = '[data-test-subj="risk-preview-error"]'; export const RISK_PREVIEW_ERROR_BUTTON = '[data-test-subj="risk-preview-error-button"]'; + +export const LOCAL_QUERY_BAR_SELECTOR = getDataTestSubjectSelector('risk-score-preview-search-bar'); diff --git a/x-pack/plugins/security_solution/cypress/screens/search_bar.ts b/x-pack/plugins/security_solution/cypress/screens/search_bar.ts index 1ffd720451108..d90532f8504f3 100644 --- a/x-pack/plugins/security_solution/cypress/screens/search_bar.ts +++ b/x-pack/plugins/security_solution/cypress/screens/search_bar.ts @@ -5,12 +5,15 @@ * 2.0. */ +export const GLOBAL_KQL_WRAPPER = '[data-test-subj="filters-global-container"]'; + export const GLOBAL_SEARCH_BAR_ADD_FILTER = '[data-test-subj="globalDatePicker"] [data-test-subj="addFilter"]'; -export const LOCAL_SEACH_BAR_SUBMMIT_BUTTON = '[data-test-subj="querySubmitButton"]'; +export const GLOBAL_SEARCH_BAR_SUBMIT_BUTTON = `${GLOBAL_KQL_WRAPPER} [data-test-subj="querySubmitButton"]`; -export const GLOBAL_SEARCH_BAR_SUBMIT_BUTTON = `[data-test-subj="globalDatePicker"] ${LOCAL_SEACH_BAR_SUBMMIT_BUTTON}`; +export const GET_LOCAL_SEARCH_BAR_SUBMIT_BUTTON = (localSearchBarSelector: string) => + `${localSearchBarSelector ?? ''} [data-test-subj="querySubmitButton"]`; export const ADD_FILTER_FORM_FIELD_INPUT = '[data-test-subj="filterFieldSuggestionList"] input[data-test-subj="comboBoxSearchInput"]'; @@ -36,8 +39,6 @@ export const GLOBAL_SEARCH_BAR_FILTER_ITEM_DELETE = '#popoverFor_filter0 button[ export const GLOBAL_SEARCH_BAR_PINNED_FILTER = '.globalFilterItem-isPinned'; -export const GLOBAL_KQL_WRAPPER = '[data-test-subj="filters-global-container"]'; - export const LOCAL_KQL_INPUT = `[data-test-subj="unifiedQueryInput"] textarea`; export const GLOBAL_KQL_INPUT = `[data-test-subj="filters-global-container"] ${LOCAL_KQL_INPUT}`; diff --git a/x-pack/plugins/security_solution/cypress/screens/security_header.ts b/x-pack/plugins/security_solution/cypress/screens/security_header.ts index 9bf01fef56b24..2720e4e1a60e3 100644 --- a/x-pack/plugins/security_solution/cypress/screens/security_header.ts +++ b/x-pack/plugins/security_solution/cypress/screens/security_header.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { GLOBAL_KQL_WRAPPER } from './search_bar'; + // main links export const DASHBOARDS = '[data-test-subj="solutionSideNavItemLink-dashboards"]'; export const DASHBOARDS_PANEL_BTN = '[data-test-subj="solutionSideNavItemButton-dashboards"]'; @@ -68,9 +70,9 @@ export const EXCEPTIONS = '[data-test-subj="solutionSideNavPanelLink-exceptions" // other export const BREADCRUMBS = '[data-test-subj="breadcrumbs"] a'; -export const KQL_INPUT = '[data-test-subj="queryInput"]'; +export const KQL_INPUT = `${GLOBAL_KQL_WRAPPER} [data-test-subj="queryInput"]`; -export const REFRESH_BUTTON = '[data-test-subj="querySubmitButton"]'; +export const REFRESH_BUTTON = `${GLOBAL_KQL_WRAPPER} [data-test-subj="querySubmitButton"]`; export const LOADING_INDICATOR = '[data-test-subj="globalLoadingIndicator"]'; export const LOADING_INDICATOR_HIDDEN = '[data-test-subj="globalLoadingIndicator-hidden"]'; diff --git a/x-pack/plugins/security_solution/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts index d46b0d04f3355..3b3639f9234d5 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timeline.ts @@ -9,7 +9,8 @@ import type { TimelineFilter } from '../objects/timeline'; export const ADD_NOTE_BUTTON = '[data-test-subj="add-note"]'; -export const ADD_FILTER = '[data-test-subj="timeline"] [data-test-subj="addFilter"]'; +export const ADD_FILTER = + '[data-test-subj="timeline-search-or-filter"] [data-test-subj="addFilter"]'; export const ATTACH_TIMELINE_TO_CASE_BUTTON = '[data-test-subj="attach-timeline-case-button"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/date_picker.ts b/x-pack/plugins/security_solution/cypress/tasks/date_picker.ts index a3b7a3f0ce1ec..4a74ac3ddd7fa 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/date_picker.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/date_picker.ts @@ -13,7 +13,6 @@ import { DATE_PICKER_END_DATE_POPOVER_BUTTON, DATE_PICKER_END_DATE_POPOVER_BUTTON_TIMELINE, DATE_PICKER_START_DATE_POPOVER_BUTTON, - GLOBAL_FILTERS_CONTAINER, SHOW_DATES_BUTTON, DATE_PICKER_START_DATE_POPOVER_BUTTON_TIMELINE, DATE_PICKER_SHOW_DATE_POPOVER_BUTTON, @@ -21,6 +20,8 @@ import { DATE_PICKER_NOW_BUTTON, LOCAL_DATE_PICKER_APPLY_BUTTON, LOCAL_DATE_PICKER_END_DATE_POPOVER_BUTTON, + DATE_PICKER_CONTAINER, + GET_LOCAL_SHOW_DATES_BUTTON, } from '../screens/date_picker'; export const setEndDate = (date: string) => { @@ -42,8 +43,7 @@ export const setEndDateNow = () => { }; export const setStartDate = (date: string) => { - cy.get(GLOBAL_FILTERS_CONTAINER); - cy.get('.euiSuperDatePicker'); + cy.get(DATE_PICKER_CONTAINER).should('be.visible'); cy.get('body').then(($container) => { if ($container.find(SHOW_DATES_BUTTON).length > 0) { cy.get(DATE_PICKER_SHOW_DATE_POPOVER_BUTTON).click({ force: true }); @@ -101,8 +101,12 @@ export const updateTimelineDates = () => { cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE).first().should('not.have.text', 'Updating'); }; -export const updateDateRangeInLocalDatePickers = (startDate: string, endDate: string) => { - cy.get(SHOW_DATES_BUTTON).click(); +export const updateDateRangeInLocalDatePickers = ( + localQueryBarSelector: string, + startDate: string, + endDate: string +) => { + cy.get(GET_LOCAL_SHOW_DATES_BUTTON(localQueryBarSelector)).click(); cy.get(DATE_PICKER_ABSOLUTE_TAB).first().click(); cy.get(DATE_PICKER_ABSOLUTE_INPUT).click(); diff --git a/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts b/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts index 144b71f5b2ff5..94d3d064d8e0e 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts @@ -18,7 +18,7 @@ import { ADD_FILTER_FORM_FILTER_VALUE_INPUT, GLOBAL_KQL_INPUT, LOCAL_KQL_INPUT, - LOCAL_SEACH_BAR_SUBMMIT_BUTTON, + GET_LOCAL_SEARCH_BAR_SUBMIT_BUTTON, } from '../screens/search_bar'; export const openAddFilterPopover = () => { @@ -72,6 +72,6 @@ export const fillLocalSearchBar = (query: string) => { cy.get(LOCAL_KQL_INPUT).type(query); }; -export const submitLocalSearch = () => { - cy.get(LOCAL_SEACH_BAR_SUBMMIT_BUTTON).click(); +export const submitLocalSearch = (localSearchBarSelector: string) => { + cy.get(GET_LOCAL_SEARCH_BAR_SUBMIT_BUTTON(localSearchBarSelector)).click(); }; diff --git a/x-pack/plugins/security_solution/kibana.jsonc b/x-pack/plugins/security_solution/kibana.jsonc index 8f3ced69de6e3..f4716adfca310 100644 --- a/x-pack/plugins/security_solution/kibana.jsonc +++ b/x-pack/plugins/security_solution/kibana.jsonc @@ -6,7 +6,10 @@ "id": "securitySolution", "server": true, "browser": true, - "configPath": ["xpack", "securitySolution"], + "configPath": [ + "xpack", + "securitySolution" + ], "requiredPlugins": [ "actions", "alerting", @@ -29,6 +32,7 @@ "lens", "licensing", "maps", + "navigation", "ruleRegistry", "sessionView", "spaces", @@ -40,8 +44,11 @@ "unifiedSearch", "files", "controls", + "dataViewEditor", "savedObjectsManagement", - "stackConnectors" + "stackConnectors", + "discover", + "notifications" ], "optionalPlugins": [ "cloudExperiments", @@ -69,6 +76,8 @@ "unifiedSearch", "cloudChat" ], - "extraPublicDirs": ["common"] + "extraPublicDirs": [ + "common" + ] } } diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts index de9750af2541c..0d192428c081e 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts @@ -10,6 +10,8 @@ import React from 'react'; import type { RecursivePartial } from '@elastic/eui/src/components/common'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; +import { navigationPluginMock } from '@kbn/navigation-plugin/public/mocks'; +import { discoverPluginMock } from '@kbn/discover-plugin/public/mocks'; import { coreMock, themeServiceMock } from '@kbn/core/public/mocks'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; @@ -102,11 +104,14 @@ export const createStartServicesMock = ( const { storage } = createSecuritySolutionStorageMock(); const apm = mockApm(); const data = dataPluginMock.createStartContract(); + const customDataService = dataPluginMock.createStartContract(); const security = securityMock.createSetup(); const urlService = new MockUrlService(); const locator = urlService.locators.create(new MlLocatorDefinition()); const fleet = fleetMock.createStartMock(); const unifiedSearch = unifiedSearchPluginMock.createStartContract(); + const navigation = navigationPluginMock.createStartContract(); + const discover = discoverPluginMock.createStartContract(); const cases = mockCasesContract(); const dataViewServiceMock = dataViewPluginMocks.createStartContract(); cases.helpers.getUICapabilities.mockReturnValue(noCasesPermissions()); @@ -119,6 +124,8 @@ export const createStartServicesMock = ( apm, cases, unifiedSearch, + navigation, + discover, dataViews: dataViewServiceMock, data: { ...data, @@ -193,6 +200,7 @@ export const createStartServicesMock = ( guidedOnboarding, isSidebarEnabled$: of(true), upselling: new UpsellingService(), + customDataService, } as unknown as StartServices; }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_section.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_section.tsx index d5fc0c3fd9107..5636daa39f4e6 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_section.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_section.tsx @@ -156,7 +156,7 @@ export const RiskScorePreviewSection = () => { {i18n.PREVIEW_DESCRIPTION} - + {indexPattern && ( { - cy.getByTestSubj('queryInput').click().type(text); - cy.getByTestSubj('querySubmitButton').click(); + cy.getByTestSubj('filters-global-container').within(() => { + cy.getByTestSubj('queryInput').click().type(text); + cy.getByTestSubj('querySubmitButton').click(); + }); }; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts index d2876f1bcdd24..f73242f036c90 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts @@ -283,7 +283,11 @@ describe('policy details: ', () => { }, malware: { mode: 'prevent', blocklist: true }, memory_protection: { mode: 'off', supported: false }, - behavior_protection: { mode: 'off', supported: false }, + behavior_protection: { + mode: 'off', + supported: false, + reputation_service: false, + }, ransomware: { mode: 'off', supported: false }, attack_surface_reduction: { credential_hardening: { @@ -316,7 +320,11 @@ describe('policy details: ', () => { mac: { events: { process: true, file: true, network: true }, malware: { mode: 'prevent', blocklist: true }, - behavior_protection: { mode: 'off', supported: false }, + behavior_protection: { + mode: 'off', + supported: false, + reputation_service: false, + }, memory_protection: { mode: 'off', supported: false }, popup: { malware: { @@ -348,7 +356,11 @@ describe('policy details: ', () => { }, logging: { file: 'info' }, malware: { mode: 'prevent', blocklist: true }, - behavior_protection: { mode: 'off', supported: false }, + behavior_protection: { + mode: 'off', + supported: false, + reputation_service: false, + }, memory_protection: { mode: 'off', supported: false }, popup: { malware: { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.test.tsx index 949c84324f7aa..3eeee6db3d622 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.test.tsx @@ -10,13 +10,16 @@ import type { AppContextTestRender } from '../../../../../../../common/mock/endp import { createAppRootMockRenderer } from '../../../../../../../common/mock/endpoint'; import { FleetPackagePolicyGenerator } from '../../../../../../../../common/endpoint/data_generators/fleet_package_policy_generator'; import React from 'react'; -import type { BehaviourProtectionCardProps } from './behaviour_protection_card'; -import { BehaviourProtectionCard, LOCKED_CARD_BEHAVIOR_TITLE } from './behaviour_protection_card'; import { licenseService as licenseServiceMocked } from '../../../../../../../common/hooks/__mocks__/use_license'; import { useLicense as _useLicense } from '../../../../../../../common/hooks/use_license'; import { createLicenseServiceMock } from '../../../../../../../../common/license/mocks'; import { set } from 'lodash'; import { ProtectionModes } from '../../../../../../../../common/endpoint/types'; +import type { BehaviourProtectionCardProps } from './protection_seetings_card/behaviour_protection_card'; +import { + BehaviourProtectionCard, + LOCKED_CARD_BEHAVIOR_TITLE, +} from './protection_seetings_card/behaviour_protection_card'; jest.mock('../../../../../../../common/hooks/use_license'); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/protection_seetings_card/behaviour_protection_card.tsx similarity index 72% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/protection_seetings_card/behaviour_protection_card.tsx index 1a71e384146c4..1a4a37f9d5c81 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/protection_seetings_card/behaviour_protection_card.tsx @@ -9,18 +9,19 @@ import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; import { OperatingSystem } from '@kbn/securitysolution-utils'; import { EuiSpacer } from '@elastic/eui'; -import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; -import { SettingCard } from '../setting_card'; -import { NotifyUserOption } from '../notify_user_option'; -import { DetectPreventProtectionLevel } from '../detect_prevent_protection_level'; -import { ProtectionSettingCardSwitch } from '../protection_setting_card_switch'; -import type { Immutable } from '../../../../../../../../common/endpoint/types'; -import { PolicyOperatingSystem } from '../../../../../../../../common/endpoint/types'; -import type { BehaviorProtectionOSes } from '../../../../types'; -import { useLicense } from '../../../../../../../common/hooks/use_license'; -import { SettingLockedCard } from '../setting_locked_card'; -import type { PolicyFormComponentCommonProps } from '../../types'; -import { RelatedDetectionRulesCallout } from '../related_detection_rules_callout'; +import { RelatedDetectionRulesCallout } from '../../related_detection_rules_callout'; +import { ReputationService } from './components/reputation_service'; +import { useTestIdGenerator } from '../../../../../../../hooks/use_test_id_generator'; +import { SettingCard } from '../../setting_card'; +import { NotifyUserOption } from '../../notify_user_option'; +import { DetectPreventProtectionLevel } from '../../detect_prevent_protection_level'; +import { ProtectionSettingCardSwitch } from '../../protection_setting_card_switch'; +import type { Immutable } from '../../../../../../../../../common/endpoint/types'; +import { PolicyOperatingSystem } from '../../../../../../../../../common/endpoint/types'; +import type { BehaviorProtectionOSes } from '../../../../../types'; +import { useLicense } from '../../../../../../../../common/hooks/use_license'; +import { SettingLockedCard } from '../../setting_locked_card'; +import type { PolicyFormComponentCommonProps } from '../../../types'; export const LOCKED_CARD_BEHAVIOR_TITLE = i18n.translate( 'xpack.securitySolution.endpoint.policy.details.behavior', @@ -86,6 +87,13 @@ export const BehaviourProtectionCard = memo( data-test-subj={getTestId('protectionLevel')} /> + + { + const isEditMode = mode === 'edit'; + + const { cloud } = useKibana().services; + const isCloud = cloud?.isCloudEnabled ?? false; + + const getTestId = useTestIdGenerator(dataTestSubj); + + const protectionTurnedOn = policy.windows.behavior_protection.mode !== ProtectionModes.off; + + const checkboxChecked = + policy.windows.behavior_protection.reputation_service && protectionTurnedOn; + + const handleChange = useCallback( + (event) => { + const newPayload = cloneDeep(policy); + newPayload.windows.behavior_protection.reputation_service = event.target.checked; + newPayload.mac.behavior_protection.reputation_service = event.target.checked; + newPayload.linux.behavior_protection.reputation_service = event.target.checked; + + onChange({ isValid: true, updatedPolicy: newPayload }); + }, + [policy, onChange] + ); + + const checkboxLabel = checkboxChecked + ? USE_REPUTATION_SERVICE_CHECKBOX_LABEL + : DO_NOT_USE_REPUTATION_SERVICE_CHECKBOX_LABEL; + + if (!isCloud) { + return null; + } + + return ( +
+ + + + + +

+ +

+
+
+ + + } + /> + +
+
+ + {isEditMode ? ( + + ) : ( + <>{checkboxLabel} + )} +
+ ); + } +); + +ReputationService.displayName = 'ReputationService'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx index b55fbeba172ba..32dfebbfb46f3 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx @@ -84,6 +84,11 @@ export const ProtectionSettingCardSwitch = React.memo( newPayload[os].popup[protection as LinuxPolicyProtection].enabled = event.target.checked; } + if (protection === 'behavior_protection') { + newPayload.windows.behavior_protection.reputation_service = false; + newPayload.mac.behavior_protection.reputation_service = false; + newPayload.linux.behavior_protection.reputation_service = false; + } } } } else { @@ -96,6 +101,11 @@ export const ProtectionSettingCardSwitch = React.memo( newPayload[os][protection as LinuxPolicyProtection].mode = ProtectionModes.prevent; } if (isPlatinumPlus) { + if (protection === 'behavior_protection') { + newPayload.windows.behavior_protection.reputation_service = false; + newPayload.mac.behavior_protection.reputation_service = false; + newPayload.linux.behavior_protection.reputation_service = false; + } if (os === 'windows') { newPayload[os].popup[protection].enabled = event.target.checked; } else if (os === 'mac') { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx index 8771e40e4be7c..623c61ebbf0ee 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx @@ -13,7 +13,7 @@ import { LinuxEventCollectionCard } from './components/cards/linux_event_collect import { MacEventCollectionCard } from './components/cards/mac_event_collection_card'; import { WindowsEventCollectionCard } from './components/cards/windows_event_collection_card'; import { AttackSurfaceReductionCard } from './components/cards/attack_surface_reduction_card'; -import { BehaviourProtectionCard } from './components/cards/behaviour_protection_card'; +import { BehaviourProtectionCard } from './components/cards/protection_seetings_card/behaviour_protection_card'; import { MemoryProtectionCard } from './components/cards/memory_protection_card'; import { RansomwareProtectionCard } from './components/cards/ransomware_protection_card'; import { MalwareProtectionsCard } from './components/cards/malware_protections_card'; diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 0a54b27cfa9fd..caa9dc3735e99 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -16,6 +16,8 @@ import type { PluginInitializerContext, Plugin as IPlugin, } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { FilterManager, NowProvider, QueryService } from '@kbn/data-plugin/public'; import { DEFAULT_APP_CATEGORIES, AppNavLinkStatus } from '@kbn/core/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import type { @@ -79,6 +81,8 @@ export class Plugin implements IPlugin(); @@ -90,6 +94,7 @@ export class Plugin implements IPlugin(); @@ -124,6 +129,12 @@ export class Plugin implements IPlugin { ); + await waitFor(() => { expect(EmptyComponent.getByTestId('flyout-pane')).toHaveStyle('display: block'); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/index.test.tsx new file mode 100644 index 0000000000000..db874f9a81245 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/index.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { TestProviders } from '../../../../common/mock'; +import DiscoverTabContent from '.'; +import { render, screen, waitFor } from '@testing-library/react'; + +const TestComponent = () => { + return ( + + + + ); +}; + +describe('Discover Tab Content', () => { + it('renders', async () => { + render(); + + await waitFor(() => { + expect(screen.getByTestId('timeline-embedded-discover')).toBeInTheDocument(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/index.tsx new file mode 100644 index 0000000000000..d853baefbbd8e --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/index.tsx @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { useHistory } from 'react-router-dom'; +import type { CustomizationCallback } from '@kbn/discover-plugin/public/customizations/types'; +import styled, { createGlobalStyle } from 'styled-components'; +import type { ScopedHistory } from '@kbn/core/public'; +import { useKibana } from '../../../../common/lib/kibana'; +import { useGetStatefulQueryBar } from './use_get_stateful_query_bar'; + +const HideSearchSessionIndicatorBreadcrumbIcon = createGlobalStyle` + [data-test-subj='searchSessionIndicator'] { + display: none; + } +`; + +const EmbeddedDiscoverContainer = styled.div` + width: 100%; + height: 100%; + overflow: scroll; + display: grid, + place-items: center +`; + +export const DiscoverTabContent = () => { + const history = useHistory(); + const { + services: { customDataService: discoverDataService, discover, discoverFilterManager }, + } = useKibana(); + + const { CustomStatefulTopNavKqlQueryBar } = useGetStatefulQueryBar(); + + const customize: CustomizationCallback = useCallback( + ({ customizations }) => { + customizations.set({ + id: 'search_bar', + CustomSearchBar: CustomStatefulTopNavKqlQueryBar, + }); + }, + [CustomStatefulTopNavKqlQueryBar] + ); + + const services = useMemo( + () => ({ + filterManager: discoverFilterManager, + data: discoverDataService, + }), + [discoverDataService, discoverFilterManager] + ); + + const DiscoverContainer = discover.DiscoverContainer; + + return ( + + + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export default DiscoverTabContent; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/use_get_stateful_query_bar.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/use_get_stateful_query_bar.test.tsx new file mode 100644 index 0000000000000..6f3951e3ecac1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/use_get_stateful_query_bar.test.tsx @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TestProviders } from '../../../../common/mock'; +import { renderHook } from '@testing-library/react-hooks'; +import { useGetStatefulQueryBar } from './use_get_stateful_query_bar'; + +describe('useGetStatefulQueryBar', () => { + it('returns custom QueryBar', async () => { + const { result } = renderHook(() => useGetStatefulQueryBar(), { + wrapper: TestProviders, + }); + + expect(result.current).toHaveProperty('CustomStatefulTopNavKqlQueryBar'); + expect(result.current.CustomStatefulTopNavKqlQueryBar).not.toBeUndefined(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/use_get_stateful_query_bar.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/use_get_stateful_query_bar.tsx new file mode 100644 index 0000000000000..61ccaeaef2a65 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/discover_tab_content/use_get_stateful_query_bar.tsx @@ -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 { useMemo } from 'react'; +import { useKibana } from '../../../../common/lib/kibana'; + +export const useGetStatefulQueryBar = () => { + const { + services: { + navigation: { + ui: { createTopNavWithCustomContext }, + }, + unifiedSearch, + customDataService, + }, + } = useKibana(); + + const { + ui: { getCustomSearchBar }, + } = unifiedSearch; + + const CustomSearchBar = useMemo( + () => getCustomSearchBar(customDataService), + [customDataService, getCustomSearchBar] + ); + + const CustomStatefulTopNavKqlQueryBar = useMemo(() => { + const customUnifiedSearch = { + ...unifiedSearch, + ui: { + ...unifiedSearch.ui, + SearchBar: CustomSearchBar, + AggregateQuerySearchBar: CustomSearchBar, + }, + }; + + return createTopNavWithCustomContext(customUnifiedSearch); + }, [CustomSearchBar, createTopNavWithCustomContext, unifiedSearch]); + + return { + CustomStatefulTopNavKqlQueryBar, + }; +}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx index f6bf0adf45a15..15bcf2ed0f011 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx @@ -9,10 +9,12 @@ import { EuiBadge, EuiSkeletonText, EuiTabs, EuiTab } from '@elastic/eui'; import { css } from '@emotion/react'; import { Assistant } from '@kbn/elastic-assistant'; import { isEmpty } from 'lodash/fp'; +import type { Ref, ReactElement, ComponentType } from 'react'; import React, { lazy, memo, Suspense, useCallback, useEffect, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; +import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { useConversationStore } from '../../../../assistant/use_conversation_store'; import { useAssistantAvailability } from '../../../../assistant/use_assistant_availability'; import type { SessionViewConfig } from '../../../../../common/types'; @@ -52,17 +54,37 @@ const HideShowContainer = styled.div.attrs<{ $isVisible: boolean; isOverflowYScr flex: 1; `; +/** + * A HOC which supplies React.Suspense with a fallback component + * @param Component A component deferred by `React.lazy` + * @param fallback A fallback component to render while things load. Default is EuiSekeleton for all tabs + */ +const tabWithSuspense =

( + Component: ComponentType

, + fallback: ReactElement | null = +) => { + const Comp = React.forwardRef((props: P, ref: Ref) => ( + + + + )); + + Comp.displayName = `${Component.displayName ?? 'Tab'}WithSuspense`; + return Comp; +}; + const AssistantTabContainer = styled.div` overflow-y: auto; width: 100%; `; -const QueryTabContent = lazy(() => import('../query_tab_content')); -const EqlTabContent = lazy(() => import('../eql_tab_content')); -const GraphTabContent = lazy(() => import('../graph_tab_content')); -const NotesTabContent = lazy(() => import('../notes_tab_content')); -const PinnedTabContent = lazy(() => import('../pinned_tab_content')); -const SessionTabContent = lazy(() => import('../session_tab_content')); +const QueryTab = tabWithSuspense(lazy(() => import('../query_tab_content'))); +const EqlTab = tabWithSuspense(lazy(() => import('../eql_tab_content'))); +const GraphTab = tabWithSuspense(lazy(() => import('../graph_tab_content'))); +const NotesTab = tabWithSuspense(lazy(() => import('../notes_tab_content'))); +const PinnedTab = tabWithSuspense(lazy(() => import('../pinned_tab_content'))); +const SessionTab = tabWithSuspense(lazy(() => import('../session_tab_content'))); +const DiscoverTab = tabWithSuspense(lazy(() => import('../discover_tab_content'))); interface BasicTimelineTab { renderCellValue: (props: CellValueElementProps) => React.ReactNode; @@ -75,72 +97,6 @@ interface BasicTimelineTab { timelineDescription: string; } -const QueryTab: React.FC<{ - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - rowRenderers: RowRenderer[]; - timelineId: TimelineId; -}> = memo(({ renderCellValue, rowRenderers, timelineId }) => ( - }> - - -)); -QueryTab.displayName = 'QueryTab'; - -const EqlTab: React.FC<{ - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - rowRenderers: RowRenderer[]; - timelineId: TimelineId; -}> = memo(({ renderCellValue, rowRenderers, timelineId }) => ( - }> - - -)); -EqlTab.displayName = 'EqlTab'; - -const GraphTab: React.FC<{ timelineId: TimelineId }> = memo(({ timelineId }) => ( - }> - - -)); -GraphTab.displayName = 'GraphTab'; - -const NotesTab: React.FC<{ timelineId: TimelineId }> = memo(({ timelineId }) => ( - }> - - -)); -NotesTab.displayName = 'NotesTab'; - -const SessionTab: React.FC<{ timelineId: TimelineId }> = memo(({ timelineId }) => ( - }> - - -)); -SessionTab.displayName = 'SessionTab'; - -const PinnedTab: React.FC<{ - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - rowRenderers: RowRenderer[]; - timelineId: TimelineId; -}> = memo(({ renderCellValue, rowRenderers, timelineId }) => ( - }> - - -)); -PinnedTab.displayName = 'PinnedTab'; - const AssistantTab: React.FC<{ isAssistantEnabled: boolean; renderCellValue: (props: CellValueElementProps) => React.ReactNode; @@ -177,6 +133,7 @@ const ActiveTimelineTab = memo( timelineType, showTimeline, }) => { + const isDiscoverInTimelineEnabled = useIsExperimentalFeatureEnabled('discoverInTimeline'); const { hasAssistantPrivilege, isAssistantEnabled } = useAssistantAvailability(); const getTab = useCallback( (tab: TimelineTabs) => { @@ -276,6 +233,14 @@ const ActiveTimelineTab = memo( )} )} + {isDiscoverInTimelineEnabled && ( + + + + )} ); } @@ -313,6 +278,7 @@ const TabsContentComponent: React.FC = ({ sessionViewConfig, timelineDescription, }) => { + const isDiscoverInTimelineEnabled = useIsExperimentalFeatureEnabled('discoverInTimeline'); const { hasAssistantPrivilege } = useAssistantAvailability(); const dispatch = useDispatch(); const getActiveTab = useMemo(() => getActiveTabSelector(), []); @@ -388,6 +354,10 @@ const TabsContentComponent: React.FC = ({ setActiveTab(TimelineTabs.securityAssistant); }, [setActiveTab]); + const setDiscoverAsActiveTab = useCallback(() => { + setActiveTab(TimelineTabs.discover); + }, [setActiveTab]); + useEffect(() => { if (!graphEventId && activeTab === TimelineTabs.graph) { setQueryAsActiveTab(); @@ -479,6 +449,17 @@ const TabsContentComponent: React.FC = ({ {i18n.SECURITY_ASSISTANT} )} + {isDiscoverInTimelineEnabled && ( + + {i18n.DISCOVER_IN_TIMELINE_TAB} + + )} )} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts index f8daba8330a43..e900af321c030 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts @@ -46,6 +46,13 @@ export const SECURITY_ASSISTANT = i18n.translate( } ); +export const DISCOVER_IN_TIMELINE_TAB = i18n.translate( + 'xpack.securitySolution.timeline.tabs.discoverInTimeline', + { + defaultMessage: 'Discover', + } +); + export const SESSION_TAB = i18n.translate( 'xpack.securitySolution.timeline.tabs.sessionTabTimelineTitle', { diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 358111dd55265..62924b89b872c 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -9,7 +9,7 @@ import type { Observable } from 'rxjs'; import type { AppLeaveHandler, CoreStart } from '@kbn/core/public'; import type { HomePublicPluginSetup } from '@kbn/home-plugin/public'; -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { DataPublicPluginStart, FilterManager } from '@kbn/data-plugin/public'; import type { FieldFormatsStartCommon } from '@kbn/field-formats-plugin/common'; import type { EmbeddableStart } from '@kbn/embeddable-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; @@ -50,6 +50,9 @@ import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/ import type { DataViewsServicePublic } from '@kbn/data-views-plugin/public'; import type { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; +import type { DiscoverStart } from '@kbn/discover-plugin/public'; +import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public'; +import type { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; import type { ResolverPluginSetup } from './resolver/types'; import type { Inspect } from '../common/search_strategy'; import type { Detections } from './detections'; @@ -122,6 +125,9 @@ export interface StartPlugins { cloudExperiments?: CloudExperimentsPluginStart; dataViews: DataViewsServicePublic; fieldFormats: FieldFormatsStartCommon; + discover: DiscoverStart; + navigation: NavigationPublicPluginStart; + dataViewEditor: DataViewEditorStart; } export interface StartPluginsDependencies extends StartPlugins { @@ -153,6 +159,8 @@ export type StartServices = CoreStart & }; savedObjectsManagement: SavedObjectsManagementPluginStart; telemetry: TelemetryClientStart; + discoverFilterManager: FilterManager; + customDataService: DataPublicPluginStart; }; export interface PluginSetup { diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts index 867876d6345a3..58dcd24bdf916 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts @@ -49,9 +49,14 @@ describe('Create Default Policy tests ', () => { // check some of the protections to be disabled const disabledButSupported = { mode: ProtectionModes.off, supported: true }; - expect(policy.windows.behavior_protection).toEqual(disabledButSupported); + const disabledButSupportedBehaviorProtection = { + mode: ProtectionModes.off, + supported: true, + reputation_service: false, + }; + expect(policy.windows.behavior_protection).toEqual(disabledButSupportedBehaviorProtection); expect(policy.mac.memory_protection).toEqual(disabledButSupported); - expect(policy.linux.behavior_protection).toEqual(disabledButSupported); + expect(policy.linux.behavior_protection).toEqual(disabledButSupportedBehaviorProtection); // malware popups should be disabled expect(policy.windows.popup.malware.enabled).toBeFalsy(); @@ -72,9 +77,14 @@ describe('Create Default Policy tests ', () => { // check some of the protections to be disabled and unsupported const disabledAndUnsupported = { mode: ProtectionModes.off, supported: false }; - expect(policy.windows.behavior_protection).toEqual(disabledAndUnsupported); + const disabledAndUnsupportedBehaviorProtection = { + mode: ProtectionModes.off, + supported: false, + reputation_service: false, + }; + expect(policy.windows.behavior_protection).toEqual(disabledAndUnsupportedBehaviorProtection); expect(policy.mac.memory_protection).toEqual(disabledAndUnsupported); - expect(policy.linux.behavior_protection).toEqual(disabledAndUnsupported); + expect(policy.linux.behavior_protection).toEqual(disabledAndUnsupportedBehaviorProtection); // malware popups are enabled on unpaid license expect(policy.windows.popup.malware.enabled).toBeTruthy(); @@ -130,9 +140,14 @@ describe('Create Default Policy tests ', () => { // check some of the protections to be disabled const disabledButSupported = { mode: ProtectionModes.off, supported: true }; - expect(policy.windows.behavior_protection).toEqual(disabledButSupported); + const disabledButSupportedBehaviorProtection = { + mode: ProtectionModes.off, + supported: true, + reputation_service: false, + }; + expect(policy.windows.behavior_protection).toEqual(disabledButSupportedBehaviorProtection); expect(policy.mac.memory_protection).toEqual(disabledButSupported); - expect(policy.linux.behavior_protection).toEqual(disabledButSupported); + expect(policy.linux.behavior_protection).toEqual(disabledButSupportedBehaviorProtection); // malware popups should be disabled expect(policy.windows.popup.malware.enabled).toBeFalsy(); diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index 01987641931a7..3828a6839cd6c 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -161,6 +161,9 @@ "@kbn/field-formats-plugin", "@kbn/dev-proc-runner", "@kbn/cloud-chat-plugin", + "@kbn/discover-plugin", + "@kbn/navigation-plugin", + "@kbn/data-view-editor-plugin", "@kbn/alerts-ui-shared" ] } diff --git a/x-pack/plugins/security_solution_serverless/server/cloud_security/cloud_security_metring.ts b/x-pack/plugins/security_solution_serverless/server/cloud_security/cloud_security_metring.ts new file mode 100644 index 0000000000000..25fb2b3fdefcc --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/server/cloud_security/cloud_security_metring.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getCspmUsageRecord } from './cspm_metring_task'; +import type { MeteringCallbackInput, UsageRecord } from '../types'; + +export const CLOUD_SECURITY_TASK_TYPE = 'Cloud_Security'; + +export const cloudSecurityMetringCallback = async ({ + esClient, + cloudSetup, + logger, + taskId, + lastSuccessfulReport, +}: MeteringCallbackInput): Promise => { + const projectId = cloudSetup?.serverless?.projectId || 'missing project id'; + + if (!cloudSetup?.serverless?.projectId) { + logger.error('no project id found'); + } + + try { + const cloudSecurityUsageRecords: UsageRecord[] = []; + + const cspmUsageRecord = await getCspmUsageRecord({ + esClient, + projectId, + logger, + taskId, + lastSuccessfulReport, + }); + + if (cspmUsageRecord) { + cloudSecurityUsageRecords.push(cspmUsageRecord); + } + + return cloudSecurityUsageRecords; + } catch (err) { + logger.error(`Failed to fetch Cloud Security metering data ${err}`); + return []; + } +}; diff --git a/x-pack/plugins/security_solution_serverless/server/cloud_security/cspm_metring_task.ts b/x-pack/plugins/security_solution_serverless/server/cloud_security/cspm_metring_task.ts new file mode 100644 index 0000000000000..a217046c32ca1 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/server/cloud_security/cspm_metring_task.ts @@ -0,0 +1,110 @@ +/* + * Copyright 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 { + CSPM_POLICY_TEMPLATE, + CSP_LATEST_FINDINGS_DATA_VIEW, +} from '@kbn/cloud-security-posture-plugin/common/constants'; +import { CLOUD_SECURITY_TASK_TYPE } from './cloud_security_metring'; +import { cloudSecurityMetringTaskProperties } from './metering_tasks_configs'; + +import type { CloudSecurityMeteringCallbackInput, UsageRecord } from '../types'; + +const CSPM_CYCLE_SCAN_FREQUENT = '24h'; +const CSPM_BUCKET_SUB_TYPE_NAME = 'CSPM'; + +interface ResourceCountAggregation { + min_timestamp: MinTimestamp; + unique_resources: { + value: number; + }; +} + +interface MinTimestamp { + value: number; + value_as_string: string; +} + +export const getCspmUsageRecord = async ({ + esClient, + projectId, + logger, + taskId, +}: CloudSecurityMeteringCallbackInput): Promise => { + try { + const response = await esClient.search( + getFindingsByResourceAggQuery() + ); + + if (!response.aggregations) { + return; + } + const cspmResourceCount = response.aggregations.unique_resources.value; + + const minTimestamp = response.aggregations + ? new Date(response.aggregations.min_timestamp.value_as_string).toISOString() + : new Date().toISOString(); + + const usageRecords = { + id: `${CLOUD_SECURITY_TASK_TYPE}:${CLOUD_SECURITY_TASK_TYPE}`, + usage_timestamp: minTimestamp, + creation_timestamp: new Date().toISOString(), + usage: { + type: CLOUD_SECURITY_TASK_TYPE, + sub_type: CSPM_BUCKET_SUB_TYPE_NAME, + quantity: cspmResourceCount, + period_seconds: cloudSecurityMetringTaskProperties.periodSeconds, + }, + source: { + id: taskId, + instance_group_id: projectId, + }, + }; + + logger.debug(`Fetched CSPM metring data`); + + return usageRecords; + } catch (err) { + logger.error(`Failed to fetch CSPM metering data ${err}`); + } +}; + +export const getFindingsByResourceAggQuery = () => ({ + index: CSP_LATEST_FINDINGS_DATA_VIEW, + query: { + bool: { + must: [ + { + term: { + 'rule.benchmark.posture_type': CSPM_POLICY_TEMPLATE, + }, + }, + { + range: { + '@timestamp': { + gte: `now-${CSPM_CYCLE_SCAN_FREQUENT}`, // the "look back" period should be the same as the scan interval + }, + }, + }, + ], + }, + }, + size: 0, + aggs: { + unique_resources: { + cardinality: { + field: 'resource.id', + precision_threshold: 3000, // default = 3000 note note that even with a threshold as low as 100, the error remains very low 1-6% even when counting millions of items. https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html#_counts_are_approximate + }, + }, + min_timestamp: { + min: { + field: '@timestamp', + }, + }, + }, +}); diff --git a/x-pack/plugins/security_solution_serverless/server/cloud_security/metering_tasks_configs.ts b/x-pack/plugins/security_solution_serverless/server/cloud_security/metering_tasks_configs.ts new file mode 100644 index 0000000000000..46b4f16ed39e4 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/server/cloud_security/metering_tasks_configs.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { cloudSecurityMetringCallback } from './cloud_security_metring'; +import type { MetringTaskProperties } from '../types'; + +const TASK_INTERVAL = 3600; // 1 hour + +export const cloudSecurityMetringTaskProperties: MetringTaskProperties = { + taskType: 'cloud-security-usage-reporting-task', + taskTitle: 'Cloud Security Metring Periodic Tasks', + meteringCallback: cloudSecurityMetringCallback, + interval: `${TASK_INTERVAL.toString()}s`, + periodSeconds: TASK_INTERVAL, + version: '1', +}; diff --git a/x-pack/plugins/security_solution_serverless/server/common/services/usage_reporting_service.ts b/x-pack/plugins/security_solution_serverless/server/common/services/usage_reporting_service.ts index f6ca7a52b3342..aae47c8de9f24 100644 --- a/x-pack/plugins/security_solution_serverless/server/common/services/usage_reporting_service.ts +++ b/x-pack/plugins/security_solution_serverless/server/common/services/usage_reporting_service.ts @@ -15,7 +15,7 @@ export class UsageReportingService { public async reportUsage(records: UsageRecord[]): Promise { return fetch(USAGE_SERVICE_USAGE_URL, { method: 'post', - body: JSON.stringify([records]), + body: JSON.stringify(records), headers: { 'Content-Type': 'application/json' }, }); } diff --git a/x-pack/plugins/security_solution_serverless/server/plugin.ts b/x-pack/plugins/security_solution_serverless/server/plugin.ts index b4801eff75533..d8fa96d6f5180 100644 --- a/x-pack/plugins/security_solution_serverless/server/plugin.ts +++ b/x-pack/plugins/security_solution_serverless/server/plugin.ts @@ -15,6 +15,8 @@ import type { SecuritySolutionServerlessPluginSetupDeps, SecuritySolutionServerlessPluginStartDeps, } from './types'; +import { SecurityUsageReportingTask } from './task_manager/usage_reporting_task'; +import { cloudSecurityMetringTaskProperties } from './cloud_security/metering_tasks_configs'; export class SecuritySolutionServerlessPlugin implements @@ -26,6 +28,7 @@ export class SecuritySolutionServerlessPlugin > { private config: ServerlessSecurityConfig; + private cspmUsageReportingTask: SecurityUsageReportingTask | undefined; constructor(private readonly initializerContext: PluginInitializerContext) { this.config = this.initializerContext.config.get(); @@ -35,17 +38,33 @@ export class SecuritySolutionServerlessPlugin // securitySolutionEss plugin should always be disabled when securitySolutionServerless is enabled. // This check is an additional layer of security to prevent double registrations when // `plugins.forceEnableAllPlugins` flag is enabled). + const shouldRegister = pluginsSetup.securitySolutionEss == null; if (shouldRegister) { pluginsSetup.securitySolution.setAppFeatures(getProductAppFeatures(this.config.productTypes)); } - pluginsSetup.ml.setFeaturesEnabled({ ad: true, dfa: true, nlp: false }); + + this.cspmUsageReportingTask = new SecurityUsageReportingTask({ + core: _coreSetup, + logFactory: this.initializerContext.logger, + taskManager: pluginsSetup.taskManager, + cloudSetup: pluginsSetup.cloudSetup, + taskType: cloudSecurityMetringTaskProperties.taskType, + taskTitle: cloudSecurityMetringTaskProperties.taskTitle, + version: cloudSecurityMetringTaskProperties.version, + meteringCallback: cloudSecurityMetringTaskProperties.meteringCallback, + }); + return {}; } public start(_coreStart: CoreStart, pluginsSetup: SecuritySolutionServerlessPluginStartDeps) { + this.cspmUsageReportingTask?.start({ + taskManager: pluginsSetup.taskManager, + interval: cloudSecurityMetringTaskProperties.interval, + }); return {}; } diff --git a/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts b/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts index 322ef2f32b0d9..0218ccf41c1ee 100644 --- a/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts +++ b/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts @@ -6,79 +6,71 @@ */ import type { Response } from 'node-fetch'; - -import type { CoreSetup, ElasticsearchClient, Logger, LoggerFactory } from '@kbn/core/server'; -import type { - ConcreteTaskInstance, - TaskManagerSetupContract, - TaskManagerStartContract, -} from '@kbn/task-manager-plugin/server'; +import type { CoreSetup, Logger } from '@kbn/core/server'; +import type { ConcreteTaskInstance } from '@kbn/task-manager-plugin/server'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import { throwUnrecoverableError } from '@kbn/task-manager-plugin/server'; - -import type { UsageRecord } from '../types'; import { usageReportingService } from '../common/services'; +import type { + MeteringCallback, + SecurityUsageReportingTaskStartContract, + SecurityUsageReportingTaskSetupContract, +} from '../types'; const SCOPE = ['serverlessSecurity']; const TIMEOUT = '1m'; export const VERSION = '1.0.0'; -type MeteringCallback = (metringCallbackInput: MeteringCallbackInput) => UsageRecord[]; - -export interface MeteringCallbackInput { - esClient: ElasticsearchClient; - lastSuccessfulReport: Date; -} - -export interface CloudSecurityUsageReportingTaskSetupContract { - taskType: string; - taskTitle: string; - meteringCallback: MeteringCallback; - logFactory: LoggerFactory; - core: CoreSetup; - taskManager: TaskManagerSetupContract; -} - -export interface SecurityMetadataTaskStartContract { - taskType: string; - interval: string; - version: string; - taskManager: TaskManagerStartContract; -} - export class SecurityUsageReportingTask { - private logger: Logger; private wasStarted: boolean = false; + private cloudSetup: CloudSetup; + private taskType: string; + private taskId: string; + private version: string; + private logger: Logger; - constructor(setupContract: CloudSecurityUsageReportingTaskSetupContract) { - const { taskType, taskTitle, logFactory, core, taskManager, meteringCallback } = setupContract; - - this.logger = logFactory.get(this.getTaskId(taskType)); - taskManager.registerTaskDefinitions({ - [taskType]: { - title: taskTitle, - timeout: TIMEOUT, - createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { - return { - run: async () => { - return this.runTask(taskInstance, core, meteringCallback); - }, - // TODO - cancel: async () => {}, - }; + constructor(setupContract: SecurityUsageReportingTaskSetupContract) { + const { + core, + logFactory, + taskManager, + cloudSetup, + taskType, + taskTitle, + version, + meteringCallback, + } = setupContract; + + this.cloudSetup = cloudSetup; + this.taskType = taskType; + this.version = version; + this.taskId = this.getTaskId(taskType, version); + this.logger = logFactory.get(this.taskId); + + try { + taskManager.registerTaskDefinitions({ + [taskType]: { + title: taskTitle, + timeout: TIMEOUT, + createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { + return { + run: async () => { + return this.runTask(taskInstance, core, meteringCallback); + }, + cancel: async () => {}, + }; + }, }, - }, - }); + }); + this.logger.info(`Scheduled task successfully ${taskTitle}`); + } catch (err) { + this.logger.error(`Failed to setup task ${taskType}, ${err} `); + } } - public start = async ({ - taskManager, - taskType, - interval, - version, - }: SecurityMetadataTaskStartContract) => { + public start = async ({ taskManager, interval }: SecurityUsageReportingTaskStartContract) => { if (!taskManager) { - this.logger.error('missing required service during start'); return; } @@ -86,8 +78,8 @@ export class SecurityUsageReportingTask { try { await taskManager.ensureScheduled({ - id: this.getTaskId(taskType), - taskType, + id: this.taskId, + taskType: this.taskType, scope: SCOPE, schedule: { interval, @@ -95,7 +87,7 @@ export class SecurityUsageReportingTask { state: { lastSuccessfulReport: null, }, - params: { version }, + params: { version: this.version }, }); } catch (e) { this.logger.debug(`Error scheduling task, received ${e.message}`); @@ -112,27 +104,47 @@ export class SecurityUsageReportingTask { this.logger.debug('[runTask()] Aborted. Task not started yet'); return; } - // Check that this task is current - if (taskInstance.id !== this.getTaskId(taskInstance.taskType)) { + if (taskInstance.id !== this.taskId) { // old task, die throwUnrecoverableError(new Error('Outdated task version')); } const [{ elasticsearch }] = await core.getStartServices(); - const esClient = elasticsearch.client.asInternalUser; + const lastSuccessfulReport = taskInstance.state.lastSuccessfulReport; - const usageRecords = meteringCallback({ esClient, lastSuccessfulReport }); + const usageRecords = await meteringCallback({ + esClient, + cloudSetup: this.cloudSetup, + logger: this.logger, + taskId: this.taskId, + lastSuccessfulReport, + }); + + this.logger.debug(`received usage records: ${JSON.stringify(usageRecords)}`); let usageReportResponse: Response | undefined; - try { - usageReportResponse = await usageReportingService.reportUsage(usageRecords); - } catch (e) { - this.logger.warn(JSON.stringify(e)); + if (usageRecords.length !== 0) { + try { + usageReportResponse = await usageReportingService.reportUsage(usageRecords); + + if (!usageReportResponse.ok) { + const errorResponse = await usageReportResponse.json(); + this.logger.error(`API error ${usageReportResponse.status}, ${errorResponse}`); + return; + } + + this.logger.info( + `usage records report was sent successfully: ${usageReportResponse.status}, ${usageReportResponse.statusText}` + ); + } catch (err) { + this.logger.error(`Failed to send usage records report ${JSON.stringify(err)} `); + } } + const state = { lastSuccessfulReport: usageReportResponse?.status === 201 ? new Date() : taskInstance.state.lastSuccessfulReport, @@ -140,7 +152,7 @@ export class SecurityUsageReportingTask { return { state }; }; - private getTaskId = (taskType: string): string => { - return `${taskType}:${VERSION}`; + private getTaskId = (taskType: string, version: string): string => { + return `${taskType}:${version}`; }; } diff --git a/x-pack/plugins/security_solution_serverless/server/types.ts b/x-pack/plugins/security_solution_serverless/server/types.ts index e107a32b49335..e3e3ad84b1d5e 100644 --- a/x-pack/plugins/security_solution_serverless/server/types.ts +++ b/x-pack/plugins/security_solution_serverless/server/types.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import type { CoreSetup, ElasticsearchClient, Logger, LoggerFactory } from '@kbn/core/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import type { PluginSetupContract, PluginStartContract } from '@kbn/features-plugin/server'; import type { @@ -12,9 +12,10 @@ import type { PluginStart as SecuritySolutionPluginStart, } from '@kbn/security-solution-plugin/server'; import type { - TaskManagerSetupContract as TaskManagerPluginSetup, - TaskManagerStartContract as TaskManagerPluginStart, + TaskManagerSetupContract, + TaskManagerStartContract, } from '@kbn/task-manager-plugin/server'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { SecuritySolutionEssPluginSetup } from '@kbn/security-solution-ess/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; @@ -30,14 +31,15 @@ export interface SecuritySolutionServerlessPluginSetupDeps { securitySolutionEss: SecuritySolutionEssPluginSetup; features: PluginSetupContract; ml: MlPluginSetup; - taskManager: TaskManagerPluginSetup; + taskManager: TaskManagerSetupContract; + cloudSetup: CloudSetup; } export interface SecuritySolutionServerlessPluginStartDeps { security: SecurityPluginStart; securitySolution: SecuritySolutionPluginStart; features: PluginStartContract; - taskManager: TaskManagerPluginStart; + taskManager: TaskManagerStartContract; } export interface UsageRecord { @@ -60,5 +62,47 @@ export interface UsageMetrics { export interface UsageSource { id: string; instance_group_id: string; - instance_group_type: string; + instance_group_type?: string; // not seems part of step 1 fields https://github.com/elastic/mx-team/blob/main/teams/billing/services/usage_record_schema_v2.md +} + +export interface SecurityUsageReportingTaskSetupContract { + core: CoreSetup; + logFactory: LoggerFactory; + taskManager: TaskManagerSetupContract; + cloudSetup: CloudSetup; + taskType: string; + taskTitle: string; + version: string; + meteringCallback: MeteringCallback; +} + +export interface SecurityUsageReportingTaskStartContract { + taskManager: TaskManagerStartContract; + interval: string; +} + +export type MeteringCallback = ( + metringCallbackInput: MeteringCallbackInput +) => Promise; + +export interface MeteringCallbackInput { + esClient: ElasticsearchClient; + cloudSetup: CloudSetup; + logger: Logger; + taskId: string; + lastSuccessfulReport: Date; +} + +export interface CloudSecurityMeteringCallbackInput + extends Omit { + projectId: string; +} + +export interface MetringTaskProperties { + taskType: string; + taskTitle: string; + meteringCallback: MeteringCallback; + interval: string; + periodSeconds: number; + version: string; } diff --git a/x-pack/plugins/security_solution_serverless/tsconfig.json b/x-pack/plugins/security_solution_serverless/tsconfig.json index 30ecd2e9655b2..cce3249926fee 100644 --- a/x-pack/plugins/security_solution_serverless/tsconfig.json +++ b/x-pack/plugins/security_solution_serverless/tsconfig.json @@ -11,9 +11,7 @@ "server/**/*.ts", "../../../typings/**/*" ], - "exclude": [ - "target/**/*" - ], + "exclude": ["target/**/*"], "kbn_references": [ "@kbn/core", "@kbn/config-schema", @@ -32,6 +30,8 @@ "@kbn/features-plugin", "@kbn/ml-plugin", "@kbn/kibana-utils-plugin", - "@kbn/task-manager-plugin" + "@kbn/task-manager-plugin", + "@kbn/cloud-plugin", + "@kbn/cloud-security-posture-plugin" ] } diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts index 8851a95c6ebc3..0bcde310a224b 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts @@ -16,6 +16,7 @@ import { CaseStatuses, CommentRequestExternalReferenceSOType, CommentRequestAlertType, + ExternalReferenceStorageType, } from '@kbn/cases-plugin/common/api'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { @@ -42,6 +43,7 @@ import { getCaseUserActions, removeServerGeneratedPropertiesFromUserAction, getAllComments, + bulkCreateAttachments, } from '../../../../common/lib/api'; import { createSignalsIndex, @@ -468,6 +470,76 @@ export default ({ getService }: FtrProviderContext): void => { expectedHttpCode: 400, }); }); + + it('400s when attempting to add a persistable state to a case that already has 100', async () => { + const postedCase = await createCase(supertest, postCaseReq); + + const attachments = Array(100).fill({ + type: CommentType.externalReference as const, + owner: 'securitySolutionFixture', + externalReferenceAttachmentTypeId: '.test', + externalReferenceId: 'so-id', + externalReferenceMetadata: {}, + externalReferenceStorage: { + soType: 'external-ref', + type: ExternalReferenceStorageType.savedObject as const, + }, + }); + + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: attachments, + expectedHttpCode: 200, + }); + + await createComment({ + supertest, + caseId: postedCase.id, + params: { + persistableStateAttachmentTypeId: '.test', + persistableStateAttachmentState: {}, + type: CommentType.persistableState as const, + owner: 'securitySolutionFixture', + }, + expectedHttpCode: 400, + }); + }); + + it('400s when attempting to add an external reference to a case that already has 100', async () => { + const postedCase = await createCase(supertest, postCaseReq); + + const attachments = Array(100).fill({ + persistableStateAttachmentTypeId: '.test', + persistableStateAttachmentState: {}, + type: CommentType.persistableState as const, + owner: 'securitySolutionFixture', + }); + + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: attachments, + expectedHttpCode: 200, + }); + + await createComment({ + supertest, + caseId: postedCase.id, + params: { + type: CommentType.externalReference as const, + owner: 'securitySolutionFixture', + externalReferenceAttachmentTypeId: '.test', + externalReferenceId: 'so-id', + externalReferenceMetadata: {}, + externalReferenceStorage: { + soType: 'external-ref', + type: ExternalReferenceStorageType.savedObject as const, + }, + }, + expectedHttpCode: 400, + }); + }); }); describe('alerts', () => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts index a0b626482f473..e5eaedb6dae8c 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts @@ -15,6 +15,7 @@ import { CaseStatuses, CommentRequestExternalReferenceSOType, CommentType, + ExternalReferenceStorageType, } from '@kbn/cases-plugin/common/api'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { @@ -42,6 +43,7 @@ import { createAndUploadFile, deleteAllFiles, getAllComments, + createComment, } from '../../../../common/lib/api'; import { createSignalsIndex, @@ -619,102 +621,174 @@ export default ({ getService }: FtrProviderContext): void => { await createCaseAndBulkCreateAttachments({ supertest, expectedHttpCode: 400 }); }); - it('400s when attempting to add more than 1K alerts to a case', async () => { - const alerts = [...Array(1001).keys()].map((num) => `test-${num}`); - const postedCase = await createCase(supertest, postCaseReq); - await bulkCreateAttachments({ - supertest, - caseId: postedCase.id, - params: [ - { - ...postCommentAlertReq, - alertId: alerts, - index: alerts, - }, - ], - expectedHttpCode: 400, + describe('validation', () => { + it('400s when attempting to add more than 1K alerts to a case', async () => { + const alerts = [...Array(1001).keys()].map((num) => `test-${num}`); + const postedCase = await createCase(supertest, postCaseReq); + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: [ + { + ...postCommentAlertReq, + alertId: alerts, + index: alerts, + }, + ], + expectedHttpCode: 400, + }); }); - }); - it('400s when attempting to add more than 1K alerts to a case in the same request', async () => { - const alerts = [...Array(1001).keys()].map((num) => `test-${num}`); - const postedCase = await createCase(supertest, postCaseReq); - await bulkCreateAttachments({ - supertest, - caseId: postedCase.id, - params: [ - { - ...postCommentAlertReq, - alertId: alerts.slice(0, 500), - index: alerts.slice(0, 500), - }, - { - ...postCommentAlertReq, - alertId: alerts.slice(500, alerts.length), - index: alerts.slice(500, alerts.length), - }, - postCommentAlertReq, - ], - expectedHttpCode: 400, + it('400s when attempting to add more than 1K alerts to a case in the same request', async () => { + const alerts = [...Array(1001).keys()].map((num) => `test-${num}`); + const postedCase = await createCase(supertest, postCaseReq); + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: [ + { + ...postCommentAlertReq, + alertId: alerts.slice(0, 500), + index: alerts.slice(0, 500), + }, + { + ...postCommentAlertReq, + alertId: alerts.slice(500, alerts.length), + index: alerts.slice(500, alerts.length), + }, + postCommentAlertReq, + ], + expectedHttpCode: 400, + }); }); - }); - it('400s when attempting to add an alert to a case that already has 1K alerts', async () => { - const alerts = [...Array(1000).keys()].map((num) => `test-${num}`); - const postedCase = await createCase(supertest, postCaseReq); - await bulkCreateAttachments({ - supertest, - caseId: postedCase.id, - params: [ - { - ...postCommentAlertReq, - alertId: alerts, - index: alerts, - }, - ], + it('400s when attempting to add an alert to a case that already has 1K alerts', async () => { + const alerts = [...Array(1000).keys()].map((num) => `test-${num}`); + const postedCase = await createCase(supertest, postCaseReq); + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: [ + { + ...postCommentAlertReq, + alertId: alerts, + index: alerts, + }, + ], + }); + + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: [ + { + ...postCommentAlertReq, + alertId: 'test-id', + index: 'test-index', + }, + ], + expectedHttpCode: 400, + }); }); - await bulkCreateAttachments({ - supertest, - caseId: postedCase.id, - params: [ - { - ...postCommentAlertReq, - alertId: 'test-id', - index: 'test-index', - }, - ], - expectedHttpCode: 400, + it('400s when the case already has alerts and the sum of existing and new alerts exceed 1k', async () => { + const alerts = [...Array(1200).keys()].map((num) => `test-${num}`); + const postedCase = await createCase(supertest, postCaseReq); + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: [ + { + ...postCommentAlertReq, + alertId: alerts.slice(0, 500), + index: alerts.slice(0, 500), + }, + ], + }); + + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: [ + { + ...postCommentAlertReq, + alertId: alerts.slice(500), + index: alerts.slice(500), + }, + postCommentAlertReq, + ], + expectedHttpCode: 400, + }); }); - }); - it('400s when the case already has alerts and the sum of existing and new alerts exceed 1k', async () => { - const alerts = [...Array(1200).keys()].map((num) => `test-${num}`); - const postedCase = await createCase(supertest, postCaseReq); - await bulkCreateAttachments({ - supertest, - caseId: postedCase.id, - params: [ - { - ...postCommentAlertReq, - alertId: alerts.slice(0, 500), - index: alerts.slice(0, 500), + it('400s when attempting to bulk create persistable state attachments reaching the 100 limit', async () => { + const postedCase = await createCase(supertest, postCaseReq); + + await createComment({ + supertest, + caseId: postedCase.id, + params: { + type: CommentType.externalReference as const, + owner: 'securitySolutionFixture', + externalReferenceAttachmentTypeId: '.test', + externalReferenceId: 'so-id', + externalReferenceMetadata: {}, + externalReferenceStorage: { + soType: 'external-ref', + type: ExternalReferenceStorageType.savedObject as const, + }, }, - ], + expectedHttpCode: 200, + }); + + const persistableStateAttachments = Array(100).fill({ + persistableStateAttachmentTypeId: '.test', + persistableStateAttachmentState: {}, + type: CommentType.persistableState as const, + owner: 'securitySolutionFixture', + }); + + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: persistableStateAttachments, + expectedHttpCode: 400, + }); }); - await bulkCreateAttachments({ - supertest, - caseId: postedCase.id, - params: [ - { - ...postCommentAlertReq, - alertId: alerts.slice(500), - index: alerts.slice(500), + it('400s when attempting to bulk create >100 external reference attachments reaching the 100 limit', async () => { + const postedCase = await createCase(supertest, postCaseReq); + + await createComment({ + supertest, + caseId: postedCase.id, + params: { + persistableStateAttachmentTypeId: '.test', + persistableStateAttachmentState: {}, + type: CommentType.persistableState as const, + owner: 'securitySolutionFixture', }, - postCommentAlertReq, - ], - expectedHttpCode: 400, + expectedHttpCode: 200, + }); + + const externalRequestAttachments = Array(100).fill({ + type: CommentType.externalReference as const, + owner: 'securitySolutionFixture', + externalReferenceAttachmentTypeId: '.test', + externalReferenceId: 'so-id', + externalReferenceMetadata: {}, + externalReferenceStorage: { + soType: 'external-ref', + type: ExternalReferenceStorageType.savedObject as const, + }, + }); + + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: externalRequestAttachments, + expectedHttpCode: 400, + }); }); }); }); diff --git a/yarn.lock b/yarn.lock index 3aafb5c0e7810..ec7ff3a02eeba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15380,11 +15380,6 @@ eslint-plugin-node@^11.1.0: resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-prefer-object-spread@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-object-spread/-/eslint-plugin-prefer-object-spread-1.2.1.tgz#27fb91853690cceb3ae6101d9c8aecc6a67a402c" - integrity sha1-J/uRhTaQzOs65hAdnIrsxqZ6QCw= - eslint-plugin-prettier@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz#8b99d1e4b8b24a762472b4567992023619cb98e0"