diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index 7a563f067a0f9e..4387911b411827 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -265,6 +265,7 @@ enabled: - x-pack/test/security_api_integration/session_idle.config.ts - x-pack/test/security_api_integration/session_invalidate.config.ts - x-pack/test/security_api_integration/session_lifespan.config.ts + - x-pack/test/security_api_integration/session_concurrent_limit.config.ts - x-pack/test/security_api_integration/token.config.ts - x-pack/test/security_api_integration/user_profiles.config.ts - x-pack/test/security_functional/login_selector.config.ts diff --git a/.buildkite/package-lock.json b/.buildkite/package-lock.json index cc303035b972ec..d28509d0de482a 100644 --- a/.buildkite/package-lock.json +++ b/.buildkite/package-lock.json @@ -16,12 +16,12 @@ "tslib": "*" }, "devDependencies": { - "@types/chai": "^4.2.10", + "@types/chai": "^4.3.3", "@types/js-yaml": "^4.0.5", "@types/minimatch": "^3.0.5", "@types/mocha": "^10.0.1", "@types/node": "^15.12.2", - "chai": "^4.2.0", + "chai": "^4.3.6", "mocha": "^10.2.0", "nock": "^12.0.2", "ts-node": "^10.7.0", @@ -242,9 +242,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", - "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "node_modules/@types/js-yaml": { @@ -1847,9 +1847,9 @@ "dev": true }, "@types/chai": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", - "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "@types/js-yaml": { diff --git a/.buildkite/package.json b/.buildkite/package.json index 620345b081410a..2dbcbc3c0082fe 100644 --- a/.buildkite/package.json +++ b/.buildkite/package.json @@ -15,12 +15,12 @@ "tslib": "*" }, "devDependencies": { - "@types/chai": "^4.2.10", + "@types/chai": "^4.3.3", "@types/js-yaml": "^4.0.5", "@types/minimatch": "^3.0.5", "@types/mocha": "^10.0.1", "@types/node": "^15.12.2", - "chai": "^4.2.0", + "chai": "^4.3.6", "mocha": "^10.2.0", "nock": "^12.0.2", "ts-node": "^10.7.0", diff --git a/.buildkite/scripts/steps/storybooks/build_and_upload.ts b/.buildkite/scripts/steps/storybooks/build_and_upload.ts index d15e15800821a5..f56e9bdab8529f 100644 --- a/.buildkite/scripts/steps/storybooks/build_and_upload.ts +++ b/.buildkite/scripts/steps/storybooks/build_and_upload.ts @@ -14,6 +14,7 @@ import path from 'path'; const STORYBOOKS = [ 'apm', 'canvas', + 'cases', 'ci_composite', 'cloud_chat', 'coloring', diff --git a/.ci/Dockerfile b/.ci/Dockerfile index 88966aa5062ac4..4f5236c733bc36 100644 --- a/.ci/Dockerfile +++ b/.ci/Dockerfile @@ -1,7 +1,7 @@ # NOTE: This Dockerfile is ONLY used to run certain tasks in CI. It is not used to run Kibana or as a distributable. # If you're looking for the Kibana Docker image distributable, please see: src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts -ARG NODE_VERSION=16.18.1 +ARG NODE_VERSION=18.13.0 FROM node:${NODE_VERSION} AS base diff --git a/.node-version b/.node-version index 5397c87fabfd39..d939939b25962c 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -16.18.1 +18.13.0 diff --git a/.nvmrc b/.nvmrc index 5397c87fabfd39..d939939b25962c 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.18.1 +18.13.0 diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 0a7f9596abdd8d..2e0916692591aa 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -22,13 +22,13 @@ load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "yarn_install # Setup the Node.js toolchain for the architectures we want to support node_repositories( node_repositories = { - "16.18.1-darwin_amd64": ("node-v16.18.1-darwin-x64.tar.gz", "node-v16.18.1-darwin-x64", "c190e106d4ac6177d1db3a5a739d39dd68bd276ba17f3d3c84039a93717e081e"), - "16.18.1-darwin_arm64": ("node-v16.18.1-darwin-arm64.tar.gz", "node-v16.18.1-darwin-arm64", "71720bb0a80cf158d8fdf492def08048befd953ad45e2458b1d095e32c612ba7"), - "16.18.1-linux_arm64": ("node-v16.18.1-linux-arm64.tar.xz", "node-v16.18.1-linux-arm64", "98d81a2d08f88646541d282b7ccc32429f8706ddcb30943fc3779ef9674ebb93"), - "16.18.1-linux_amd64": ("node-v16.18.1-linux-x64.tar.xz", "node-v16.18.1-linux-x64", "de2c694e7081c37022817d27a65b02f69ecf4c49699d65585e8e24431b7bc920"), - "16.18.1-windows_amd64": ("node-v16.18.1-win-x64.zip", "node-v16.18.1-win-x64", "db6a81de8e8ca3444495f1bcf04a883c076b4325d0fbaa032a190f88b38b30c5"), + "18.13.0-darwin_amd64": ("node-v18.13.0-darwin-x64.tar.gz", "node-v18.13.0-darwin-x64", "8b57c4da4ff6cca19d5ef7953f8816e3406d1508a2e4ee7f997984b3b1d11b77"), + "18.13.0-darwin_arm64": ("node-v18.13.0-darwin-arm64.tar.gz", "node-v18.13.0-darwin-arm64", "418d535e64dbcbd628715180c2de4ffcecb8a84b81f233c60e6ab9f0d795c249"), + "18.13.0-linux_arm64": ("node-v18.13.0-linux-arm64.tar.xz", "node-v18.13.0-linux-arm64", "5b338667822341d1ea3b18d5b37d442a655829b9eafdc5f9008f00b8451ac148"), + "18.13.0-linux_amd64": ("node-v18.13.0-linux-x64.tar.xz", "node-v18.13.0-linux-x64", "7f5d6922a91986ef059ba8a4396aa435440adacfe6fc6fab60a857c8f2cf5e7a"), + "18.13.0-windows_amd64": ("node-v18.13.0-win-x64.zip", "node-v18.13.0-win-x64", "29c99ad1167ddbd72f2b15e91b560e36ac785b1873ba6791ab50d9d62f1957e2"), }, - node_version = "16.18.1", + node_version = "18.13.0", node_urls = [ "https://nodejs.org/dist/v{version}/{filename}", ], diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 22458142df3e25..a1b7ce979d1562 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 7fb6230346bc9b..31945daf7dfb1a 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 729ef85c549c1c..c90bf9ae331683 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 83f0ad7016c380..7bdaef809e7b6e 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -1054,6 +1054,23 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "alerting", + "id": "def-server.AlertingApiRequestHandlerContext.getRulesSettingsClient", + "type": "Function", + "tags": [], + "label": "getRulesSettingsClient", + "description": [], + "signature": [ + "() => ", + "RulesSettingsClient" + ], + "path": "x-pack/plugins/alerting/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "alerting", "id": "def-server.AlertingApiRequestHandlerContext.listTypes", @@ -6549,6 +6566,159 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettings", + "type": "Interface", + "tags": [], + "label": "RulesSettings", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettings.flapping", + "type": "CompoundType", + "tags": [], + "label": "flapping", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsFlappingProperties", + "text": "RulesSettingsFlappingProperties" + }, + " & ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsModificationMetadata", + "text": "RulesSettingsModificationMetadata" + } + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties", + "type": "Interface", + "tags": [], + "label": "RulesSettingsFlappingProperties", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties.lookBackWindow", + "type": "number", + "tags": [], + "label": "lookBackWindow", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlappingProperties.statusChangeThreshold", + "type": "number", + "tags": [], + "label": "statusChangeThreshold", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata", + "type": "Interface", + "tags": [], + "label": "RulesSettingsModificationMetadata", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.createdBy", + "type": "CompoundType", + "tags": [], + "label": "createdBy", + "description": [], + "signature": [ + "string | null" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.updatedBy", + "type": "CompoundType", + "tags": [], + "label": "updatedBy", + "description": [], + "signature": [ + "string | null" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.createdAt", + "type": "string", + "tags": [], + "label": "createdAt", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsModificationMetadata.updatedAt", + "type": "string", + "tags": [], + "label": "updatedAt", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleStateNavigation", @@ -7027,6 +7197,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "type": "string", + "tags": [], + "label": "ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "description": [], + "signature": [ + "\"allFlappingSettings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.BASE_ALERTING_API_PATH", @@ -7057,6 +7242,36 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_LOOK_BACK_WINDOW", + "type": "number", + "tags": [], + "label": "DEFAULT_LOOK_BACK_WINDOW", + "description": [], + "signature": [ + "20" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_STATUS_CHANGE_THRESHOLD", + "type": "number", + "tags": [], + "label": "DEFAULT_STATUS_CHANGE_THRESHOLD", + "description": [], + "signature": [ + "4" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.DefaultActionGroupId", @@ -7176,6 +7391,66 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.MAX_LOOK_BACK_WINDOW", + "type": "number", + "tags": [], + "label": "MAX_LOOK_BACK_WINDOW", + "description": [], + "signature": [ + "20" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.MAX_STATUS_CHANGE_THRESHOLD", + "type": "number", + "tags": [], + "label": "MAX_STATUS_CHANGE_THRESHOLD", + "description": [], + "signature": [ + "20" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.MIN_LOOK_BACK_WINDOW", + "type": "number", + "tags": [], + "label": "MIN_LOOK_BACK_WINDOW", + "description": [], + "signature": [ + "2" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.MIN_STATUS_CHANGE_THRESHOLD", + "type": "number", + "tags": [], + "label": "MIN_STATUS_CHANGE_THRESHOLD", + "description": [], + "signature": [ + "2" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.MONITORING_HISTORY_LIMIT", @@ -7206,6 +7481,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.READ_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "type": "string", + "tags": [], + "label": "READ_FLAPPING_SETTINGS_SUB_FEATURE_ID", + "description": [], + "signature": [ + "\"readFlappingSettings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RecoveredActionGroupId", @@ -7406,6 +7696,51 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RULES_SETTINGS_FEATURE_ID", + "type": "string", + "tags": [], + "label": "RULES_SETTINGS_FEATURE_ID", + "description": [], + "signature": [ + "\"rulesSettings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RULES_SETTINGS_SAVED_OBJECT_ID", + "type": "string", + "tags": [], + "label": "RULES_SETTINGS_SAVED_OBJECT_ID", + "description": [], + "signature": [ + "\"rules-settings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.RULES_SETTINGS_SAVED_OBJECT_TYPE", + "type": "string", + "tags": [], + "label": "RULES_SETTINGS_SAVED_OBJECT_TYPE", + "description": [], + "signature": [ + "\"rules-settings\"" + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleSnooze", @@ -7421,6 +7756,35 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.RulesSettingsFlapping", + "type": "Type", + "tags": [], + "label": "RulesSettingsFlapping", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsFlappingProperties", + "text": "RulesSettingsFlappingProperties" + }, + " & ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RulesSettingsModificationMetadata", + "text": "RulesSettingsModificationMetadata" + } + ], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.RuleStatusValues", @@ -7630,6 +7994,89 @@ } ], "objects": [ + { + "parentPluginId": "alerting", + "id": "def-common.API_PRIVILEGES", + "type": "Object", + "tags": [], + "label": "API_PRIVILEGES", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.API_PRIVILEGES.READ_FLAPPING_SETTINGS", + "type": "string", + "tags": [], + "label": "READ_FLAPPING_SETTINGS", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.API_PRIVILEGES.WRITE_FLAPPING_SETTINGS", + "type": "string", + "tags": [], + "label": "WRITE_FLAPPING_SETTINGS", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS", + "type": "Object", + "tags": [], + "label": "DEFAULT_FLAPPING_SETTINGS", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS.lookBackWindow", + "type": "number", + "tags": [], + "label": "lookBackWindow", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold", + "type": "number", + "tags": [], + "label": "statusChangeThreshold", + "description": [], + "path": "x-pack/plugins/alerting/common/rules_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.DisabledActionTypeIdsForActionGroup", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index f16e15e18e7dd3..5438d2f13f34a1 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 434 | 0 | 425 | 37 | +| 465 | 0 | 456 | 38 | ## Client diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index f54c2089411197..c56b5f9550718c 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -810,7 +810,7 @@ "label": "APIEndpoint", "description": [], "signature": [ - "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/samples\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/error/{errorId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/nodes\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"GET /internal/apm/services\" | \"POST /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/services/{serviceName}/alerts_count\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/service-group/counts\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"POST /internal/apm/traces/aggregated_critical_path\" | \"GET /internal/apm/traces/{traceId}/transactions/{transactionId}\" | \"GET /internal/apm/traces/{traceId}/spans/{spanId}\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/rule_types/transaction_error_rate/chart_preview\" | \"GET /internal/apm/rule_types/transaction_duration/chart_preview\" | \"GET /internal/apm/rule_types/error_count/chart_preview\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"POST /internal/apm/sourcemaps/migrate_fleet_artifacts\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/operations/spans\" | \"GET /internal/apm/correlations/field_candidates/transactions\" | \"GET /internal/apm/correlations/field_value_stats/transactions\" | \"POST /internal/apm/correlations/field_value_pairs/transactions\" | \"POST /internal/apm/correlations/significant_correlations/transactions\" | \"POST /internal/apm/correlations/p_values/transactions\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"GET /internal/apm/storage_explorer/is_cross_cluster_search\" | \"GET /internal/apm/storage_explorer/get_services\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\" | \"GET /internal/apm/settings/labs\" | \"GET /internal/apm/get_agents_per_service\" | \"GET /internal/apm/services/{serviceName}/agent_instances\" | \"GET /internal/apm/services/{serviceName}/mobile/filters\" | \"GET /internal/apm/mobile-services/{serviceName}/stats\"" + "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/samples\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/error/{errorId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/nodes\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"GET /internal/apm/services\" | \"POST /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/services/{serviceName}/alerts_count\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/service-group/counts\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"POST /internal/apm/traces/aggregated_critical_path\" | \"GET /internal/apm/traces/{traceId}/transactions/{transactionId}\" | \"GET /internal/apm/traces/{traceId}/spans/{spanId}\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/rule_types/transaction_error_rate/chart_preview\" | \"GET /internal/apm/rule_types/transaction_duration/chart_preview\" | \"GET /internal/apm/rule_types/error_count/chart_preview\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"POST /internal/apm/sourcemaps/migrate_fleet_artifacts\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/operations/spans\" | \"GET /internal/apm/correlations/field_candidates/transactions\" | \"GET /internal/apm/correlations/field_value_stats/transactions\" | \"POST /internal/apm/correlations/field_value_pairs/transactions\" | \"POST /internal/apm/correlations/significant_correlations/transactions\" | \"POST /internal/apm/correlations/p_values/transactions\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"GET /internal/apm/storage_explorer/is_cross_cluster_search\" | \"GET /internal/apm/storage_explorer/get_services\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\" | \"GET /internal/apm/settings/labs\" | \"GET /internal/apm/get_agents_per_service\" | \"GET /internal/apm/services/{serviceName}/agent_instances\" | \"GET /internal/apm/services/{serviceName}/mobile/filters\" | \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions\" | \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests\" | \"GET /internal/apm/mobile-services/{serviceName}/stats\"" ], "path": "x-pack/plugins/apm/server/routes/apm_routes/get_global_apm_server_route_repository.ts", "deprecated": false, @@ -934,6 +934,142 @@ "MobileStats", ", ", "APMRouteCreateOptions", + ">; \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests\": ", + { + "pluginId": "@kbn/server-route-repository", + "scope": "public", + "docId": "kibKbnServerRouteRepositoryPluginApi", + "section": "def-public.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">]>; }>, ", + "PartialC", + "<{ offset: ", + "StringC", + "; }>, ", + "PartialC", + "<{ transactionType: ", + "StringC", + "; transactionName: ", + "StringC", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", ", + "HttpRequestsTimeseries", + ", ", + "APMRouteCreateOptions", + ">; \"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions\": ", + { + "pluginId": "@kbn/server-route-repository", + "scope": "public", + "docId": "kibKbnServerRouteRepositoryPluginApi", + "section": "def-public.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">]>; }>, ", + "PartialC", + "<{ offset: ", + "StringC", + "; }>, ", + "PartialC", + "<{ transactionType: ", + "StringC", + "; transactionName: ", + "StringC", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", ", + "SessionsTimeseries", + ", ", + "APMRouteCreateOptions", ">; \"GET /internal/apm/services/{serviceName}/mobile/filters\": ", { "pluginId": "@kbn/server-route-repository", diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index bebb7bffbd2175..1e003340160077 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; @@ -21,7 +21,7 @@ Contact [APM UI](https://github.com/orgs/elastic/teams/apm-ui) for questions reg | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 42 | 0 | 42 | 59 | +| 42 | 0 | 42 | 61 | ## Client diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 2c25218d3f988c..79031fcac7ebf0 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 1f20888214c7e0..2091075c1a9ae6 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index fbafdb9e946961..7d38c8891f7670 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 6e5650586e1a50..7221d2fe903f8a 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 6eafd5de4de515..c8a1bb56065a3e 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 15a5d3360c9b5e..5cb39015197c69 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 195d0a6f168577..90d9d098c4769c 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_data_migration.devdocs.json b/api_docs/cloud_data_migration.devdocs.json index be8d01e527096f..46a118a592a92b 100644 --- a/api_docs/cloud_data_migration.devdocs.json +++ b/api_docs/cloud_data_migration.devdocs.json @@ -71,25 +71,46 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "cloudDataMigration", + "id": "def-public.CloudDataMigrationPluginStart", + "type": "Interface", + "tags": [], + "label": "CloudDataMigrationPluginStart", + "description": [], + "path": "x-pack/plugins/cloud_integrations/cloud_data_migration/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "cloudDataMigration", + "id": "def-public.CloudDataMigrationPluginStart.cloud", + "type": "Object", + "tags": [], + "label": "cloud", + "description": [], + "signature": [ + { + "pluginId": "cloud", + "scope": "public", + "docId": "kibCloudPluginApi", + "section": "def-public.CloudStart", + "text": "CloudStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_data_migration/public/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false } ], "enums": [], "misc": [], - "objects": [], - "start": { - "parentPluginId": "cloudDataMigration", - "id": "def-public.CloudDataMigrationPluginStart", - "type": "Interface", - "tags": [], - "label": "CloudDataMigrationPluginStart", - "description": [], - "path": "x-pack/plugins/cloud_integrations/cloud_data_migration/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "lifecycle": "start", - "initialIsOpen": true - } + "objects": [] }, "server": { "classes": [], diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 732e97890fac4a..06851fa4d4f26e 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; @@ -21,13 +21,10 @@ Contact [Platform Onboarding](https://github.com/orgs/elastic/teams/platform-onb | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 7 | 1 | 7 | 1 | +| 8 | 1 | 8 | 1 | ## Client -### Start - - ### Interfaces diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index 17f45d00ca8f9f..3caf7e892c17db 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 7b0672a8164051..b4d5c9985577cf 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 758ac128ce921d..7ea6accf144ce6 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index c6d3bc5063a2c6..5b9341c0bb1c2e 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index c353896d4134a5..e743d05c9e508d 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json index ea00a8c879bd2a..c03d559ea74dd0 100644 --- a/api_docs/core.devdocs.json +++ b/api_docs/core.devdocs.json @@ -2441,6 +2441,22 @@ "path": "packages/core/chrome/core-chrome-browser/src/help_extension.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-public.ChromeHelpExtensionMenuCustomLink.external", + "type": "CompoundType", + "tags": [], + "label": "external", + "description": [ + "\nOpens link in new tab" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/core/chrome/core-chrome-browser/src/help_extension.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/core.mdx b/api_docs/core.mdx index 803dc9268b0ea1..131673b3ea265a 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2823 | 17 | 1019 | 0 | +| 2824 | 17 | 1019 | 0 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 5fe93a968ee4db..786f7d999daf9c 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index a6b917d452f1f4..8be7ee29035cd8 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 0cae3443af3003..ba8a99d190ea1a 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index b78ddbb0bd64b0..9e5eafd9735429 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index f6e7c535342ada..dcff8c8f1d7b1a 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 291be4fd74cce8..f0b87249c1ad99 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 837fe016b3e409..a98687effa085f 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 8583ad0e7b8c2a..4f37bb3608f121 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 927a76ee4f24f9..bd2904fd625ebc 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 1b34c2f8374a56..c7fbb77db91f84 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index b2d2f7049457c3..ca0c5c86d0308e 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 1bdfe7e8ee894c..3d376728a8342d 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 7504461ae5cd48..f07c2381e15d59 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index b4da21755cc64d..f41198da286db6 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 52161703cf8e72..eff8274043dede 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 83fca54d43528d..2d2525811bda00 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index b56b67c21d9d7c..b95768b92fdc6d 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 3d0477f17a5b1f..f1b5afab243dd1 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index abedc7602291f6..86a19aadcd2a85 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index a46de465e51298..22e8a25f5ad628 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index dfbf84fc295ab3..5440713ff4e8f0 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index bd3b64f99a5b69..ba44b3bb65477d 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 607bcc39aa041f..686921c335db97 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index c296d038c1d621..2fefd1cdecd240 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 4f66131b3c160c..f538215cd00c98 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 6bd67af894931c..0375b2ae8c575e 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 631e95c3a04f91..0ef4c6e2417028 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 0f8cc1d4344488..b6d8573862df6c 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index bfb9669016023f..cc9b04694c13ce 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 456e3ae7436aff..02022f798586a9 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 2c4c085ee09ebf..67329af2adccd3 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 7019231e838dc4..464165ef1ca15a 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 2af4db495dc7d8..59974d46869010 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index f6f3d8eb7f224b..d9bad00c4d5d43 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index be7694b34475a3..9a2d2dcc0123d1 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 80c28dabbb7f14..fea88ab3ecb582 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 9acc9b2129a101..eef598ed81c114 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 5dac98a18cffaf..ee158c5a8f563d 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.devdocs.json b/api_docs/features.devdocs.json index 6831369f3b147e..01692bc13b431b 100644 --- a/api_docs/features.devdocs.json +++ b/api_docs/features.devdocs.json @@ -56,7 +56,7 @@ "label": "config", "description": [], "signature": [ - "Readonly<{ id: string; name: string; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", + "Readonly<{ id: string; name: string; description?: string | undefined; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", { "pluginId": "features", "scope": "common", @@ -64,7 +64,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" ], "path": "x-pack/plugins/features/common/kibana_feature.ts", "deprecated": false, @@ -96,6 +96,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-public.KibanaFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-public.KibanaFeature.order", @@ -556,6 +570,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-public.KibanaFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-public.KibanaFeatureConfig.category", @@ -882,6 +912,22 @@ "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "features", + "id": "def-public.SubFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the sub-feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/sub_feature.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -1263,7 +1309,7 @@ "label": "config", "description": [], "signature": [ - "Readonly<{ id: string; name: string; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", + "Readonly<{ id: string; name: string; description?: string | undefined; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", { "pluginId": "features", "scope": "common", @@ -1271,7 +1317,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" ], "path": "x-pack/plugins/features/common/kibana_feature.ts", "deprecated": false, @@ -1303,6 +1349,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-server.KibanaFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-server.KibanaFeature.order", @@ -1942,6 +2002,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-server.KibanaFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-server.KibanaFeatureConfig.category", @@ -2998,7 +3074,7 @@ "label": "config", "description": [], "signature": [ - "Readonly<{ id: string; name: string; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", + "Readonly<{ id: string; name: string; description?: string | undefined; category: Readonly<{ id: string; label: string; ariaLabel?: string | undefined; order?: number | undefined; euiIconType?: string | undefined; }>; order?: number | undefined; excludeFromBasePrivileges?: boolean | undefined; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; app: readonly string[]; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: readonly string[] | undefined; cases?: readonly string[] | undefined; privileges: Readonly<{ all: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; read: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }> | null; subFeatures?: readonly Readonly<{ name: string; requireAllSpaces?: boolean | undefined; privilegesTooltip?: string | undefined; privilegeGroups: readonly Readonly<{ groupType: ", { "pluginId": "features", "scope": "common", @@ -3006,7 +3082,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>[] | undefined; privilegesTooltip?: string | undefined; reserved?: Readonly<{ description: string; privileges: readonly Readonly<{ id: string; privilege: Readonly<{ excludeFromBasePrivileges?: boolean | undefined; requireAllSpaces?: boolean | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; api?: readonly string[] | undefined; app?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; ui: readonly string[]; }>; }>[]; }> | undefined; }>" ], "path": "x-pack/plugins/features/common/kibana_feature.ts", "deprecated": false, @@ -3038,6 +3114,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-common.KibanaFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-common.KibanaFeature.order", @@ -3256,7 +3346,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }>" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }>" ], "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, @@ -3310,6 +3400,17 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-common.SubFeature.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "x-pack/plugins/features/common/sub_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-common.SubFeature.toRaw", @@ -3326,7 +3427,7 @@ "section": "def-common.SubFeaturePrivilegeGroupType", "text": "SubFeaturePrivilegeGroupType" }, - "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; }" + "; privileges: readonly Readonly<{ id: string; name: string; includeIn: \"none\" | \"all\" | \"read\"; minimumLicense?: \"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\" | undefined; disabled?: boolean | undefined; management?: Readonly<{ [x: string]: readonly string[]; }> | undefined; catalogue?: readonly string[] | undefined; alerting?: Readonly<{ rule?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; alert?: Readonly<{ all?: readonly string[] | undefined; read?: readonly string[] | undefined; }> | undefined; }> | undefined; cases?: Readonly<{ all?: readonly string[] | undefined; push?: readonly string[] | undefined; create?: readonly string[] | undefined; read?: readonly string[] | undefined; update?: readonly string[] | undefined; delete?: readonly string[] | undefined; }> | undefined; ui: readonly string[]; app?: readonly string[] | undefined; requireAllSpaces?: boolean | undefined; api?: readonly string[] | undefined; savedObject: Readonly<{ all: readonly string[]; read: readonly string[]; }>; }>[]; }>[]; description?: string | undefined; }" ], "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, @@ -3799,6 +3900,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "features", + "id": "def-common.KibanaFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/kibana_feature.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "features", "id": "def-common.KibanaFeatureConfig.category", @@ -4125,6 +4242,22 @@ "path": "x-pack/plugins/features/common/sub_feature.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "features", + "id": "def-common.SubFeatureConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [ + "\nAn optional description that will appear as subtext underneath the sub-feature name" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/features/common/sub_feature.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 876b9bab2f44ab..1dee1737a041ab 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 227 | 0 | 96 | 2 | +| 236 | 0 | 100 | 2 | ## Client diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 2000819ea5b3aa..9f8b30c0e19b90 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 1c3c35bce1ba39..b17f7bf11ffad8 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 5637f36d5909f9..f215b09505026d 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index ce45e38fe64bc1..31555b4455c6bf 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 105e8c2b0ca803..dae0558193bc00 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 7e79cdf16b3394..beef1364ad893e 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index bb2e793f45082e..6ce4b28be17813 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 05f87cb1774b96..120d967c6a8800 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index b7ed2ee6adf76b..b22c237086fa44 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 23b772f1341cc0..c337bae367f5dc 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 5f309bb4c825fc..93c6e92b4a4737 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index ef62a9a769ccad..c1603013c869ea 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 73b6d21e2c2dd2..4a1fcb60a3935a 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 432aecf3300072..6944fc39abe17d 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 3fe279e278d31c..5b95b95d48ea71 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index bc2ca9c0a5a6f5..340e05a7cbf702 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 45525222854989..b7b19c6366b5f9 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index 4f646d77700f5b..c02f467bd6b960 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 25305aedeaaf03..20639d149569dc 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 048a32c3720cbc..b02e9213d3d32d 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 144156b8321709..37cfd7cacc304b 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 3bed244b25cae1..5492fab3d131ee 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 7c7bcb54e86b09..57de118630486a 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index ae268c787a2829..cc7c9ddbc79c10 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index b2b682b6de3bed..a158f46aa6c6a1 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 5513cd368dbca0..1b83cbb8840355 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 82993d5123f3d8..bb935bc94bb5ac 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 896956338384be..6519e9feea038f 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index ada37c0cdf7d37..259d75bf8f001a 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index f833c186ddeab3..1db949dd3b6c28 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.devdocs.json b/api_docs/kbn_cases_components.devdocs.json index 098fcecdffa0df..0d0cf52bf71ea0 100644 --- a/api_docs/kbn_cases_components.devdocs.json +++ b/api_docs/kbn_cases_components.devdocs.json @@ -67,9 +67,240 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.Tooltip", + "type": "Function", + "tags": [], + "label": "Tooltip", + "description": [], + "signature": [ + "React.NamedExoticComponent<", + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseTooltipProps", + "text": "CaseTooltipProps" + }, + "> & { readonly type: React.NamedExoticComponent<", + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseTooltipProps", + "text": "CaseTooltipProps" + }, + ">; }" + ], + "path": "packages/kbn-cases-components/src/tooltip/tooltip.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.Tooltip.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps", + "type": "Interface", + "tags": [], + "label": "CaseTooltipContentProps", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.status", + "type": "Enum", + "tags": [], + "label": "status", + "description": [], + "signature": [ + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseStatuses", + "text": "CaseStatuses" + } + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.totalComments", + "type": "number", + "tags": [], + "label": "totalComments", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.createdAt", + "type": "string", + "tags": [], + "label": "createdAt", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipContentProps.createdBy", + "type": "Object", + "tags": [], + "label": "createdBy", + "description": [], + "signature": [ + "{ username?: string | undefined; fullName?: string | undefined; }" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps", + "type": "Interface", + "tags": [], + "label": "CaseTooltipProps", + "description": [], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.children", + "type": "CompoundType", + "tags": [], + "label": "children", + "description": [], + "signature": [ + "boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.content", + "type": "Object", + "tags": [], + "label": "content", + "description": [], + "signature": [ + { + "pluginId": "@kbn/cases-components", + "scope": "common", + "docId": "kibKbnCasesComponentsPluginApi", + "section": "def-common.CaseTooltipContentProps", + "text": "CaseTooltipContentProps" + } + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.dataTestSubj", + "type": "string", + "tags": [], + "label": "dataTestSubj", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.className", + "type": "string", + "tags": [], + "label": "className", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cases-components", + "id": "def-common.CaseTooltipProps.loading", + "type": "CompoundType", + "tags": [], + "label": "loading", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-cases-components/src/tooltip/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false } ], - "interfaces": [], "enums": [ { "parentPluginId": "@kbn/cases-components", diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 46d446cbc675cc..1383a7a084c4c0 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; @@ -21,13 +21,16 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 4 | 0 | 3 | 0 | +| 19 | 0 | 17 | 0 | ## Common ### Functions +### Interfaces + + ### Enums diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index b28431fa63c134..9ccb77e9e7530f 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 7c1525d0c5053c..d2db6df86e1c11 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 93475daa01c6c5..1fb428f7bfd86b 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 65db6ed620daed..050646efc62bef 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index d3684ae9d7adb9..1e041284ad082a 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 68418049a8a408..0272b99dc0d5f5 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index 5f8daa694c2806..4450424eb9146e 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 57f37f8c8d946a..15900a4a750f26 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 84bbf658fb8ccb..963bb0bf55f556 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 3ccc2ed171f638..1ce90777a92655 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index 68b8d15e419355..09307a9a5e8b3b 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 7a1d91a0137daf..a20e9f8a3c5aa2 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 3d2b49044c92f3..7dfc1cd540af32 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index bc756a75cc1532..f5557404253efd 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 9a8e864e75fade..fd7b8006083eaf 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 47fd0f6b5e19dd..cf91b8ca6196db 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 93b772ec2ccc5b..a0b19a767f0b2a 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 1e22382c5abff4..2a399c82ae3170 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 4703e70fae435d..5c212de74c01f6 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index dfd0c1052b88f8..29afa052090f3e 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index ec7b5806fff32f..8da709e6fdf74b 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 5cc41d84c9f541..c3796ff08c7f44 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index c9b9a3e975aa16..2dc0511e53a6e6 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index b9277c2c0284d4..fe7ad49f1c35a1 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 854eccc1b921f3..4e8f4094ebc616 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 501a88d08e7a5d..cd89760667b73b 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index e8b84dd1ac70f0..b72f07dc3db019 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 9042e62c59bea3..61b5ca8885174e 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 553496ecf484a9..55630403a79792 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index ef94ed601ba69d..369ca58e93dbc4 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 82b52256af8941..a168e0a7d17cf2 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 7265551f325705..0c78ca87b6f547 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.devdocs.json b/api_docs/kbn_core_chrome_browser.devdocs.json index 11d74117c84156..f5c7db656e790e 100644 --- a/api_docs/kbn_core_chrome_browser.devdocs.json +++ b/api_docs/kbn_core_chrome_browser.devdocs.json @@ -422,6 +422,22 @@ "path": "packages/core/chrome/core-chrome-browser/src/help_extension.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeHelpExtensionMenuCustomLink.external", + "type": "CompoundType", + "tags": [], + "label": "external", + "description": [ + "\nOpens link in new tab" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/core/chrome/core-chrome-browser/src/help_extension.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index a9b56861226b4b..ad9782c1f33c73 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; @@ -21,7 +21,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 119 | 0 | 46 | 0 | +| 120 | 0 | 46 | 0 | ## Common diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 984143fca593b7..2b89597d24af07 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 94965fbf1999c9..bcd2d4cbb802d2 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 1c6283499631f5..6bc4310789592b 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index a27c16ddc13d90..883a8b4114df5f 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index 21a6de75a1d12e..606f917d876988 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 5c15a6f9a7ebb3..77a74fa813459b 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index 75e6dbee2b6038..183da513a2b920 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index 7a632f526d7806..013ecebe3b5ad3 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index fa6b31f81e376b..b8ecb5935e6498 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 6d9d0023e40bfa..7725e72b796e21 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index 716ff52e30287b..e052464f84e8b1 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 699205a6dff9e2..2a30857093ccb1 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index bbbac870d53350..e29ade1fef42c3 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index b881647823acb3..66f16160cd23dc 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 3d17713b3d95d4..fff8b8004aaab5 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 158b5fcadc7056..a762f3f3e68822 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index a8f16a527d8390..416b2979acad81 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 3e59d579b7cdc2..5a265902076e97 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index ea4d17d85e064c..be24bb8e16b1c1 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 1085010c4f63ef..2f0777515d6744 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 9fac6a9393f54f..f0b4b587da614a 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 8bb6d7854ab8c9..a7563f1802b72e 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index e7243805529dfd..cb1080d43cb148 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 86a4704eca32b2..e09c279ec461dd 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 2d88b369bfd300..955ee445f9995c 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index a29a8ec13fbd8a..472b0b5ccc1b9d 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 0e0b159fa6821e..c13b75a9f2da46 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 0095a1f843e7cf..4e540508c7bb50 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 08ff3a8998203e..c4e5788d553671 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 213b91f9f42b80..7c77a10d2711e3 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index acdd53c71e2d7f..44c88de8f84a83 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index ca79163131d9db..c6fcc3f3526897 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 28c3c59b22d71a..7765d5b30d751f 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 034799a64176af..9a77d31cc8e59a 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 1856b83401dd8d..3a0a45182fbd11 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 57ee12eb2cd764..ffd424441e1d05 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index fde5d3fc2fa58d..ee2d03ab82b63c 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 413bd82ef9cae5..f96855ef9dc755 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 4034e8442c9e59..5372de82f3d221 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 2ebd60b4d37976..5bf41ab4e30b0c 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 67e3bd22f002a5..e2590f15a815c4 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index be4e5d4f5f82b2..bd75e3445c5982 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index 50e2ef853f5954..b2575105ac9c6f 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 299b9a0ba1e708..1f2482afeff634 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 1669e41bc417a3..456c88de99e289 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index edf932e97d4c04..35f035dc528adc 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index fbf6cf1d13e4ac..eb9a5332d75401 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 0c611c3ef3afaa..8f0d54c59f90fd 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 57b9b388f27626..58c8e413baf0b7 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.devdocs.json b/api_docs/kbn_core_http_server_mocks.devdocs.json index 3e64bb2af2e99a..03dcec7536ef24 100644 --- a/api_docs/kbn_core_http_server_mocks.devdocs.json +++ b/api_docs/kbn_core_http_server_mocks.devdocs.json @@ -886,7 +886,9 @@ "IncomingMessage", "; res: ", "ServerResponse", - "; }> | undefined; readonly route?: ", + "<", + "IncomingMessage", + ">; }> | undefined; readonly route?: ", { "pluginId": "@kbn/utility-types", "scope": "common", diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 10904f85d851bf..74bb1cf8de8c72 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 98b40f1bb4e9c4..de5cb71f971ef8 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 5da8faeb5e5dc5..546afc9f715eb5 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index 7d3b2d9bfcff95..c3b532bc5ffab6 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 132a7a801d399d..6190756d945405 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 4d5420c4e6e175..e1773261895124 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 9080d30136aba2..85d59b760de15b 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index bd6ff73af6705a..41956983980e77 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 9b58c3dd35662c..f2b92bf299b734 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index f7999bb2cedb1c..c3fa9de8f5ec80 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 10ee5e84a110f3..6dabcd528a50dd 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index 7b9c2274529ded..263138ba9bddae 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index f91800694fb6c9..c5f44e04c9420b 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index d3e89324f66c6f..1f6fb9346f70a0 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 8d50db8b9f8b96..313b37477b530a 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 6bec62f30078f0..ddbcd3010e164c 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 86de318294ced5..de392e214465e5 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index bc0ed35b27bc78..3106e8c3de66cb 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 919e61e9c951c7..e07daaba8f54f7 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index fd768ebf4a0fe0..b83f0957c217af 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index f5a290cba9c07d..73b620be148862 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index e1c3418dbe4ade..ea9246b2b07d5c 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index f9db5b936975ca..a59ea081e17cac 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index ed482c62fdb5e2..5237821584191b 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index 58aa145187b0f6..bc28583413524a 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index b19aa9d5768054..b2a98d5704fd75 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 6d9f0d91d5f506..c83a0cda2501ad 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index 11558e0da9904d..d9dac783cec142 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index beefe02de85428..9da36254234200 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index f1ffa9132dd09b..b9ecdfc7751e3d 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index c810f8c604eade..c6e6a665885c78 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 45a5f1cf98e404..98079ea1e6b469 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 71208cc4065f1b..8108494b00c906 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 4978f129043662..d01bf2baef294e 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index b4823d53c0d4d7..777e9d238e683a 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index bb8c81c975fdc7..e05cb04898b8b5 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 98f4cccbb535ff..441d591bebcf4f 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index da25ba8fed1047..b9d31dc75058bd 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 5a844692e94129..074104605e4c7d 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index f20cea4df6fc1a..fbce8ff25a5782 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index 627a6b6162186a..ac788fd89acb99 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index 0f25d646cc70a1..353f961c17c594 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index 8f25db54eb5a29..e0f0cfcfd7f35a 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 08dfb4a4e80ac1..c88269bf119989 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 8beaef277c4ffb..1a2df544e05a6f 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index edf0c04a26b99c..8639ebdc3695d1 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index a86d42d0cb55f2..2bd563246fb9f5 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index 18e39b36ce81ee..18ce469e778726 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 796eb5bdea3d11..39ebf7912e8646 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 2c0568f19555c8..1fd9db3b76d42f 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index aa74e3ee2fb070..0706ece98d2bce 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 6f1e149283ef4a..a9c7379266a684 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index d1c0294fb578c5..b31ce7c8611790 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index c1185b7d885164..c92bb074e7a305 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index 67740d149c2063..2513ceec8ecee9 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 784c791d9af396..abf38108404579 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index 00fa3c64e050cd..7dd0192cc1b874 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 6b96a0a34fd1f7..75c7047b9ed673 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 01a010a304a27f..fad9f8a7b25f49 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 2d9e1ef718fd5e..1bf3921e97e5dc 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 839fa91de9e285..b54f4ead918bcd 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 3474e6cfda0104..cfad4d9b5fa974 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 624fc57ccd82ff..64ca53dc9e25dc 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index bb8d3763f39603..bb8c4f84b4de0c 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index dfa000761cd679..aabf7772e2923d 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 1831961324062e..39be35691328a1 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index d91b1cee3531b0..b70ff69f57b35a 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 91fa65dfece1f3..7e3c8455ca8f36 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index ef31947b0fd9ab..aebb7d2e48094f 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 5f1dacc24c5eab..343f9c20c51bfb 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index 28fad63abb437b..ec3395e709bb22 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 17e55440712d64..8a1c75f66698bd 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index ba7ba8935ebba5..0b027bbb83c27f 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index e9598f9c1e9d2b..9548cb4e6da0e1 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 23e3a16ce535b4..6307b046d66edc 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 79a6c7bec0d465..1405c952237f3f 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 24e00dfbad8768..f704f8861bfa70 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index 1c8cf205577e9e..ca35f69a29717e 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index f1c9e0625f931a..7d926327aec1a2 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index 11fd534bf739fb..efce399b6387a2 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 67887568fc9e16..064fc439869879 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index f530d638eb8c70..32b862453c5c9e 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index f813dc823bc697..78c35be8d2b93a 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 2fbda680a74473..453bf061ea015f 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index d5f8c380954056..ee6c19dd69594a 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 1fca7db9a6df4d..c827cd45618400 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index a5de64a2bdf75a..4f638de74c1279 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 7826eeb2fb7cb3..9dfb5388b6e424 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 97a1670b755cbc..2778231aaec559 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 49ba0ef192712c..2dd89ad16bdd8f 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 59cca04ae2899b..a7636942acda7e 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 18c3fc286ded38..cea0719a9a6362 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 497b5f3f9eeb48..5c1279a2ddbcf1 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 552bfc7e0c4950..5a8e90548ea723 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 85a90b1877ea87..f7279b5b1b5a9a 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 946e9dd8613393..88c6669c818520 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index dd46d09c687b32..1cd1241e720209 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index a91e2406184fd3..3871a67bcaa01f 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index cf0c657dcde336..cf3b6246ed16a8 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.devdocs.json b/api_docs/kbn_es_query.devdocs.json index 775b0dc995f1a7..caa4ce3315b8dd 100644 --- a/api_docs/kbn_es_query.devdocs.json +++ b/api_docs/kbn_es_query.devdocs.json @@ -2201,6 +2201,129 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/es-query", + "id": "def-common.filterToQueryDsl", + "type": "Function", + "tags": [], + "label": "filterToQueryDsl", + "description": [], + "signature": [ + "(filter: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + ", inputDataViews: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.DataViewBase", + "text": "DataViewBase" + }, + " | ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.DataViewBase", + "text": "DataViewBase" + }, + "[] | undefined, options: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.EsQueryFiltersConfig", + "text": "EsQueryFiltersConfig" + }, + ") => ", + "QueryDslQueryContainer" + ], + "path": "packages/kbn-es-query/src/es_query/from_filters.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/es-query", + "id": "def-common.filterToQueryDsl.$1", + "type": "Object", + "tags": [], + "label": "filter", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + } + ], + "path": "packages/kbn-es-query/src/es_query/from_filters.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/es-query", + "id": "def-common.filterToQueryDsl.$2", + "type": "CompoundType", + "tags": [], + "label": "inputDataViews", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.DataViewBase", + "text": "DataViewBase" + }, + " | ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.DataViewBase", + "text": "DataViewBase" + }, + "[] | undefined" + ], + "path": "packages/kbn-es-query/src/es_query/from_filters.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/es-query", + "id": "def-common.filterToQueryDsl.$3", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.EsQueryFiltersConfig", + "text": "EsQueryFiltersConfig" + } + ], + "path": "packages/kbn-es-query/src/es_query/from_filters.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/es-query", "id": "def-common.fromCombinedFilter", @@ -4047,7 +4170,7 @@ "section": "def-common.Filter", "text": "Filter" }, - ", field?: string | undefined, operator?: FilterOperator | undefined, params?: any) => { meta: { key: string | undefined; field: string | undefined; params: { query: undefined; }; value: undefined; type: undefined; alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; }; query: undefined; $state?: { store: ", + ", field?: string | undefined, operator?: FilterOperator | undefined, params?: any, fieldType?: string | undefined) => { meta: { key: string | undefined; field: string | undefined; params: { query: undefined; }; value: undefined; type: undefined; alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; }; query: undefined; $state?: { store: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -4063,7 +4186,7 @@ "section": "def-common.FilterStateStore", "text": "FilterStateStore" }, - "; } | undefined; } | { meta: { negate: boolean | undefined; type: string | undefined; params: any; alias?: string | null | undefined; disabled?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; key?: string | undefined; value?: string | undefined; }; query: { range: { [x: string]: any; }; }; $state?: { store: ", + "; } | undefined; } | { meta: { negate: boolean | undefined; type: string | undefined; params: { gte: string | number | undefined; lt: string | number | undefined; }; alias?: string | null | undefined; disabled?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; key?: string | undefined; value?: string | undefined; }; query: { range: { [x: string]: { gte: string | number | undefined; lt: string | number | undefined; }; }; }; $state?: { store: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -4079,7 +4202,7 @@ "section": "def-common.FilterStateStore", "text": "FilterStateStore" }, - "; } | undefined; } | { meta: { negate: boolean | undefined; type: string | undefined; params: any; alias?: string | null | undefined; disabled?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; key?: string | undefined; value?: string | undefined; }; query: { match_phrase: { [x: string]: any; }; }; $state?: { store: ", + "; } | undefined; } | { meta: { negate: boolean | undefined; type: string | undefined; params: any; value: undefined; alias?: string | null | undefined; disabled?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; key?: string | undefined; }; query: { match_phrase: { [x: string]: any; }; }; $state?: { store: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -4158,6 +4281,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/es-query", + "id": "def-common.updateFilter.$5", + "type": "string", + "tags": [], + "label": "fieldType", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-es-query/src/filters/helpers/update_filter.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [], diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 39c6febada4c2c..fac2d5468a936b 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 244 | 2 | 187 | 13 | +| 249 | 2 | 192 | 13 | ## Common diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 231527940d8a80..94f159886adda8 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 78c526bf9dca00..11425a42c525eb 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index b13003b359db15..444ad17a268eab 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 3cb02a2abd6d68..493a9424caf54f 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index fc154315796736..8331cdecf359f8 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 8fd22f8be9f7d3..5278da727fe22a 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index 27fafda0b49737..0667f2f59db7d2 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index ed378e26f9b7b4..ca8b60cec723bd 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 2ef7dde4835e6d..ebb147216a9160 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.devdocs.json b/api_docs/kbn_hapi_mocks.devdocs.json index b6bc88b0ceafc2..ea6ed36bfa5807 100644 --- a/api_docs/kbn_hapi_mocks.devdocs.json +++ b/api_docs/kbn_hapi_mocks.devdocs.json @@ -248,7 +248,9 @@ "IncomingMessage", "; res: ", "ServerResponse", - "; }> | undefined; readonly route?: ", + "<", + "IncomingMessage", + ">; }> | undefined; readonly route?: ", { "pluginId": "@kbn/utility-types", "scope": "common", diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 28133b495dc252..4a78887e481ec7 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 33cdb9c49636cc..8e6c006b602cca 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index b23a5b2295bacc..05a0652a933945 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 705b0b9e506fb8..a0adb2ebeb1347 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 7ef77c3383825c..0d032d65c8bbc8 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index 414cefd95eecd5..bc693d547cb77a 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 8a7eeabb8e15e1..631e66e5526fd7 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 0e39c1a319bcbe..fdee8228580c76 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index f4a245b05e6017..5e24cf172f3886 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 42ec6f839193ee..fb3ac9d3269c9e 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index ae7af9171acba0..ac5d2f4c930788 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index cc094ba17bfa31..f9abb342f54608 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 8b903a91a5f63b..97989573151470 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index 52b091bbcceccb..f8ed3a7159d478 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 347f5b3cd1859d..7828be038bea0e 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index af67c36031f19b..b7ab7611478787 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 11cb3133f7649f..9b80fe0e7ff699 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index cc7ec831f84021..a921e32e6dbae6 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 121c169d68fde6..50d75602e83a84 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 23fb42075a7b6e..a7d85207967aa0 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index dc66bb9da70ded..390749b7ec1e16 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index b426af00bcee9e..e1b2128ec82878 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 22af5b56fb4f79..efdd33b0391349 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 376504b80e9e6e..53c553077041da 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index a14cccd1784982..890726df5ea703 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index e0f7f02c73ef84..ddd706c6d80ddc 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 6758e1e73f64da..47d5c587e0c334 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 0d5e4ad9300c68..fd951fba1eb5e8 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 79d35bdd1e9cf8..4afef6c1cb1961 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 5aa1aaf5ba6541..fde177b5de6f71 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index d962fac1cb4b43..72e19743a9cd69 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 8dee161f1e31c8..ac63fff1084b63 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index c1453c2409471c..973415f94b17d9 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 1d6fa74785b7c8..26b4deef4e067d 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index a8c6595cc3397e..45c32038437795 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index a76455e4c917d0..d64ccf7e7977d4 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 935ac1afb3bb6c..34469ade3c69e5 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index b8ebeaf09d6e98..26d7842c0dcb58 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 731aaa7088d34b..d43ce5536b441e 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index d4df97fc0e847b..cf1709dcdd0e2d 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 479c3a3f1b7c1e..f3d12996b6f2f1 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.devdocs.json b/api_docs/kbn_securitysolution_autocomplete.devdocs.json index 5f57ad28f5f73b..365830c784ff37 100644 --- a/api_docs/kbn_securitysolution_autocomplete.devdocs.json +++ b/api_docs/kbn_securitysolution_autocomplete.devdocs.json @@ -842,7 +842,7 @@ "label": "smallLists", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx", "deprecated": false, @@ -856,7 +856,7 @@ "label": "largeLists", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 99ee0ddc47034c..ec2a7e89bcb179 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 860b4d4bdbb336..c6df175c945abb 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.devdocs.json b/api_docs/kbn_securitysolution_exception_list_components.devdocs.json index 83973455bda55c..6e10def35b04f5 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.devdocs.json +++ b/api_docs/kbn_securitysolution_exception_list_components.devdocs.json @@ -721,7 +721,7 @@ "label": "item", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/header/index.tsx", "deprecated": false, @@ -788,7 +788,7 @@ "label": "item", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx", "deprecated": false, @@ -904,7 +904,7 @@ "label": "exceptionItem", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, @@ -1095,7 +1095,7 @@ "label": "onEditException", "description": [], "signature": [ - "(item: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void" + "(item: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, @@ -1109,7 +1109,7 @@ "label": "item", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-exception-list-components/src/exception_item_card/exception_item_card.tsx", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index d3ba5df20a821b..b1db1199786a07 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 28738aa7dad041..dafdb0bf90124f 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index e38964fec0bbaf..04c8f63fce960a 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json index 9bcbaf8108ab88..f54dfcd7e0da22 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json +++ b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json @@ -27,7 +27,7 @@ "label": "updateExceptionListItemValidate", "description": [], "signature": [ - "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -41,7 +41,7 @@ "label": "schema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -60,7 +60,7 @@ "label": "validateComments", "description": [], "signature": [ - "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -74,7 +74,7 @@ "label": "item", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -162,7 +162,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -718,7 +718,7 @@ "label": "exceptions", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -1589,7 +1589,7 @@ "label": "exceptions", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -1847,7 +1847,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -1945,7 +1945,7 @@ "label": "exceptions", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false, @@ -2617,7 +2617,7 @@ "label": "CreateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -2647,7 +2647,7 @@ "label": "CreateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -2662,7 +2662,7 @@ "label": "CreateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -2737,7 +2737,7 @@ "label": "CreateListSchema", "description": [], "signature": [ - "{ description: string; name: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" + "{ description: string; name: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2752,7 +2752,7 @@ "label": "CreateListSchemaDecoded", "description": [], "signature": [ - "{ name: string; description: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; id: string | undefined; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" + "{ name: string; description: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; id: string | undefined; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2767,7 +2767,7 @@ "label": "CreateRuleExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_rule_exception_item_schema/index.ts", "deprecated": false, @@ -2782,7 +2782,7 @@ "label": "CreateRuleExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; list_id: undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; list_id: undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_rule_exception_item_schema/index.ts", "deprecated": false, @@ -3097,7 +3097,7 @@ "label": "EntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -3112,7 +3112,7 @@ "label": "EntriesArrayOrUndefined", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[] | undefined" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[] | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -3127,7 +3127,7 @@ "label": "Entry", "description": [], "signature": [ - "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" + "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -3157,7 +3157,7 @@ "label": "EntryList", "description": [], "signature": [ - "{ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" + "{ field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries_list/index.ts", "deprecated": false, @@ -3247,7 +3247,7 @@ "label": "ExceptionListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/exception_list_item_schema/index.ts", "deprecated": false, @@ -3592,7 +3592,7 @@ "label": "FoundAllListItemsSchema", "description": [], "signature": [ - "{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; }" + "{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_all_list_items_schema/index.ts", "deprecated": false, @@ -3607,7 +3607,7 @@ "label": "FoundExceptionListItemSchema", "description": [], "signature": [ - "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" + "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_exception_list_item_schema/index.ts", "deprecated": false, @@ -3637,7 +3637,7 @@ "label": "FoundListItemSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_item_schema/index.ts", "deprecated": false, @@ -3652,7 +3652,7 @@ "label": "FoundListsBySizeSchema", "description": [], "signature": [ - "{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }" + "{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_lists_by_size_schema/index.ts", "deprecated": false, @@ -3667,7 +3667,7 @@ "label": "FoundListSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_schema/index.ts", "deprecated": false, @@ -3682,7 +3682,7 @@ "label": "GetExceptionFilterSchema", "description": [], "signature": [ - "({ exception_list_ids: { exception_list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; type: \"exception_list_ids\"; } | { exceptions: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; type: \"exception_items\"; }) & { alias?: string | undefined; chunk_size?: number | undefined; exclude_exceptions?: boolean | undefined; }" + "({ exception_list_ids: { exception_list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; type: \"exception_list_ids\"; } | { exceptions: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; type: \"exception_items\"; }) & { alias?: string | undefined; chunk_size?: number | undefined; exclude_exceptions?: boolean | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/get_exception_filter_schema/index.ts", "deprecated": false, @@ -3802,7 +3802,7 @@ "label": "ImportExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -3817,7 +3817,7 @@ "label": "ImportExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -3877,7 +3877,7 @@ "label": "ImportListItemQuerySchema", "description": [], "signature": [ - "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" + "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -3892,7 +3892,7 @@ "label": "ImportListItemQuerySchemaEncoded", "description": [], "signature": [ - "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" + "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -4042,7 +4042,7 @@ "label": "ListArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -4087,7 +4087,7 @@ "label": "ListItemArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -4117,7 +4117,7 @@ "label": "ListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -4147,7 +4147,7 @@ "label": "ListSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -4372,7 +4372,7 @@ "label": "NonEmptyEntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -4387,7 +4387,7 @@ "label": "NonEmptyEntriesArrayDecoded", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -4822,7 +4822,7 @@ "label": "SearchListItemArraySchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -4837,7 +4837,7 @@ "label": "SearchListItemSchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -5002,7 +5002,7 @@ "label": "Type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -5017,7 +5017,7 @@ "label": "TypeOrUndefined", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -5077,7 +5077,7 @@ "label": "UpdateEndpointListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -5092,7 +5092,7 @@ "label": "UpdateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -5107,7 +5107,7 @@ "label": "UpdateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -5122,7 +5122,7 @@ "label": "UpdateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -5677,7 +5677,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -5845,7 +5845,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", @@ -7252,7 +7252,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -8521,7 +8521,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -8808,7 +8808,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; item_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; item_id: ", "Type", "; list_id: ", "Type", @@ -9848,7 +9848,7 @@ ], "signature": [ "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>" + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -10858,7 +10858,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", @@ -10912,7 +10912,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index b4c274a317c2b6..84abef50d74cd6 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index c0ce6c9eedf720..2caed79022855a 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index d6a7be6272d81a..0f1200f62d7725 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.devdocs.json b/api_docs/kbn_securitysolution_list_api.devdocs.json index cd8334e742dda8..44699631fbffc2 100644 --- a/api_docs/kbn_securitysolution_list_api.devdocs.json +++ b/api_docs/kbn_securitysolution_list_api.devdocs.json @@ -82,7 +82,7 @@ "section": "def-common.AddExceptionListItemProps", "text": "AddExceptionListItemProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -270,7 +270,7 @@ "section": "def-common.ApiCallByIdProps", "text": "ApiCallByIdProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -317,7 +317,7 @@ "section": "def-common.DeleteListParams", "text": "DeleteListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -509,7 +509,7 @@ "section": "def-common.ApiCallByIdProps", "text": "ApiCallByIdProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -556,7 +556,7 @@ "section": "def-common.ApiCallByListIdProps", "text": "ApiCallByListIdProps" }, - ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" + ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -650,7 +650,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ") => Promise<{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" + ") => Promise<{ largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -697,7 +697,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -862,7 +862,7 @@ "section": "def-common.ImportListParams", "text": "ImportListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -1072,7 +1072,7 @@ "section": "def-common.UpdateExceptionListItemProps", "text": "UpdateExceptionListItemProps" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -1471,7 +1471,7 @@ "label": "type", "description": [], "signature": [ - "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" + "\"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\" | undefined" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/types.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 83f80419db12db..5caaeaf4662eb9 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index e71dcaa48e28f4..fa9092037f8fe9 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.devdocs.json b/api_docs/kbn_securitysolution_list_hooks.devdocs.json index befcfaaecfb139..a9290e1b6ed6b7 100644 --- a/api_docs/kbn_securitysolution_list_hooks.devdocs.json +++ b/api_docs/kbn_securitysolution_list_hooks.devdocs.json @@ -29,7 +29,7 @@ "\nThis adds an id to the incoming exception item entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n\nThis does break the type system slightly as we are lying a bit to the type system as we return\nthe same exceptionItem as we have previously but are augmenting the arrays with an id which TypeScript\ndoesn't mind us doing here. However, downstream you will notice that you have an id when the type\ndoes not indicate it. In that case use (ExceptionItem & { id: string }) temporarily if you're using the id. If you're not,\nyou can ignore the id and just use the normal TypeScript with ReactJS.\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -45,7 +45,7 @@ "The exceptionItem to add an id to the threat matches." ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -68,7 +68,7 @@ "\nThis removes createdAt, createdBy from the exceptionItem if a comment was added to\nthe Exception item, and return the comment message with id to prevent creating the commet\ntwice" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -84,7 +84,7 @@ "The exceptionItem to remove createdAt, createdBy from the comments array." ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -107,7 +107,7 @@ "\nThis removes an id from the exceptionItem entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n" ], "signature": [ - "(exceptionItem: T) => T" + "(exceptionItem: T) => T" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -146,7 +146,7 @@ "\nTransforms the output of rules to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the input called \"myNewTransform\" do it\nin the form of:\nflow(addIdToExceptionItemEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -162,7 +162,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -183,7 +183,7 @@ "label": "transformNewItemOutput", "description": [], "signature": [ - "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -197,7 +197,7 @@ "label": "exceptionItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -218,7 +218,7 @@ "\nTransforms the output of exception items to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the output called \"myNewTransform\" do it\nin the form of:\nflow(removeIdFromExceptionItemsEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -234,7 +234,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -407,7 +407,7 @@ "section": "def-common.DeleteListParams", "text": "DeleteListParams" }, - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_delete_list/index.ts", "deprecated": false, @@ -545,7 +545,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_find_lists/index.ts", "deprecated": false, @@ -586,7 +586,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ">], { largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" + ">], { largeLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; smallLists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_find_lists_by_size/index.ts", "deprecated": false, @@ -627,7 +627,7 @@ "section": "def-common.ImportListParams", "text": "ImportListParams" }, - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_import_list/index.ts", "deprecated": false, @@ -851,7 +851,7 @@ "label": "addExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -876,7 +876,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -895,7 +895,7 @@ "label": "updateExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -920,7 +920,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -1039,7 +1039,7 @@ "section": "def-common.ApiCallMemoProps", "text": "ApiCallMemoProps" }, - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -1060,7 +1060,7 @@ "section": "def-common.ApiCallMemoProps", "text": "ApiCallMemoProps" }, - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -1423,7 +1423,7 @@ "label": "ReturnPersistExceptionItem", "description": [], "signature": [ - "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" + "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_persist_exception_item/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 504aaf822c3811..ea0c67170bcac6 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.devdocs.json b/api_docs/kbn_securitysolution_list_utils.devdocs.json index e874763d9e6306..4fe323489c2170 100644 --- a/api_docs/kbn_securitysolution_list_utils.devdocs.json +++ b/api_docs/kbn_securitysolution_list_utils.devdocs.json @@ -27,7 +27,7 @@ "label": "addIdToEntries", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -41,7 +41,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -314,7 +314,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" + ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -474,7 +474,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", + ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -521,7 +521,7 @@ "- newly selected list" ], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -2108,7 +2108,7 @@ "label": "hasLargeValueList", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -2122,7 +2122,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -2779,7 +2779,7 @@ "label": "BuilderEntry", "description": [], "signature": [ - "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", + "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -2840,7 +2840,7 @@ "label": "CreateExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"entries\" | \"meta\" | \"list_id\" | \"namespace_type\"> & { meta: { temporaryUuid: string; }; entries: ", + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"entries\" | \"meta\" | \"list_id\" | \"namespace_type\"> & { meta: { temporaryUuid: string; }; entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -2966,7 +2966,7 @@ "label": "ExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", + "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3033,7 +3033,7 @@ "label": "ExceptionsBuilderReturnExceptionItem", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; list_id?: undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-utils/src/types/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index d7fdfddfd55e34..134ca5e360ca27 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 1a323a4fc946bf..335f4c299ed739 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index a3bde43cc2357d..97050175777937 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 52a0bec2e889a5..b0fadb56e32ca3 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index f92973a7e31121..4c0b45c1273cb9 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 99a7870efbd1e9..52283100abbc15 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index c31ad5facdcd6c..316e48226bae76 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index 0cc2cf33ea16e4..e769b5a784e2f6 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 81d4b273231724..05d911c2a5c82a 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index d27e59abd681dd..e51317e0af2bd4 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 4979d187db7aa2..9c6ce26ba3ee61 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 4c3c00ba0080ca..cba1def03b762e 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index f8bc508555762e..dd67a2c134ddfd 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index d10aed549cf858..25568d770ba069 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index a6853aecb6b507..fe2a2675c45f61 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 95d5d7e3e211ed..80d0d0760af519 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index 36a4c751df96b9..448e155417e08d 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index 9ea068bfbfe5ae..0b927ab8079f62 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 8b117a4ddf3952..163bdbd1316cb5 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 07a81f3b0229c5..3e87e8bdaa72cb 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index 00c3c595176a09..c424d8e88aac7f 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index f35cde586224f8..e8213f3111c536 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index c72d360d77c7ee..f04c04386b6965 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 63e8718fd8ae4c..825a52f29d24b4 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index ab5fad6a46ee58..dcd2e7576b9732 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 857889a9b5f642..1ea17698443015 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 459c55296eaf94..d4344a2edb7d0a 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index d0f4517a77aa57..9a23865a9d39b7 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index b0f0c766c9f41a..c542f315b5dd1d 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 04abc17211078d..78bddfa5de4033 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index b1c9d1040a3400..8192dff2449f84 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 23040234719fc5..e2f62a7e695939 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 875878ce3e4d40..43723d1181d01b 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index 7c58fc99b257cb..5b7bf8f6c12ec0 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 2fd36f09dce7e6..afc6bd84f32d0e 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index ff5a74c44862ba..edd0ad93ed24fd 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index f9d1c59554fef0..241cc809bdaadb 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index ca74d483aba718..e462f2c0e5c65b 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index 3cbac583be707c..dffe5c2247f2da 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 6ed4111aad6de1..870fed94d83839 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index 73ee7c278039f8..d8f97d5f50ac9c 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index 66d3d901b72134..a0303300825630 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index bf9443c6b484e7..acb61141fa5667 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 30ef884c27b21b..4d4c9731702ff2 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 794f45af5522f8..6a1332238b333e 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 158ae23491ca38..8bf96726acc577 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 39b82513865112..c885fb60b7ff46 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 8b16e8ea37c0aa..3af966a999afe5 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 67f0f89961e6e8..ba2cf954dbdb62 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 3bec1c372797e3..0f53d02b03fae5 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index b5910d0efa06da..29520c4dadab99 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index d80d0423cafbe1..68d4aeafb3ed7f 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 765f188ad85aa1..ffbbb0c11f9512 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index b4437b59ae07ec..7a53910e3f2263 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 9cb03d97de3165..72d6261c0bd752 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index d620260268d873..f0148700e75fcd 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 115d244a57ec42..39302005457801 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index d01cd4c11695d5..b17aa744d4f701 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 7d5c8452b438cb..173892aef0a28f 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 2e48c18c489684..4ac2d5a90fac2a 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 1851fff1a0ccf8..ce31e7f13af761 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 74b9284e28c9a0..d3f3d2c20b5cec 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 4fee855414f491..c7f372d17ce13f 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 3319e2d2b4bcea..ccc49b2480e41d 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index b1320400e59c8d..f863adfa011db0 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index f4856bf7b1e1b4..291b3218340402 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index befe0d85db8b8b..486b7e288918da 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index c6f7f545ffa88a..8bea4499a7bddf 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 6c6fe37d2eaaa9..12ac8378f21eff 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 5dd4fd210c1395..392be28b9a38a6 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index fe6b127d726b69..051d8a6071cb15 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.devdocs.json b/api_docs/lists.devdocs.json index 6233f803836c37..711eb0bcf6a20c 100644 --- a/api_docs/lists.devdocs.json +++ b/api_docs/lists.devdocs.json @@ -345,7 +345,7 @@ "label": "exceptionsToDelete", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx", "deprecated": false, @@ -622,7 +622,7 @@ "signature": [ "({ itemId, id, namespaceType, }: ", "GetExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -700,7 +700,7 @@ "signature": [ "({ comments, description, entries, itemId, meta, name, osTypes, tags, type, }: ", "CreateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -776,7 +776,7 @@ "signature": [ "({ _version, comments, description, entries, id, itemId, meta, name, osTypes, tags, type, }: ", "UpdateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -814,7 +814,7 @@ "signature": [ "({ itemId, id, }: ", "GetEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -972,7 +972,7 @@ "section": "def-server.CreateExceptionListItemOptions", "text": "CreateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1022,7 +1022,7 @@ "section": "def-server.UpdateExceptionListItemOptions", "text": "UpdateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1066,7 +1066,7 @@ "signature": [ "({ id, itemId, namespaceType, }: ", "DeleteExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1140,7 +1140,7 @@ "signature": [ "({ id, itemId, }: ", "DeleteEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1176,7 +1176,7 @@ "signature": [ "({ listId, filter, perPage, pit, page, search, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1214,7 +1214,7 @@ "signature": [ "({ listId, filter, perPage, pit, page, search, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListsItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1252,7 +1252,7 @@ "signature": [ "({ perPage, pit, page, searchAfter, sortField, sortOrder, valueListId, }: ", "FindValueListExceptionListsItems", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1328,7 +1328,7 @@ "signature": [ "({ filter, perPage, page, pit, search, searchAfter, sortField, sortOrder, }: ", "FindEndpointListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1814,7 +1814,7 @@ "signature": [ "({ id }: ", "GetListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1852,7 +1852,7 @@ "signature": [ "({ id, deserializer, immutable, serializer, name, description, type, meta, version, }: ", "CreateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1890,7 +1890,7 @@ "signature": [ "({ id, deserializer, serializer, name, description, immutable, type, meta, version, }: ", "CreateListIfItDoesNotExistOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2408,7 +2408,7 @@ "signature": [ "({ id }: ", "DeleteListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2446,7 +2446,7 @@ "signature": [ "({ listId, value, type, }: ", "DeleteListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2484,7 +2484,7 @@ "signature": [ "({ id }: ", "DeleteListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2558,7 +2558,7 @@ "signature": [ "({ deserializer, serializer, type, listId, stream, meta, version, }: ", "ImportListItemsToStreamOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2594,7 +2594,7 @@ "signature": [ "({ listId, value, type, }: ", "GetListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2632,7 +2632,7 @@ "signature": [ "({ id, deserializer, serializer, listId, value, type, meta, }: ", "CreateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2668,7 +2668,7 @@ "signature": [ "({ _version, id, value, meta, }: ", "UpdateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2704,7 +2704,7 @@ "signature": [ "({ _version, id, name, description, meta, version, }: ", "UpdateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2740,7 +2740,7 @@ "signature": [ "({ id }: ", "GetListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2778,7 +2778,7 @@ "signature": [ "({ type, listId, value, }: ", "GetListItemsByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2816,7 +2816,7 @@ "signature": [ "({ type, listId, value, }: ", "SearchListItemByValuesOptions", - ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" + ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2854,7 +2854,7 @@ "signature": [ "({ filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, runtimeMappings, }: ", "FindListOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2892,7 +2892,7 @@ "signature": [ "({ listId, filter, currentIndexPosition, perPage, page, runtimeMappings, sortField, sortOrder, searchAfter, }: ", "FindListItemOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2928,7 +2928,7 @@ "signature": [ "({ listId, filter, sortField, sortOrder, }: ", "FindAllListItemsOptions", - ") => Promise<{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; } | null>" + ") => Promise<{ data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; updated_at: string; updated_by: string; value: string; }[]; total: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2997,7 +2997,7 @@ "an array with the exception list item entries" ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false, @@ -3309,7 +3309,7 @@ "item exception entries logic" ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"binary\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"date\" | \"keyword\" | \"ip\" | \"text\" | \"geo_point\" | \"geo_shape\" | \"date_nanos\" | \"binary\" | \"long\" | \"double\" | \"date_range\" | \"ip_range\" | \"shape\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"integer\" | \"double_range\" | \"float_range\" | \"integer_range\" | \"long_range\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false, diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 10ccad3ad9e43a..5f8da7a5e33dc3 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 8f06ef12a04e13..cd268de888f6e4 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 0f8f719fed732f..5c101eac778a54 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 7e7322fe5a6b75..3a074b874b3e39 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index c1a756160e3f9a..f1564fbfc13268 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index e5f0ada08a1d73..52550cadc48a68 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index a45045adf27985..00b3f061260e87 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index d0e2e08ab81437..e3742c0fbb8126 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 0f95e9d9c01301..21d8c6e411a046 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 29537e5dd1aa34..d47d889932b31b 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 4ef8210200fd01..f99c1d1c40cd71 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 5a669d9a707585..bc090400114539 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index fbdf7597026efb..2e29dcfb005a03 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 34354 | 526 | 24000 | 1191 | +| 34421 | 526 | 24056 | 1196 | ## Plugin Directory @@ -30,8 +30,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 220 | 8 | 215 | 24 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 1 | 32 | 2 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 12 | 0 | 1 | 2 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 434 | 0 | 425 | 37 | -| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 42 | 0 | 42 | 59 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 465 | 0 | 456 | 38 | +| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 42 | 0 | 42 | 61 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 89 | 1 | 74 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | @@ -39,7 +39,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 267 | 16 | 252 | 9 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 39 | 0 | 11 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | Chat available on Elastic Cloud deployments for quicker assistance. | 1 | 0 | 0 | 0 | -| | [Platform Onboarding](https://github.com/orgs/elastic/teams/platform-onboarding) | Static migration page where self-managed users can see text/copy about migrating to Elastic Cloud | 7 | 1 | 7 | 1 | +| | [Platform Onboarding](https://github.com/orgs/elastic/teams/platform-onboarding) | Static migration page where self-managed users can see text/copy about migrating to Elastic Cloud | 8 | 1 | 8 | 1 | | | [Cloud Native Integrations](https://github.com/orgs/elastic/teams/sec-cloudnative-integrations) | Defend for Containers | 2 | 0 | 2 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/@elastic/kibana-core) | Provides the necessary APIs to implement A/B testing scenarios, fetching the variations in configuration and reporting back metrics to track conversion rates of the experiments. | 12 | 0 | 0 | 0 | | cloudFullStory | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | When Kibana runs on Elastic Cloud, this plugin registers FullStory as a shipper for telemetry. | 0 | 0 | 0 | 0 | @@ -48,7 +48,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 17 | 0 | 2 | 2 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 264 | 0 | 260 | 9 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2823 | 17 | 1019 | 0 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2824 | 17 | 1019 | 0 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | customBranding | [global-experience](https://github.com/orgs/elastic/teams/kibana-global-experience) | Enables customization of Kibana | 0 | 0 | 0 | 0 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 107 | 0 | 88 | 1 | @@ -84,7 +84,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 7 | 0 | 7 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 170 | 0 | 160 | 13 | | | [Visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Adds expression runtime to Kibana | 2205 | 74 | 1746 | 5 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 227 | 0 | 96 | 2 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 236 | 0 | 100 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 26 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | | | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 254 | 1 | 45 | 5 | @@ -145,7 +145,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 4 | | searchprofiler | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 269 | 0 | 89 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 113 | 0 | 76 | 29 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 115 | 0 | 75 | 29 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 7 | 0 | 7 | 1 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 115 | 0 | 56 | 10 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 22 | 1 | 22 | 1 | @@ -158,11 +158,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 31 | 0 | 26 | 6 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 1 | 0 | 1 | 0 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 5 | 0 | 0 | 0 | -| | [Protections Experience Team](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 34 | 0 | 14 | 3 | +| | [Protections Experience Team](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 35 | 0 | 15 | 5 | | | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 257 | 1 | 214 | 21 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 579 | 11 | 550 | 53 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 580 | 11 | 551 | 53 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 144 | 2 | 99 | 12 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 206 | 0 | 140 | 9 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list which can be integrated into apps | 270 | 0 | 245 | 7 | @@ -209,7 +209,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Owner missing] | Elastic APM trace data generator | 152 | 0 | 152 | 16 | | | [Owner missing] | - | 11 | 0 | 11 | 0 | | | [Owner missing] | - | 10 | 0 | 10 | 0 | -| | [Owner missing] | - | 4 | 0 | 3 | 0 | +| | [Owner missing] | - | 19 | 0 | 17 | 0 | | | [Owner missing] | - | 76 | 0 | 76 | 0 | | | [Owner missing] | - | 7 | 0 | 2 | 0 | | | [Owner missing] | - | 3 | 0 | 3 | 0 | @@ -242,7 +242,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 5 | 0 | 0 | 0 | | | Kibana Core | - | 16 | 0 | 7 | 0 | | | Kibana Core | - | 6 | 0 | 6 | 0 | -| | Kibana Core | - | 119 | 0 | 46 | 0 | +| | Kibana Core | - | 120 | 0 | 46 | 0 | | | Kibana Core | - | 3 | 0 | 3 | 0 | | | Kibana Core | - | 4 | 0 | 4 | 0 | | | [Owner missing] | - | 8 | 0 | 8 | 0 | @@ -391,7 +391,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Owner missing] | - | 4 | 0 | 4 | 0 | | | [Owner missing] | - | 27 | 0 | 14 | 1 | | | Kibana Core | - | 7 | 0 | 3 | 0 | -| | [Owner missing] | - | 244 | 2 | 187 | 13 | +| | [Owner missing] | - | 249 | 2 | 192 | 13 | | | Kibana Core | - | 11 | 0 | 11 | 0 | | | [Owner missing] | - | 2 | 0 | 1 | 0 | | | [Owner missing] | - | 20 | 0 | 16 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index a3f8bc3c01fd10..ddd22b5d98288b 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 559faae0ac435e..8462ab9eb55fb6 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index e28f623a9c8d52..88dace58a3c616 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 62aea27ba58e59..ef66af531507ad 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 6c1bb0516d7139..26f6e01cca7c9a 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 66718bab2f6145..df05b55ca56679 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 4ed481e35bdf2b..914f9ac25522ed 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 13abe7a2a1e962..929a546f331175 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index c6e1655f619b77..4166448900097e 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index f5f903181d9d6c..b653be79e36330 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 13b93868ca83db..a96a6a681bea37 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 6aa37cc43d8e44..809da024dc7921 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 2578683f40c684..8d937b0d75f650 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 386e6ddb762931..28d5b1ec1cc5e6 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 3cda0ae2441b8c..d619dde786e529 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 7a1042600f6303..d383f6e06ffc16 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 8e51ac05f833aa..5c8d70432251e8 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -45,13 +45,44 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.kibanaBranch", + "type": "string", + "tags": [], + "label": "kibanaBranch", + "description": [ + "\nThe current Kibana branch. e.g. 'main'" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "securitySolution", "id": "def-public.Plugin.kibanaVersion", "type": "string", "tags": [], "label": "kibanaVersion", - "description": [], + "description": [ + "\nThe current Kibana version. e.g. '8.0.0' or '8.0.0-SNAPSHOT'" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.prebuiltRulesPackageVersion", + "type": "string", + "tags": [], + "label": "prebuiltRulesPackageVersion", + "description": [ + "\nFor internal use. Specify which version of the Detection Rules fleet package to install\nwhen upgrading rules. If not provided, the latest compatible package will be installed,\nor if running from a dev environment or -SNAPSHOT build, the latest pre-release package\nwill be used (if fleet is available or not within an airgapped environment).\n\nNote: This is for `upgrade only`, which occurs by means of the `useUpgradeSecurityPackages`\nhook when navigating to a Security Solution page. The package version specified in\n`fleet_packages.json` in project root will always be installed first on Kibana start if\nthe package is not already installed." + ], + "signature": [ + "string | undefined" + ], "path": "x-pack/plugins/security_solution/public/plugin.tsx", "deprecated": false, "trackAdoption": false @@ -2007,7 +2038,7 @@ "label": "ConfigType", "description": [], "signature": [ - "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; }> & { experimentalFeatures: ", + "Readonly<{ prebuiltRulesPackageVersion?: string | undefined; } & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; }> & { experimentalFeatures: ", "ExperimentalFeatures", "; }" ], diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 551484f337c397..e70de928b16896 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Security solution](https://github.com/orgs/elastic/teams/security-solut | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 113 | 0 | 76 | 29 | +| 115 | 0 | 75 | 29 | ## Client diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 66f2fb2bd830a3..08e18cd79b9a7c 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 4f7eeb70251f1c..db3279168e6dea 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index ef4d7ee698391a..aa246037a4cf60 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 99a7069af01ff5..106ebabcc4c1dd 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index a47cce6193024e..61cc97e81204da 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index d722c1a200cdc4..73dab132ff84e3 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 7006a5d92af142..cfa406bccfe488 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index e6b8896115c21b..1d8f1d3df1f0b7 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 5569fac17355e2..0a1f7b7fdcb760 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 00a7efa0ec5b16..d86369dfe67b3f 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index d6d8feba5926da..763979a5eff90a 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.devdocs.json b/api_docs/threat_intelligence.devdocs.json index bf7f44448dd5f2..ccce9277fb2406 100644 --- a/api_docs/threat_intelligence.devdocs.json +++ b/api_docs/threat_intelligence.devdocs.json @@ -502,6 +502,24 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "threatIntelligence", + "id": "def-public.SecuritySolutionPluginContext.blockList", + "type": "Object", + "tags": [], + "label": "blockList", + "description": [], + "signature": [ + "{ exceptionListApiClient: unknown; useSetUrlParams: () => (params: Record, replace?: boolean | undefined) => void; getFlyoutComponent: () => React.NamedExoticComponent<", + "BlockListFlyoutProps", + ">; getFormComponent: () => React.NamedExoticComponent<", + "BlockListFormProps", + ">; }" + ], + "path": "x-pack/plugins/threat_intelligence/public/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index e3627642912d51..24658e3241a422 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Protections Experience Team](https://github.com/orgs/elastic/teams/prot | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 34 | 0 | 14 | 3 | +| 35 | 0 | 15 | 5 | ## Client diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index c5dcf94a08e0aa..ea2a77e7bfbc21 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index e6eed985be513e..15e4275f94f507 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 2d586636a5af72..e77f1248943b6c 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -3757,6 +3757,21 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.controls", + "type": "Object", + "tags": [], + "label": "controls", + "description": [], + "signature": [ + "EuiDataGridToolBarAdditionalControlsOptions", + " | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index b256089e37b4e7..a436aa93a9e9f8 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 579 | 11 | 550 | 53 | +| 580 | 11 | 551 | 53 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 952084f31f9a67..34657422ae5e72 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index d3e8e5e14e5b93..5a81db30bd6854 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index b9df25a5e1e830..d57456df720397 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 03561e0fdc7d7b..f2ea75c43ffd7a 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 592368df78c689..35af51292c3cde 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 58171baf3245a5..53a1e31d8b3295 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 0c7f19b9648c8f..d5094c9442c1da 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 584f8992b8c94c..9be1a43cb976a9 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index edac590dfd7b45..56b138bd99d8e8 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 081b74cbb1b319..3015962d017577 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index c5e1e304b7429a..d7a967f6d0e586 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 87126c627ff911..9afe90971c5c5f 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 5264502819411c..7db8de3127c0ab 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 07ad87c971b23e..93af1b9bf05862 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 61f8d067732882..3f41d9c61c5005 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index c9724bca5b14a6..db0179826dda07 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index 6cbfbcd4501c68..81816a86889a3b 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 646694d739686a..ac72c300fb6004 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index dbf5f36e47f5da..61698abcaacb33 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index bfc3b09e9800a0..6ccc21fc6c089e 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-01-16 +date: 2023-01-18 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/docs/api-generated/cases/case-apis-passthru.asciidoc b/docs/api-generated/cases/case-apis-passthru.asciidoc index 80e8c7eb9cac7a..b95159d606ab18 100644 --- a/docs/api-generated/cases/case-apis-passthru.asciidoc +++ b/docs/api-generated/cases/case-apis-passthru.asciidoc @@ -160,6 +160,9 @@ Any modifications made to this file will be overwritten.

200

Indicates a successful call. case_response_properties +

401

+ Authorization information is missing or invalid. + 4xx_response





















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

Table of Contents

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

4xx_response - Unsuccessful cases API response Up

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

Case_response_properties_for_comments_inner - Up

diff --git a/docs/api-generated/connectors/connector-apis-passthru.asciidoc b/docs/api-generated/connectors/connector-apis-passthru.asciidoc index 03a22d9addfde4..ac2c18b4f2c295 100644 --- a/docs/api-generated/connectors/connector-apis-passthru.asciidoc +++ b/docs/api-generated/connectors/connector-apis-passthru.asciidoc @@ -18,13 +18,81 @@ Any modifications made to this file will be overwritten.

Connectors

Connectors

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

Path parameters

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

Consumes

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

Request body

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

Request headers

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

Return type

+ + + + +

Example data

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

Produces

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

Responses

+

200

+ Indicates a successful call. + connector_response_properties +

401

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

Produces

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

Responses

204

Indicates a successful call. +

401

+ Authorization information is missing or invalid. + createConnector_401_response +

404

+ Object is not found. + getConnector_404_response

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

Return type

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

Example data

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

Produces

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

Responses

200

Indicates a successful call. - getConnector_200_response + connector_response_properties +

401

+ Authorization information is missing or invalid. + createConnector_401_response +

404

+ Object is not found. + getConnector_404_response

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

Return type

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

200

Indicates a successful call. +

401

+ Authorization information is missing or invalid. + createConnector_401_response

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

Return type

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

200

Indicates a successful call. +

401

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

Path parameters

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

Consumes

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

Request body

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

Request headers

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

Return type

+ + + + +

Example data

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

Produces

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

Responses

+

200

+ Indicates a successful call. + connector_response_properties +

400

+ Indicates a bad request. + updateConnector_400_response +

401

+ Authorization information is missing or invalid. + createConnector_401_response +

404

+ Object is not found. + getConnector_404_response

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

Table of Contents

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

connector_types - Up

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

Alert_identifier_mapping - Alert identifier mapping Up

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

features - Up

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

Case_comment_mapping - Case comment mapping Up

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

getConnectorTypes_200_response_inner - Up

+

Case_description_mapping - Case description mapping Up

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

Case_identifier_mapping - Case identifier mapping Up

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

Case_name_mapping - Case name mapping Up

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

Connector_mappings_properties_for_a_Swimlane_connector - Connector mappings properties for a Swimlane connector Up

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

Create_connector_request_body_properties - Create connector request body properties Up

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

Get_connector_types_response_body_properties_inner - Up

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

getConnector_200_response - Up

+

Get_connectors_response_body_properties - Get connectors response body properties Up

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

Rule_name_mapping - Rule name mapping Up

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

Severity_mapping - Severity mapping Up

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

Update_connector_request_body_properties - Update connector request body properties Up

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

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

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

config_properties_index - Connector request properties for an index connector Up

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

config_properties_jira - Connector request properties for a Jira connector Up

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

config_properties_opsgenie - Connector request properties for an Opsgenie connector Up

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

config_properties_resilient - Connector request properties for a IBM Resilient connector Up

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

config_properties_servicenow - Connector request properties for a ServiceNow ITSM connector Up

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

config_properties_servicenow_itom - Connector request properties for a ServiceNow ITSM connector Up

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

config_properties_swimlane - Connector request properties for a Swimlane connector Up

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

connector_response_properties - Connector response properties Up

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

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

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

getConnectors_200_response_inner - Up

+

connector_response_properties_email - Connector response properties for an email connector Up

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

connector_response_properties_index - Connector response properties for an index connector Up

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

connector_response_properties_jira - Connector response properties for a Jira connector Up

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

connector_response_properties_opsgenie - Connector response properties for an Opsgenie connector Up

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

connector_response_properties_pagerduty - Connector response properties for a PagerDuty connector Up

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

connector_response_properties_resilient - Connector response properties for a IBM Resilient connector Up

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

connector_response_properties_serverlog - Connector response properties for a server log connector Up

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

connector_response_properties_servicenow - Connector response properties for a ServiceNow ITSM connector Up

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

connector_response_properties_servicenow_itom - Connector response properties for a ServiceNow ITOM connector Up

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

connector_response_properties_servicenow_sir - Connector response properties for a ServiceNow SecOps connector Up

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

connector_response_properties_slack - Connector response properties for a Slack connector Up

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

connector_response_properties_swimlane - Connector response properties for a Swimlane connector Up

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

connector_response_properties_teams - Connector response properties for a Microsoft Teams connector Up

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

connector_response_properties_tines - Connector response properties for a Tines connector Up

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

connector_response_properties_webhook - Connector response properties for a Webhook connector Up

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

connector_response_properties_xmatters - Connector response properties for an xMatters connector Up

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

connector_types - Connector types Up

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

createConnector_401_response - Up

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

create_connector_request_cases_webhook - Create Webhook - Case Managment connector request Up

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

create_connector_request_email - Create email connector request Up

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

create_connector_request_index - Create index connector request Up

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

create_connector_request_jira - Create Jira connector request Up

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

create_connector_request_opsgenie - Create Opsgenie connector request Up

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

create_connector_request_pagerduty - Create PagerDuty connector request Up

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

create_connector_request_resilient - Create IBM Resilient connector request Up

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

create_connector_request_serverlog - Create server log connector request Up

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

create_connector_request_servicenow - Create ServiceNow ITSM connector request Up

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

create_connector_request_servicenow_itom - Create ServiceNow ITOM connector request Up

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

create_connector_request_servicenow_sir - Create ServiceNow SecOps connector request Up

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

create_connector_request_slack - Create Slack connector request Up

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

create_connector_request_swimlane - Create Swimlane connector request Up

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

create_connector_request_teams - Create Microsoft Teams connector request Up

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

create_connector_request_tines - Create Tines connector request Up

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

create_connector_request_webhook - Create Webhook connector request Up

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

create_connector_request_xmatters - Create xMatters connector request Up

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

features - Up

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

getConnector_404_response - Up

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

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

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

secrets_properties_jira - Connector secrets properties for a Jira connector Up

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

secrets_properties_opsgenie - Connector secrets properties for an Opsgenie connector Up

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

secrets_properties_resilient - Connector secrets properties for IBM Resilient connector Up

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

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

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

secrets_properties_swimlane - Connector secrets properties for a Swimlane connector Up

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

updateConnector_400_response - Up

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

update_connector_request_index - Update index connector request Up

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

update_connector_request_jira - Update Jira connector request Up

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

update_connector_request_serverlog - Update server log connector request Up

+
+
+
name
String The display name for the connector.
+
+
+ + + diff --git a/docs/api-generated/rules/rule-apis-passthru.asciidoc b/docs/api-generated/rules/rule-apis-passthru.asciidoc index 0e9260905cbc8b..8ef9fdfacf5609 100644 --- a/docs/api-generated/rules/rule-apis-passthru.asciidoc +++ b/docs/api-generated/rules/rule-apis-passthru.asciidoc @@ -22,7 +22,9 @@ Any modifications made to this file will be overwritten.
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/_disable
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/_enable
  • get /s/{spaceId}/api/alerting/rules/_find
  • +
  • get /s/{spaceId}/api/alerting/_health
  • get /s/{spaceId}/api/alerting/rule/{ruleId}
  • +
  • get /s/{spaceId}/api/alerting/rule_types
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all
  • post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute
  • @@ -63,18 +65,30 @@ Any modifications made to this file will be overwritten. +

    Produces

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

    Responses

    204

    Indicates a successful call. +

    401

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

    404

    + Object is not found. + 404_response
    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_disable
    -
    Disable a rule. (disableRule)
    +
    Disables a rule. (disableRule)
    You must have all privileges for the appropriate Kibana features, depending on the consumer and rule_type_id of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features.

    Path parameters

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

    Produces

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

    Responses

    204

    Indicates a successful call. +

    401

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

    404

    + Object is not found. + 404_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_enable
    -
    Enable a rule. (enableRule)
    +
    Enables a rule. (enableRule)
    This API supports token-based authentication only. You must have all privileges for the appropriate Kibana features, depending on the consumer and rule_type_id of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features.

    Path parameters

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

    Produces

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

    Responses

    204

    Indicates a successful call. +

    401

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

    404

    + Object is not found. + 401_response

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

    Path parameters

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

    Return type

    + + + + +

    Example data

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

    Produces

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

    Responses

    +

    200

    + Indicates a successful call. + getAlertingHealth_200_response +

    401

    + Authorization information is missing or invalid. + 401_response

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

    Path parameters

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

    200

    Indicates a successful call. rule_response_properties +

    401

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

    404

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

    Path parameters

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

    Return type

    + + + + +

    Example data

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

    Produces

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

    Responses

    +

    200

    + Indicates a successful call. + +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute
    -
    Mute an alert. (muteAlert)
    +
    Mutes an alert. (muteAlert)
    You must have all privileges for the appropriate Kibana features, depending on the consumer and rule_type_id of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

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

    Produces

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

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all
    -
    Mute all alerts. (muteAllAlerts)
    +
    Mutes all alerts. (muteAllAlerts)
    This API snoozes the notifications for the rule indefinitely. The rule checks continue to occur but alerts will not trigger any actions. You must have all privileges for the appropriate Kibana features, depending on the consumer and rule_type_id of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

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

    Produces

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

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute
    -
    Unmute an alert. (unmuteAlert)
    +
    Unmutes an alert. (unmuteAlert)
    You must have all privileges for the appropriate Kibana features, depending on the consumer and rule_type_id of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

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

    Produces

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

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response

    Up
    post /s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all
    -
    Unmute all alerts. (unmuteAllAlerts)
    +
    Unmutes all alerts. (unmuteAllAlerts)
    If the rule has its notifications snoozed indefinitely, this API cancels the snooze. You must have all privileges for the appropriate Kibana features, depending on the consumer and rule_type_id of the rule. For example, the Management > Stack Rules feature, Analytics > Discover and Machine Learning features, Observability, and Security features. If the rule has actions, you must also have read privileges for the Management > Actions and Connectors feature.

    Path parameters

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

    Produces

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

    Responses

    204

    Indicates a successful call. +

    401

    + Authorization information is missing or invalid. + 401_response


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

    Table of Contents

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

    401_response - Unsuccessful rule API response Up

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

    404_response - Up

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

    actions_inner - Up

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

    getAlertingHealth_200_response - Up

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

    getAlertingHealth_200_response_alerting_framework_health - Up

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

    getAlertingHealth_200_response_alerting_framework_health_decryption_health - Up

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

    getAlertingHealth_200_response_alerting_framework_health_execution_health - Up

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

    getAlertingHealth_200_response_alerting_framework_health_read_health - Up

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

    getAlertingHealth_200_response_alerting_framework_heath_decryption_health - Up

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

    getRuleTypes_200_response_inner - Up

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

    getRuleTypes_200_response_inner_action_variables - Up

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

    getRuleTypes_200_response_inner_action_variables_context_inner - Up

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

    getRuleTypes_200_response_inner_action_variables_params_inner - Up

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

    getRuleTypes_200_response_inner_recovery_action_group - Up

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

    notify_when - Up

    Indicates how often alerts generate actions. Valid values include: onActionGroupChange: Actions run when the alert status changes; onActiveAlert: Actions run when the alert becomes active and at each check interval while the rule conditions are met; onThrottleInterval: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met.
    diff --git a/docs/api/actions-and-connectors/create.asciidoc b/docs/api/actions-and-connectors/create.asciidoc index cdaab61e5581e9..259c5dfee00af4 100644 --- a/docs/api/actions-and-connectors/create.asciidoc +++ b/docs/api/actions-and-connectors/create.asciidoc @@ -6,6 +6,12 @@ Creates a connector. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/actions/docs/openapi[open API specification]. For a preview, check out <>. +==== + [[create-connector-api-request]] === {api-request-title} @@ -121,9 +127,9 @@ the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`. `usesTableApi`:: -(Optional, string) Determines whether the connector uses the Table API or the +(Optional, boolean) Determines whether the connector uses the Table API or the Import Set API. This property is supported only for {sn-itsm} and {sn-sir} -connectors. +connectors. The default value is `true`. + NOTE: If this property is set to false, the Elastic application should be installed in {sn}. @@ -152,7 +158,7 @@ installed in {sn}. (Optional, object) Mapping for the alert ID. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -167,7 +173,7 @@ installed in {sn}. (Optional, object) Mapping for the case ID. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -182,7 +188,7 @@ installed in {sn}. (Optional, object) Mapping for the case name. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -197,7 +203,7 @@ installed in {sn}. (Optional, object) Mapping for the case comments. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -212,7 +218,7 @@ installed in {sn}. (Optional, object) Mapping for the case description. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -227,7 +233,7 @@ installed in {sn}. (Optional, object) Mapping for the name of the alert's rule. `fieldType`:::: -(Required, Object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. @@ -242,7 +248,7 @@ installed in {sn}. (Optional, object) Mapping for the severity. `fieldType`:::: -(Required, object) The type of the field in {swimlane}. +(Required, string) The type of the field in {swimlane}. `id`:::: (Required, string) The id of the field in {swimlane}. diff --git a/docs/api/actions-and-connectors/update.asciidoc b/docs/api/actions-and-connectors/update.asciidoc index 16fb327e61931f..b690d3fac995bb 100644 --- a/docs/api/actions-and-connectors/update.asciidoc +++ b/docs/api/actions-and-connectors/update.asciidoc @@ -6,6 +6,12 @@ Updates the attributes for a connector. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/actions/docs/openapi[open API specification]. For a preview, check out <>. +==== + [[update-connector-api-request]] === {api-request-title} diff --git a/docs/api/alerting/health.asciidoc b/docs/api/alerting/health.asciidoc index 1f0c8936419b5e..ce22ece799b76f 100644 --- a/docs/api/alerting/health.asciidoc +++ b/docs/api/alerting/health.asciidoc @@ -6,6 +6,12 @@ Retrieve the health status of the alerting framework. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/alerting/docs/openapi[open API specification]. For a preview, check out <>. +==== + [[get-alerting-framework-health-api-request]] === {api-request-title} diff --git a/docs/api/alerting/list_rule_types.asciidoc b/docs/api/alerting/list_rule_types.asciidoc index 1d37ff9e4dbcc6..32b4be086705a7 100644 --- a/docs/api/alerting/list_rule_types.asciidoc +++ b/docs/api/alerting/list_rule_types.asciidoc @@ -6,6 +6,13 @@ Retrieve a list of rule types that the user is authorized to access. +[NOTE] +==== +For the most up-to-date API details, refer to the +{kib-repo}/tree/{branch}/x-pack/plugins/alerting/docs/openapi[open API specification]. For a preview, check out <>. +==== + + [[list-rule-types-api-request]] === {api-request-title} diff --git a/docs/developer/advanced/upgrading-nodejs.asciidoc b/docs/developer/advanced/upgrading-nodejs.asciidoc index 348a43c0595ff2..16e8502450c17b 100644 --- a/docs/developer/advanced/upgrading-nodejs.asciidoc +++ b/docs/developer/advanced/upgrading-nodejs.asciidoc @@ -13,11 +13,11 @@ These files must be updated when upgrading Node.js: If they are not, and the update is urgent, you can skip this file and update it later once Docker Hub has been updated. - {kib-repo}blob/{branch}/.node-version[`.node-version`] - {kib-repo}blob/{branch}/.nvmrc[`.nvmrc`] - - {kib-repo}blob/{branch}/package.json[`package.json`] - The version is specified in the `engines.node` field. + - {kib-repo}blob/{branch}/package.json[`package.json`] - The version is specified in the `engines.node` field (if possible, also upgrade `@types/node` to match the new version, both under `devDependencies` and `resolutions`). - {kib-repo}blob/{branch}/WORKSPACE.bazel[`WORKSPACE.bazel`] - The version is specified in the `node_version` property. Besides this property, the list of files under `node_repositories` must be updated along with their respective SHA256 hashes. These can be found on the https://nodejs.org[nodejs.org] website. - Example for Node.js v16.18.1: https://nodejs.org/dist/v16.18.1/SHASUMS256.txt.asc + Example for Node.js v18.13.0: https://nodejs.org/dist/v18.13.0/SHASUMS256.txt.asc See PR {kib-repo}pull/128123[#128123] for an example of how the Node.js version has been upgraded previously. diff --git a/docs/maps/connect-to-ems.asciidoc b/docs/maps/connect-to-ems.asciidoc index f3e0709f7f506c..6a2ed12d9c5369 100644 --- a/docs/maps/connect-to-ems.asciidoc +++ b/docs/maps/connect-to-ems.asciidoc @@ -66,7 +66,7 @@ endif::[] [[elastic-maps-server-configuration]] ==== Configuration -{hosted-ems} reads properties from a configuration file in YAML format that is validated on startup. The location of this file is provided by the `EMS_PATH_CONF` environment variable and defaults to `/usr/src/app/server/config/elastic-maps-server.yml`. +{hosted-ems} reads properties from a configuration file in YAML format that is validated on startup. The location of this file is provided by the `EMS_PATH_CONF` container environment variable and defaults to `/usr/src/app/server/config/elastic-maps-server.yml`. This environment variable can be changed by making use of the `-e` docker flag of the start command. *General settings* diff --git a/fleet_packages.json b/fleet_packages.json index 2b938cc2e56c53..4bbbd5dd7a138d 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -20,7 +20,7 @@ [ { "name": "apm", - "version": "8.7.0-preview-1673519880", + "version": "8.7.0-preview-1673959201", "forceAlignStackVersion": true }, { diff --git a/package.json b/package.json index 3191e25901a51f..4a9a7336ef711c 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "makelogs": "node scripts/makelogs", "spec_to_console": "node scripts/spec_to_console", "start": "node scripts/kibana --dev", - "storybook": "node scripts/storybook", + "storybook": "node --openssl-legacy-provider scripts/storybook", "test:ftr": "node scripts/functional_tests", "test:ftr:runner": "node scripts/functional_test_runner", "test:ftr:server": "node scripts/functional_tests_server", @@ -68,11 +68,11 @@ "url": "https://github.com/elastic/kibana.git" }, "engines": { - "node": "16.18.1", + "node": "18.13.0", "yarn": "^1.22.19" }, "resolutions": { - "**/@types/node": "16.11.41", + "**/@types/node": "18.11.18", "**/chokidar": "^3.5.3", "**/deepmerge": "^4.2.2", "**/fast-deep-equal": "^3.1.1", @@ -622,7 +622,7 @@ "query-string": "^6.13.2", "rbush": "^3.0.1", "re-resizable": "^6.1.1", - "re2": "1.17.4", + "re2": "1.17.7", "react": "^17.0.2", "react-ace": "^7.0.5", "react-beautiful-dnd": "^13.1.0", @@ -683,7 +683,7 @@ "styled-components": "^5.1.0", "suricata-sid-db": "^1.0.2", "symbol-observable": "^1.2.0", - "tar": "^6.1.11", + "tar": "^6.1.13", "tinycolor2": "1.4.1", "tinygradient": "0.4.3", "ts-easing": "^0.2.0", @@ -936,7 +936,7 @@ "@types/multistream": "^4.1.0", "@types/mustache": "^0.8.31", "@types/nock": "^10.0.3", - "@types/node": "16.11.41", + "@types/node": "18.11.18", "@types/node-fetch": "^2.6.0", "@types/node-forge": "^1.3.1", "@types/nodemailer": "^6.4.0", @@ -983,7 +983,7 @@ "@types/styled-components": "^5.1.0", "@types/supertest": "^2.0.5", "@types/tapable": "^1.0.6", - "@types/tar": "^4.0.5", + "@types/tar": "^6.1.3", "@types/tempy": "^0.2.0", "@types/testing-library__jest-dom": "^5.14.5", "@types/tinycolor2": "^1.4.1", @@ -1158,7 +1158,7 @@ "simple-git": "^3.15.1", "sinon": "^7.4.2", "sort-package-json": "^1.53.1", - "source-map": "^0.7.3", + "source-map": "^0.7.4", "string-replace-loader": "^2.2.0", "style-loader": "^1.1.3", "stylelint": "^14.9.1", diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx index 3a15e5d58c841f..66297bf9a9b862 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx @@ -11,9 +11,7 @@ import { EuiHeader, EuiHeaderSection, EuiHeaderSectionItem, - EuiHeaderSectionItemButton, EuiHideFor, - EuiIcon, EuiShowFor, htmlIdGenerator, } from '@elastic/eui'; @@ -47,6 +45,7 @@ import { HeaderNavControls } from './header_nav_controls'; import { HeaderActionMenu } from './header_action_menu'; import { HeaderExtension } from './header_extension'; import { HeaderTopBanner } from './header_top_banner'; +import { HeaderMenuButton } from './header_menu_button'; export interface HeaderProps { kibanaVersion: string; @@ -188,7 +187,7 @@ export function Header({ }} customNavLink$={observables.customNavLink$} button={ - - - + forwardRef={toggleCollapsibleNavRef} + /> } /> diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx index f938608091ba6d..1d4813763a2010 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx @@ -200,10 +200,10 @@ export class HeaderHelpMenu extends Component { return globalHelpExtensionMenuLinks .sort((a, b) => b.priority - a.priority) .map((link, index) => { - const { linkType, content: text, href, ...rest } = link; + const { linkType, content: text, href, external, ...rest } = link; return createCustomLink(index, text, true, { href, - onClick: this.createOnClickHandler(href, navigateToUrl), + onClick: external ? undefined : this.createOnClickHandler(href, navigateToUrl), ...rest, }); }); @@ -264,7 +264,7 @@ export class HeaderHelpMenu extends Component { }); } case 'custom': { - const { linkType, content: text, href, ...rest } = link; + const { linkType, content: text, href, external, ...rest } = link; return createCustomLink(index, text, addSpacer, { href, onClick: this.createOnClickHandler(href, navigateToUrl), diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_menu_button.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_menu_button.tsx new file mode 100644 index 00000000000000..0e318594d60b85 --- /dev/null +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_menu_button.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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, { forwardRef, Ref } from 'react'; +import { EuiHeaderSectionItemButton, EuiIcon } from '@elastic/eui'; +import { EuiHeaderSectionItemButtonRef } from '@elastic/eui/src/components/header/header_section/header_section_item_button'; + +interface HeaderMenuButtonProps { + 'aria-controls': string; + 'aria-label': string; + 'aria-expanded': boolean; + 'aria-pressed': boolean; + 'data-test-subj': string; + onClick: () => void; + forwardRef: Ref | undefined; +} + +export const HeaderMenuButton = forwardRef( + (props: HeaderMenuButtonProps, ref: Ref | undefined) => { + return ( + + + + ); + } +); diff --git a/packages/core/chrome/core-chrome-browser/src/help_extension.ts b/packages/core/chrome/core-chrome-browser/src/help_extension.ts index f682a166ca29ce..fa9c9a1f29fd7c 100644 --- a/packages/core/chrome/core-chrome-browser/src/help_extension.ts +++ b/packages/core/chrome/core-chrome-browser/src/help_extension.ts @@ -92,6 +92,10 @@ export interface ChromeHelpExtensionMenuCustomLink extends ChromeHelpExtensionLi * Content of the button (in lieu of `children`) */ content: React.ReactNode; + /** + * Opens link in new tab + */ + external?: boolean; } /** @public */ diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts index 7a6d94c31f291e..20ebeb234b4791 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/aggregations/aggs_types/bucket_aggs.ts @@ -61,6 +61,36 @@ const existsSchema = s.object({ }) ), }); + +const rangeSchema = s.object({ + range: s.recordOf( + s.string(), + s.object({ + lt: s.maybe(s.string()), + lte: s.maybe(s.string()), + gt: s.maybe(s.string()), + gte: s.maybe(s.string()), + }) + ), +}); + +const termValueSchema = s.object({ + term: s.recordOf(s.string(), s.object({ value: s.string() })), +}); + +const nestedSchema = s.object({ + nested: s.object({ + path: s.string(), + query: s.object({ + bool: s.object({ + filter: s.arrayOf(termValueSchema), + }), + }), + }), +}); + +const arraySchema = s.arrayOf(s.oneOf([nestedSchema, rangeSchema])); + // TODO: it would be great if we could recursively build the schema since the aggregation have be nested // For more details see how the types are defined in the elasticsearch javascript client: // https://github.com/elastic/elasticsearch-js/blob/4ad5daeaf401ce8ebb28b940075e0a67e56ff9ce/src/api/typesWithBodyKey.ts#L5295 @@ -70,7 +100,7 @@ const boolSchema = s.object({ must_not: s.oneOf([termSchema, existsSchema]), }), s.object({ - filter: s.oneOf([termSchema, existsSchema]), + filter: s.oneOf([termSchema, existsSchema, arraySchema]), }), ]), }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts index 8072675b96b7e7..3c47ea01ecd720 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.test.ts @@ -652,6 +652,11 @@ describe('migrations v2 model', () => { expect(newState.controlState).toBe('WAIT_FOR_YELLOW_SOURCE'); expect(newState.sourceIndex.value).toBe('.kibana_7.invalid.0_001'); + expect(newState.aliases).toEqual({ + '.kibana': '.kibana_7.invalid.0_001', + '.kibana_7.11.0': '.kibana_7.11.0_001', + '.kibana_7.12.0': '.kibana_7.invalid.0_001', + }); }); test('INIT -> WAIT_FOR_YELLOW_SOURCE when migrating from a v2 migrations index (>= 7.11.0)', () => { @@ -683,6 +688,10 @@ describe('migrations v2 model', () => { expect(newState.sourceIndex.value).toBe('.kibana_7.11.0_001'); expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); + expect(newState.aliases).toEqual({ + '.kibana': '.kibana_7.11.0_001', + '.kibana_7.11.0': '.kibana_7.11.0_001', + }); }); test('INIT -> WAIT_FOR_YELLOW_SOURCE when migrating from a v1 migrations index (>= 6.5 < 7.11.0)', () => { @@ -701,6 +710,9 @@ describe('migrations v2 model', () => { expect(newState.sourceIndex.value).toBe('.kibana_3'); expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); + expect(newState.aliases).toEqual({ + '.kibana': '.kibana_3', + }); }); test('INIT -> LEGACY_SET_WRITE_BLOCK when migrating from a legacy index (>= 6.0.0 < 6.5)', () => { const res: ResponseType<'INIT'> = Either.right({ @@ -807,67 +819,6 @@ describe('migrations v2 model', () => { expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); }); - - describe('when upgrading to a new stack version', () => { - const unchangedMappingsState: State = { - ...baseState, - controlState: 'INIT', - kibanaVersion: '7.12.0', // new version! - currentAlias: '.kibana', - versionAlias: '.kibana_7.12.0', - versionIndex: '.kibana_7.11.0_001', - }; - it('INIT -> PREPARE_COMPATIBLE_MIGRATION when the mappings have not changed', () => { - const res: ResponseType<'INIT'> = Either.right({ - '.kibana_7.11.0_001': { - aliases: { - '.kibana': {}, - '.kibana_7.11.0': {}, - }, - mappings: indexMapping, - settings: {}, - }, - }); - const newState = model(unchangedMappingsState, res) as PrepareCompatibleMigration; - - expect(newState.controlState).toEqual('PREPARE_COMPATIBLE_MIGRATION'); - expect(newState.targetIndexRawMappings).toEqual({ - _meta: { - migrationMappingPropertyHashes: { - new_saved_object_type: '4a11183eee21e6fbad864f7a30b39ad0', - }, - }, - properties: { - new_saved_object_type: { - properties: { - value: { - type: 'text', - }, - }, - }, - }, - }); - expect(newState.versionAlias).toEqual('.kibana_7.12.0'); - expect(newState.currentAlias).toEqual('.kibana'); - // will point to - expect(newState.targetIndex).toEqual('.kibana_7.11.0_001'); - expect(newState.preTransformDocsActions).toEqual([ - { - add: { - alias: '.kibana_7.12.0', - index: '.kibana_7.11.0_001', - }, - }, - { - remove: { - alias: '.kibana_7.11.0', - index: '.kibana_7.11.0_001', - must_exist: true, - }, - }, - ]); - }); - }); }); }); @@ -1259,25 +1210,129 @@ describe('migrations v2 model', () => { }); describe('WAIT_FOR_YELLOW_SOURCE', () => { - const someMappings = { - properties: {}, - } as const; - const waitForYellowSourceState: WaitForYellowSourceState = { ...baseState, controlState: 'WAIT_FOR_YELLOW_SOURCE', - sourceIndex: Option.some('.kibana_3') as Option.Some, - sourceIndexMappings: someMappings, + sourceIndex: Option.some('.kibana_7.11.0_001') as Option.Some, + sourceIndexMappings: baseState.targetIndexMappings, + aliases: { + '.kibana': '.kibana_7.11.0_001', + '.kibana_7.11.0': '.kibana_7.11.0_001', + }, }; - test('WAIT_FOR_YELLOW_SOURCE -> CHECK_UNKNOWN_DOCUMENTS if action succeeds', () => { - const res: ResponseType<'WAIT_FOR_YELLOW_SOURCE'> = Either.right({}); - const newState = model(waitForYellowSourceState, res); - expect(newState.controlState).toEqual('CHECK_UNKNOWN_DOCUMENTS'); + describe('if action succeeds', () => { + test('it resets retry count and delay', () => { + const res: ResponseType<'WAIT_FOR_YELLOW_SOURCE'> = Either.right({}); + const testState = { + ...waitForYellowSourceState, + retryCount: 1, + retryDelay: 2000, + }; + const newState = model(testState, res); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); - expect(newState).toMatchObject({ - controlState: 'CHECK_UNKNOWN_DOCUMENTS', - sourceIndex: Option.some('.kibana_3'), + describe('and mappings match (diffMappings == false)', () => { + const unchangedMappingsState: State = { + ...waitForYellowSourceState, + controlState: 'WAIT_FOR_YELLOW_SOURCE', + kibanaVersion: '7.12.0', // new version! + currentAlias: '.kibana', + versionAlias: '.kibana_7.12.0', + versionIndex: '.kibana_7.11.0_001', + }; + + test('WAIT_FOR_YELLOW_SOURCE -> PREPARE_COMPATIBLE_MIGRATION', () => { + const res: ResponseType<'WAIT_FOR_YELLOW_SOURCE'> = Either.right({ + '.kibana_7.11.0_001': { + aliases: { + '.kibana': {}, + '.kibana_7.11.0': {}, + }, + mappings: indexMapping, + settings: {}, + }, + }); + const newState = model(unchangedMappingsState, res) as PrepareCompatibleMigration; + + expect(newState.controlState).toEqual('PREPARE_COMPATIBLE_MIGRATION'); + expect(newState.targetIndexRawMappings).toEqual({ + _meta: { + migrationMappingPropertyHashes: { + new_saved_object_type: '4a11183eee21e6fbad864f7a30b39ad0', + }, + }, + properties: { + new_saved_object_type: { + properties: { + value: { + type: 'text', + }, + }, + }, + }, + }); + expect(newState.versionAlias).toEqual('.kibana_7.12.0'); + expect(newState.currentAlias).toEqual('.kibana'); + // will point to + expect(newState.targetIndex).toEqual('.kibana_7.11.0_001'); + expect(newState.preTransformDocsActions).toEqual([ + { + add: { + alias: '.kibana_7.12.0', + index: '.kibana_7.11.0_001', + }, + }, + { + remove: { + alias: '.kibana_7.11.0', + index: '.kibana_7.11.0_001', + must_exist: true, + }, + }, + ]); + }); + }); + + describe('and mappings DO NOT match (diffMappings == true)', () => { + const actualMappings: IndexMapping = { + properties: { + new_saved_object_type: { + properties: { + value: { type: 'integer' }, + }, + }, + }, + _meta: { + migrationMappingPropertyHashes: { + new_saved_object_type: '5b11183eee21e6fbad864f7a30b39be1', + }, + }, + }; + + const changedMappingsState: State = { + ...waitForYellowSourceState, + controlState: 'WAIT_FOR_YELLOW_SOURCE', + kibanaVersion: '7.12.0', // new version! + currentAlias: '.kibana', + versionAlias: '.kibana_7.12.0', + versionIndex: '.kibana_7.11.0_001', + sourceIndexMappings: actualMappings, + }; + + test('WAIT_FOR_YELLOW_SOURCE -> CHECK_UNKNOWN_DOCUMENTS', () => { + const res: ResponseType<'WAIT_FOR_YELLOW_SOURCE'> = Either.right({}); + const newState = model(changedMappingsState, res); + expect(newState.controlState).toEqual('CHECK_UNKNOWN_DOCUMENTS'); + + expect(newState).toMatchObject({ + controlState: 'CHECK_UNKNOWN_DOCUMENTS', + sourceIndex: Option.some('.kibana_7.11.0_001'), + sourceIndexMappings: actualMappings, + }); + }); }); }); @@ -1297,22 +1352,6 @@ describe('migrations v2 model', () => { } `); }); - - test('WAIT_FOR_YELLOW_SOURCE -> CHECK_UNKNOWN_DOCUMENTS resets retry count and delay if action succeeds', () => { - const res: ResponseType<'WAIT_FOR_YELLOW_SOURCE'> = Either.right({}); - const testState = { - ...waitForYellowSourceState, - retryCount: 1, - retryDelay: 2000, - }; - const newState = model(testState, res); - expect(newState.controlState).toEqual('CHECK_UNKNOWN_DOCUMENTS'); - - expect(newState).toMatchObject({ - controlState: 'CHECK_UNKNOWN_DOCUMENTS', - sourceIndex: Option.some('.kibana_3'), - }); - }); }); describe('CHECK_UNKNOWN_DOCUMENTS', () => { diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts index 44de571c13f5d4..167a5d3771b789 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/model/model.ts @@ -158,48 +158,14 @@ export const model = (currentState: State, resW: ResponseType): }, ], }; - } else if ( - // source exists - Boolean(indices[source!]?.mappings?._meta?.migrationMappingPropertyHashes) && - // ...and mappings are unchanged - !diffMappings( - /* actual */ - indices[source!].mappings, - /* expected */ - stateP.targetIndexMappings - ) - ) { - const targetIndex = source!; - const sourceMappings = indices[source!].mappings; - - return { - ...stateP, - controlState: 'PREPARE_COMPATIBLE_MIGRATION', - sourceIndex: Option.none, - targetIndex, - targetIndexRawMappings: sourceMappings, - targetIndexMappings: mergeMigrationMappingPropertyHashes( - stateP.targetIndexMappings, - sourceMappings - ), - preTransformDocsActions: [ - // Point the version alias to the source index. This let's other Kibana - // instances know that a migration for the current version is "done" - // even though we may be waiting for document transformations to finish. - { add: { index: source!, alias: stateP.versionAlias } }, - ...buildRemoveAliasActions(source!, Object.keys(aliases), [ - stateP.currentAlias, - stateP.versionAlias, - ]), - ], - versionIndexReadyActions: Option.none, - }; } else if ( // If the `.kibana` alias exists source != null ) { + // CHECKPOINT here we decide to go for yellow source return { ...stateP, + aliases, controlState: 'WAIT_FOR_YELLOW_SOURCE', sourceIndex: Option.some(source!) as Option.Some, sourceIndexMappings: indices[source!].mappings, @@ -481,10 +447,50 @@ export const model = (currentState: State, resW: ResponseType): } else if (stateP.controlState === 'WAIT_FOR_YELLOW_SOURCE') { const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { - return { - ...stateP, - controlState: 'CHECK_UNKNOWN_DOCUMENTS', - }; + // check the existing mappings to see if we can avoid reindexing + if ( + // source exists + Boolean(stateP.sourceIndexMappings._meta?.migrationMappingPropertyHashes) && + // ...and mappings are unchanged + !diffMappings( + /* actual */ + stateP.sourceIndexMappings, + /* expected */ + stateP.targetIndexMappings + ) + ) { + // The source index .kibana is pointing to. E.g: ".xx8.7.0_001" + const source = stateP.sourceIndex.value; + + return { + ...stateP, + controlState: 'PREPARE_COMPATIBLE_MIGRATION', + sourceIndex: Option.none, + targetIndex: source!, + targetIndexRawMappings: stateP.sourceIndexMappings, + targetIndexMappings: mergeMigrationMappingPropertyHashes( + stateP.targetIndexMappings, + stateP.sourceIndexMappings + ), + preTransformDocsActions: [ + // Point the version alias to the source index. This let's other Kibana + // instances know that a migration for the current version is "done" + // even though we may be waiting for document transformations to finish. + { add: { index: source!, alias: stateP.versionAlias } }, + ...buildRemoveAliasActions(source!, Object.keys(stateP.aliases), [ + stateP.currentAlias, + stateP.versionAlias, + ]), + ], + versionIndexReadyActions: Option.none, + }; + } else { + // the mappings have changed, but changes might still be compatible + return { + ...stateP, + controlState: 'CHECK_UNKNOWN_DOCUMENTS', + }; + } } else if (Either.isLeft(res)) { const left = res.left; if (isTypeof(left, 'index_not_yellow_timeout')) { diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/state.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/state.ts index e3873122329fd4..f3a59fadf2dd42 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/state.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/state.ts @@ -215,6 +215,7 @@ export interface WaitForYellowSourceState extends BaseState { readonly controlState: 'WAIT_FOR_YELLOW_SOURCE'; readonly sourceIndex: Option.Some; readonly sourceIndexMappings: IndexMapping; + readonly aliases: Record; } export interface CheckUnknownDocumentsState extends BaseState { diff --git a/packages/kbn-cases-components/.storybook/main.js b/packages/kbn-cases-components/.storybook/main.js new file mode 100644 index 00000000000000..8dc3c5d1518f4d --- /dev/null +++ b/packages/kbn-cases-components/.storybook/main.js @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = require('@kbn/storybook').defaultConfig; diff --git a/packages/kbn-cases-components/README.md b/packages/kbn-cases-components/README.md index bc60e2fba7fe59..cea88ceb6b37ba 100644 --- a/packages/kbn-cases-components/README.md +++ b/packages/kbn-cases-components/README.md @@ -13,3 +13,34 @@ import { Status, CaseStatuses } from '@kbn/cases-components'; ``` + +### Tooltip + +The component renders the tooltip with case details on hover of an Element. Usage: + +``` +import { Tooltip, CaseStatuses } from '@kbn/cases-components'; +import type { CaseTooltipContentProps, CaseTooltipProps } from '@kbn/cases-components'; + +const tooltipContent: CaseTooltipContentProps = { + title: 'Case title', + description: 'Case description', + createdAt: '2020-02-19T23:06:33.798Z', + createdBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + totalComments: 1, + status: CaseStatuses.open, +} + +const tooltipProps: CaseTooltipProps = { + loading: false, + content: tooltipContent, + className: 'customClass', +}; + + + This is a demo span + +``` diff --git a/packages/kbn-cases-components/index.ts b/packages/kbn-cases-components/index.ts index 47a7a298f0e1d7..9605b0267a25f3 100644 --- a/packages/kbn-cases-components/index.ts +++ b/packages/kbn-cases-components/index.ts @@ -9,3 +9,5 @@ export { Status } from './src/status/status'; export { CaseStatuses } from './src/status/types'; export { getStatusConfiguration } from './src/status/config'; +export { Tooltip } from './src/tooltip/tooltip'; +export type { CaseTooltipProps, CaseTooltipContentProps } from './src/tooltip/types'; diff --git a/packages/kbn-cases-components/src/__stories__/tooltip.stories.tsx b/packages/kbn-cases-components/src/__stories__/tooltip.stories.tsx new file mode 100644 index 00000000000000..673e17db75bee0 --- /dev/null +++ b/packages/kbn-cases-components/src/__stories__/tooltip.stories.tsx @@ -0,0 +1,103 @@ +/* + * Copyright 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 { I18nProvider } from '@kbn/i18n-react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import { CaseStatuses } from '../status/types'; +import { Tooltip } from '../tooltip/tooltip'; +import type { CaseTooltipProps, CaseTooltipContentProps } from '../tooltip/types'; + +const sampleText = 'This is a test span element!!'; +const TestSpan = () => ( + + {sampleText} + +); + +const tooltipContent: CaseTooltipContentProps = { + title: 'Unusual process identified', + description: 'There was an unusual process while adding alerts to existing case.', + createdAt: '2020-02-19T23:06:33.798Z', + createdBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + totalComments: 10, + status: CaseStatuses.open, +}; + +const tooltipProps: CaseTooltipProps = { + children: TestSpan, + loading: false, + content: tooltipContent, +}; + +const longTitle = `Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry standard dummy text ever since the 1500s!! Lorem!!!`; + +const longDescription = `Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer + took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, + but also the leap into electronic typesetting, remaining essentially unchanged.`; + +const Template = (args: CaseTooltipProps) => ( + + + + + +); + +export default { + title: 'CaseTooltip', + component: Template, +} as ComponentMeta; + +export const Default: ComponentStory = Template.bind({}); +Default.args = { ...tooltipProps }; + +export const LoadingState: ComponentStory = Template.bind({}); +LoadingState.args = { ...tooltipProps, loading: true }; + +export const LongTitle: ComponentStory = Template.bind({}); +LongTitle.args = { ...tooltipProps, content: { ...tooltipContent, title: longTitle } }; + +export const LongDescription: ComponentStory = Template.bind({}); +LongDescription.args = { + ...tooltipProps, + content: { ...tooltipContent, description: longDescription }, +}; + +export const InProgressStatus: ComponentStory = Template.bind({}); +InProgressStatus.args = { + ...tooltipProps, + content: { ...tooltipContent, status: CaseStatuses['in-progress'] }, +}; + +export const ClosedStatus: ComponentStory = Template.bind({}); +ClosedStatus.args = { + ...tooltipProps, + content: { ...tooltipContent, status: CaseStatuses.closed }, +}; + +export const NoUserInfo: ComponentStory = Template.bind({}); +NoUserInfo.args = { ...tooltipProps, content: { ...tooltipContent, createdBy: {} } }; + +export const FullName: ComponentStory = Template.bind({}); +FullName.args = { + ...tooltipProps, + content: { ...tooltipContent, createdBy: { fullName: 'Elastic User' } }, +}; + +export const LongUserName: ComponentStory = Template.bind({}); +LongUserName.args = { + ...tooltipProps, + content: { ...tooltipContent, createdBy: { fullName: 'LoremIpsumElasticUser WithALongSurname' } }, +}; diff --git a/packages/kbn-cases-components/src/tooltip/icon_with_count.test.tsx b/packages/kbn-cases-components/src/tooltip/icon_with_count.test.tsx new file mode 100644 index 00000000000000..99a777fd91bb9e --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/icon_with_count.test.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 } from '@testing-library/react'; + +import { IconWithCount } from './icon_with_count'; + +describe('IconWithCount', () => { + it('renders component correctly', () => { + const res = render(); + + expect(res.getByTestId('comment-count-icon')).toBeInTheDocument(); + }); + + it('renders count correctly', () => { + const res = render(); + + expect(res.getByText(100)).toBeInTheDocument(); + }); +}); diff --git a/packages/kbn-cases-components/src/tooltip/icon_with_count.tsx b/packages/kbn-cases-components/src/tooltip/icon_with_count.tsx new file mode 100644 index 00000000000000..80e8c8c9a7520d --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/icon_with_count.tsx @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText } from '@elastic/eui'; +import React from 'react'; + +export const IconWithCount = React.memo<{ + count: number; + icon: string; +}>(({ count, icon }) => ( + + + + + + {count} + + +)); + +IconWithCount.displayName = 'IconWithCount'; diff --git a/packages/kbn-cases-components/src/tooltip/skeleton.tsx b/packages/kbn-cases-components/src/tooltip/skeleton.tsx new file mode 100644 index 00000000000000..f0c78e2a2e215d --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/skeleton.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { EuiFlexItem, EuiLoadingContent, EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; + +const SkeletonComponent: React.FC = () => { + return ( + + + + + + + ); +}; + +SkeletonComponent.displayName = 'Skeleton'; + +export const Skeleton = SkeletonComponent; diff --git a/packages/kbn-cases-components/src/tooltip/tooltip.test.tsx b/packages/kbn-cases-components/src/tooltip/tooltip.test.tsx new file mode 100644 index 00000000000000..a4573db2f8ccd3 --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/tooltip.test.tsx @@ -0,0 +1,175 @@ +/* + * Copyright 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, fireEvent } from '@testing-library/react'; +import { I18nProvider } from '@kbn/i18n-react'; + +import { Tooltip } from './tooltip'; +import { CaseStatuses } from '../status/types'; +import type { CaseTooltipContentProps, CaseTooltipProps } from './types'; + +const elasticUser = { + fullName: 'Elastic User', + username: 'elastic', +}; + +const sampleText = 'This is a test span element!!'; +const TestSpan = () => {sampleText}; + +const tooltipContent: CaseTooltipContentProps = { + title: 'Another horrible breach!!', + description: 'Demo case banana Issue', + createdAt: '2020-02-19T23:06:33.798Z', + createdBy: elasticUser, + totalComments: 1, + status: CaseStatuses.open, +}; + +const tooltipProps: CaseTooltipProps = { + children: TestSpan, + loading: false, + content: tooltipContent, +}; + +describe('Tooltip', () => { + it('renders correctly', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByTestId('cases-components-tooltip')).toBeInTheDocument(); + }); + + it('renders custom test subject correctly', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByTestId('custom-data-test')).toBeInTheDocument(); + }); + + it('renders loading state correctly', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByTestId('tooltip-loading-content')).toBeInTheDocument(); + }); + + it('renders title correctly', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByText(tooltipContent.title)).toBeInTheDocument(); + }); + + it('renders description correctly', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByText(tooltipContent.description)).toBeInTheDocument(); + }); + + it('renders icon', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByTestId('comment-count-icon')).toBeInTheDocument(); + }); + + it('renders comment count', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByText(tooltipContent.totalComments)).toBeInTheDocument(); + }); + + it('renders correct status', async () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByText('Closed')).toBeInTheDocument(); + }); + + it('renders full name when no username available', async () => { + const newUser = { + fullName: 'New User', + }; + + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(await res.findByTestId('tooltip-username')).toBeInTheDocument(); + expect(await res.findByText(newUser.fullName)).toBeInTheDocument(); + }); + + it('does not render username when no username or full name available', () => { + const res = render( + + + + + + ); + + fireEvent.mouseOver(res.getByTestId('sample-span')); + expect(res.queryByTestId('tooltip-username')).not.toBeInTheDocument(); + }); +}); diff --git a/packages/kbn-cases-components/src/tooltip/tooltip.tsx b/packages/kbn-cases-components/src/tooltip/tooltip.tsx new file mode 100644 index 00000000000000..7ac199ff58f244 --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/tooltip.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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, { memo } from 'react'; +import { EuiToolTip } from '@elastic/eui'; + +import { TooltipContent } from './tooltip_content'; +import type { CaseTooltipProps } from './types'; +import { Skeleton } from './skeleton'; + +const CaseTooltipComponent = React.memo((props) => { + const { dataTestSubj, children, loading = false, className = '', content } = props; + + return ( + : } + > + <>{children} + + ); +}); + +CaseTooltipComponent.displayName = 'Tooltip'; + +export const Tooltip = memo(CaseTooltipComponent); diff --git a/packages/kbn-cases-components/src/tooltip/tooltip_content.tsx b/packages/kbn-cases-components/src/tooltip/tooltip_content.tsx new file mode 100644 index 00000000000000..262365fba3ae43 --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/tooltip_content.tsx @@ -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 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, { memo } from 'react'; +import { FormattedRelative } from '@kbn/i18n-react'; +import { EuiFlexGroup, EuiFlexItem, EuiText, EuiHorizontalRule } from '@elastic/eui'; + +import { Status } from '../status/status'; +import { CaseStatuses } from '../status/types'; +import { IconWithCount } from './icon_with_count'; +import { getTruncatedText } from './utils'; +import * as i18n from './translations'; +import type { CaseTooltipContentProps } from './types'; + +const TITLE_TRUNCATE_LENGTH = 35; +const DESCRIPTION_TRUNCATE_LENGTH = 80; +const USER_TRUNCATE_LENGTH = 15; + +const CaseTooltipContentComponent = React.memo( + ({ title, description, status, totalComments, createdAt, createdBy }) => ( + <> + + + + + + + + + + + {getTruncatedText(title, TITLE_TRUNCATE_LENGTH)} + + + + + {getTruncatedText(description, DESCRIPTION_TRUNCATE_LENGTH)} + + + + + + + {status === CaseStatuses.closed ? i18n.CLOSED : i18n.OPENED}{' '} + {' '} + {createdBy.username || createdBy.fullName ? ( + <> + {i18n.BY}{' '} + + {getTruncatedText( + createdBy.username ?? createdBy.fullName ?? '', + USER_TRUNCATE_LENGTH + )} + + + ) : null} + + + ) +); + +CaseTooltipContentComponent.displayName = 'TooltipContent'; + +export const TooltipContent = memo(CaseTooltipContentComponent); diff --git a/packages/kbn-cases-components/src/tooltip/translations.ts b/packages/kbn-cases-components/src/tooltip/translations.ts new file mode 100644 index 00000000000000..b9223ba0322060 --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/translations.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { i18n } from '@kbn/i18n'; + +export const OPENED = i18n.translate('cases.components.tooltip.opened', { + defaultMessage: 'Opened', +}); + +export const CLOSED = i18n.translate('cases.components.tooltip.closed', { + defaultMessage: 'Closed', +}); + +export const BY = i18n.translate('cases.components.tooltip.by', { + defaultMessage: 'by', +}); diff --git a/packages/kbn-cases-components/src/tooltip/types.ts b/packages/kbn-cases-components/src/tooltip/types.ts new file mode 100644 index 00000000000000..dea545ab8f40bb --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/types.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { CaseStatuses } from '../status/types'; +export interface CaseTooltipContentProps { + title: string; + description: string; + status: CaseStatuses; + totalComments: number; + createdAt: string; + createdBy: { username?: string; fullName?: string }; +} + +export interface CaseTooltipProps { + children: React.ReactNode; + content: CaseTooltipContentProps; + dataTestSubj?: string; + className?: string; + loading?: boolean; +} diff --git a/packages/kbn-cases-components/src/tooltip/utils.test.ts b/packages/kbn-cases-components/src/tooltip/utils.test.ts new file mode 100644 index 00000000000000..b9d5657ab0e3e0 --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/utils.test.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 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 { getTruncatedText } from './utils'; + +describe('getTruncatedText', () => { + it('should return truncated text correctly', () => { + const sampleText = 'This is a sample text!!'; + const res = getTruncatedText(sampleText, 4); + + expect(res).toEqual('This...'); + }); + + it('should return original text if text is empty', () => { + const res = getTruncatedText('', 4); + + expect(res).toEqual(''); + }); + + it('should return empty text if text is empty', () => { + const res = getTruncatedText('', 10); + + expect(res).toEqual(''); + }); + + it('should return original text if truncate length is negative', () => { + const sampleText = 'This is a sample text!!'; + const res = getTruncatedText(sampleText, -4); + + expect(res).toEqual(sampleText); + }); + + it('should return original text if truncate length is zero', () => { + const sampleText = 'This is a sample text!!'; + const res = getTruncatedText(sampleText, 0); + + expect(res).toEqual(sampleText); + }); + + it('should return original text if text is smaller than truncate length number', () => { + const sampleText = 'This is a sample text!!'; + const res = getTruncatedText(sampleText, 50); + + expect(res).toEqual(sampleText); + }); +}); diff --git a/packages/kbn-cases-components/src/tooltip/utils.ts b/packages/kbn-cases-components/src/tooltip/utils.ts new file mode 100644 index 00000000000000..95b43e62c36e87 --- /dev/null +++ b/packages/kbn-cases-components/src/tooltip/utils.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const getTruncatedText = (text: string, truncateLength: number): string => { + if (truncateLength <= 0 || text.length <= truncateLength) { + return text; + } + + return text.slice(0, truncateLength).trim().concat('...'); +}; diff --git a/packages/kbn-cases-components/tsconfig.json b/packages/kbn-cases-components/tsconfig.json index 3d7519541dc8d3..09abcbdb81a3e5 100644 --- a/packages/kbn-cases-components/tsconfig.json +++ b/packages/kbn-cases-components/tsconfig.json @@ -14,6 +14,7 @@ ], "kbn_references": [ "@kbn/i18n", + "@kbn/i18n-react", ], "exclude": [ "target/**/*", diff --git a/packages/kbn-cli-dev-mode/src/watcher.ts b/packages/kbn-cli-dev-mode/src/watcher.ts index 17ab0af5a7db10..bf5063ac364a47 100644 --- a/packages/kbn-cli-dev-mode/src/watcher.ts +++ b/packages/kbn-cli-dev-mode/src/watcher.ts @@ -24,8 +24,8 @@ const nonPackageMatcher = makeMatcher([ 'src/**', '!src/{dev,fixtures}/**', 'x-pack/plugins/**', - '!x-pack/plugins/screenshotting/chromium', - '!x-pack/plugins/canvas/canvas_plugin_src', + '!x-pack/plugins/screenshotting/chromium/**', + '!x-pack/plugins/canvas/shareable_runtime/**', ]); export interface Options { diff --git a/packages/kbn-es-query/index.ts b/packages/kbn-es-query/index.ts index a2b529d005ea04..b5358fbfa016cf 100644 --- a/packages/kbn-es-query/index.ts +++ b/packages/kbn-es-query/index.ts @@ -51,6 +51,7 @@ export type { export { buildEsQuery, buildQueryFromFilters, + filterToQueryDsl, decorateQuery, luceneStringToDsl, migrateFilter, diff --git a/packages/kbn-es-query/src/es_query/from_filters.ts b/packages/kbn-es-query/src/es_query/from_filters.ts index 029dcf3e15dd8e..6896825db93aba 100644 --- a/packages/kbn-es-query/src/es_query/from_filters.ts +++ b/packages/kbn-es-query/src/es_query/from_filters.ts @@ -71,32 +71,18 @@ export const buildQueryFromFilters = ( ignoreFilterIfFieldNotInIndex: false, } ): BoolQuery => { - const { ignoreFilterIfFieldNotInIndex = false, nestedIgnoreUnmapped } = options; + const { ignoreFilterIfFieldNotInIndex = false } = options; const filters = inputFilters.filter((filter) => filter && !isFilterDisabled(filter)); - const indexPatterns = Array.isArray(inputDataViews) ? inputDataViews : [inputDataViews]; - - const findIndexPattern = (id: string | undefined) => { - return indexPatterns.find((index) => index?.id === id) || indexPatterns[0]; - }; const filtersToESQueries = (negate: boolean) => { return filters .filter((f) => !!f) .filter(filterNegate(negate)) .filter((filter) => { - const indexPattern = findIndexPattern(filter.meta?.index); + const indexPattern = findIndexPattern(inputDataViews, filter.meta?.index); return !ignoreFilterIfFieldNotInIndex || filterMatchesIndex(filter, indexPattern); }) - .map((filter) => { - const indexPattern = findIndexPattern(filter.meta?.index); - const migratedFilter = migrateFilter(filter, indexPattern); - return fromNestedFilter(migratedFilter, indexPattern, { - ignoreUnmapped: nestedIgnoreUnmapped, - }); - }) - .map((filter) => fromCombinedFilter(filter, inputDataViews, options)) - .map(cleanFilter) - .map(translateToQuery); + .map((filter) => filterToQueryDsl(filter, inputDataViews, options)); }; return { @@ -106,3 +92,24 @@ export const buildQueryFromFilters = ( must_not: filtersToESQueries(true), }; }; + +function findIndexPattern( + inputDataViews: DataViewBase | DataViewBase[] | undefined, + id: string | undefined +) { + const dataViews = Array.isArray(inputDataViews) ? inputDataViews : [inputDataViews]; + return dataViews.find((index) => index?.id === id) ?? dataViews[0]; +} + +export function filterToQueryDsl( + filter: Filter, + inputDataViews: DataViewBase | DataViewBase[] | undefined, + options: EsQueryFiltersConfig = {} +) { + const indexPattern = findIndexPattern(inputDataViews, filter.meta?.index); + const migratedFilter = migrateFilter(filter, indexPattern); + const nestedFilter = fromNestedFilter(migratedFilter, indexPattern, options); + const combinedFilter = fromCombinedFilter(nestedFilter, inputDataViews, options); + const cleanedFilter = cleanFilter(combinedFilter); + return translateToQuery(cleanedFilter); +} diff --git a/packages/kbn-es-query/src/es_query/from_nested_filter.test.ts b/packages/kbn-es-query/src/es_query/from_nested_filter.test.ts index 624220f4c1a6c1..1ae8f8d3a4735c 100644 --- a/packages/kbn-es-query/src/es_query/from_nested_filter.test.ts +++ b/packages/kbn-es-query/src/es_query/from_nested_filter.test.ts @@ -42,7 +42,7 @@ describe('fromNestedFilter', function () { it('should allow to configure ignore_unmapped', () => { const field = getField('nestedField.child'); const filter = buildPhraseFilter(field!, 'foo', indexPattern); - const result = fromNestedFilter(filter, indexPattern, { ignoreUnmapped: true }); + const result = fromNestedFilter(filter, indexPattern, { nestedIgnoreUnmapped: true }); expect(result).toEqual({ meta: { index: 'logstash-*', diff --git a/packages/kbn-es-query/src/es_query/from_nested_filter.ts b/packages/kbn-es-query/src/es_query/from_nested_filter.ts index f646c531f318ea..aad9ebea2b1443 100644 --- a/packages/kbn-es-query/src/es_query/from_nested_filter.ts +++ b/packages/kbn-es-query/src/es_query/from_nested_filter.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { EsQueryFiltersConfig } from '../..'; import { getFilterField, cleanFilter, Filter } from '../filters'; import { DataViewBase } from './types'; import { getDataViewFieldSubtypeNested } from '../utils'; @@ -14,7 +15,7 @@ import { getDataViewFieldSubtypeNested } from '../utils'; export const fromNestedFilter = ( filter: Filter, indexPattern?: DataViewBase, - config: { ignoreUnmapped?: boolean } = {} + config: EsQueryFiltersConfig = {} ) => { if (!indexPattern) return filter; @@ -40,8 +41,8 @@ export const fromNestedFilter = ( nested: { path: subTypeNested.nested.path, query: query.query || query, - ...(typeof config.ignoreUnmapped === 'boolean' && { - ignore_unmapped: config.ignoreUnmapped, + ...(typeof config.nestedIgnoreUnmapped === 'boolean' && { + ignore_unmapped: config.nestedIgnoreUnmapped, }), }, }, diff --git a/packages/kbn-es-query/src/es_query/index.ts b/packages/kbn-es-query/src/es_query/index.ts index 5d3e44f597cbd0..1dca3a5524cfb1 100644 --- a/packages/kbn-es-query/src/es_query/index.ts +++ b/packages/kbn-es-query/src/es_query/index.ts @@ -10,7 +10,7 @@ export { migrateFilter } from './migrate_filter'; export type { EsQueryFiltersConfig } from './from_filters'; export type { EsQueryConfig } from './build_es_query'; export { buildEsQuery } from './build_es_query'; -export { buildQueryFromFilters } from './from_filters'; +export { buildQueryFromFilters, filterToQueryDsl } from './from_filters'; export { luceneStringToDsl } from './lucene_string_to_dsl'; export { decorateQuery } from './decorate_query'; export { diff --git a/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts b/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts index b57855bf472e87..7c33cf36e07c01 100644 --- a/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts +++ b/packages/kbn-es-query/src/filters/helpers/update_filter.test.ts @@ -127,7 +127,7 @@ describe('updateFilter', () => { meta: { alias: '', index: 'index1', - params: { query: 0 }, + params: { query: undefined }, key: 'test-field', negate: true, type: 'phrase', diff --git a/packages/kbn-es-query/src/filters/helpers/update_filter.ts b/packages/kbn-es-query/src/filters/helpers/update_filter.ts index 1ebe43cbdbfd0d..ea61545d557be9 100644 --- a/packages/kbn-es-query/src/filters/helpers/update_filter.ts +++ b/packages/kbn-es-query/src/filters/helpers/update_filter.ts @@ -79,7 +79,7 @@ function updateWithIsOperator( ...filter.meta, negate: operator?.negate, type: operator?.type, - params: { ...filter.meta.params, query: safeParams }, + params: { ...filter.meta.params, query: params }, value: undefined, }, query: { match_phrase: { [filter.meta.key!]: safeParams ?? '' } }, diff --git a/packages/kbn-i18n/src/core/i18n.test.ts b/packages/kbn-i18n/src/core/i18n.test.ts index dfea790f129b5e..f9a6535d881ee5 100644 --- a/packages/kbn-i18n/src/core/i18n.test.ts +++ b/packages/kbn-i18n/src/core/i18n.test.ts @@ -662,13 +662,13 @@ describe('I18n engine', () => { i18n.translate('a.short', { values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, } as any) - ).toBe('Coupon expires at 6:40 PM'); + ).toBe('Coupon expires at 6:40 PM'); expect( i18n.translate('a.medium', { values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, } as any) - ).toBe('Coupon expires at 6:40:30 PM'); + ).toBe('Coupon expires at 6:40:30 PM'); }); test('should format default messages with time formatter', () => { @@ -679,14 +679,14 @@ describe('I18n engine', () => { defaultMessage: 'Coupon expires at {expires, time, short}', values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, }) - ).toBe('Coupon expires at 6:40 PM'); + ).toBe('Coupon expires at 6:40 PM'); expect( i18n.translate('foo', { defaultMessage: 'Coupon expires at {expires, time, medium}', values: { expires: new Date(2018, 5, 20, 18, 40, 30, 50) }, }) - ).toBe('Coupon expires at 6:40:30 PM'); + ).toBe('Coupon expires at 6:40:30 PM'); }); test('should format message with a custom format', () => { diff --git a/packages/kbn-monaco/BUILD.bazel b/packages/kbn-monaco/BUILD.bazel index 8d13702e74588f..2ca10b073fd18f 100644 --- a/packages/kbn-monaco/BUILD.bazel +++ b/packages/kbn-monaco/BUILD.bazel @@ -56,9 +56,11 @@ webpack_cli( env = select({ "//:dist": { "NODE_ENV": "production", + "NODE_OPTIONS": "--openssl-legacy-provider", }, "//conditions:default": { "NODE_ENV": "development", + "NODE_OPTIONS": "--openssl-legacy-provider", }, }), visibility = ["//visibility:public"], diff --git a/packages/kbn-optimizer/src/optimizer/observe_worker.ts b/packages/kbn-optimizer/src/optimizer/observe_worker.ts index cf250a7deef6e0..49c150fbf2dcbd 100644 --- a/packages/kbn-optimizer/src/optimizer/observe_worker.ts +++ b/packages/kbn-optimizer/src/optimizer/observe_worker.ts @@ -60,6 +60,7 @@ function usingWorkerProc(config: OptimizerConfig, fn: (proc: ChildProcess) => (): ProcResource => { const proc = fork(require.resolve('../worker/run_worker'), [], { execArgv: [ + '--openssl-legacy-provider', `--require=@kbn/babel-register/install`, ...(inspectFlag && config.inspectWorkers ? [`${inspectFlag}=${inspectPortCounter++}`] diff --git a/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts b/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts index c10a2d3680c30c..9957d3474e5494 100644 --- a/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts +++ b/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts @@ -124,6 +124,17 @@ export class RepoSourceClassifier { } } + /** + * Apply screenshotting specific rules + * @param root the root dir within the screenshotting plugin + * @returns a type, or undefined if the file should be classified as a standard file + */ + private classifyScreenshotting(root: string): ModuleType | undefined { + if (root === 'chromium') { + return 'non-package'; + } + } + /** * Determine the "type" of a file */ @@ -195,6 +206,13 @@ export class RepoSourceClassifier { } } + if (pkgId === '@kbn/screenshotting-plugin') { + const type = this.classifyScreenshotting(root); + if (type) { + return type; + } + } + if (root === 'public' || root === 'static') { return 'browser package'; } diff --git a/packages/kbn-ui-shared-deps-npm/BUILD.bazel b/packages/kbn-ui-shared-deps-npm/BUILD.bazel index 2b49f1e5a92f17..a45f183ff80ef4 100644 --- a/packages/kbn-ui-shared-deps-npm/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-npm/BUILD.bazel @@ -83,9 +83,11 @@ webpack_cli( env = select({ "//:dist": { "NODE_ENV": "production", + "NODE_OPTIONS": "--openssl-legacy-provider", }, "//conditions:default": { "NODE_ENV": "development", + "NODE_OPTIONS": "--openssl-legacy-provider", }, }) ) diff --git a/packages/kbn-ui-shared-deps-src/BUILD.bazel b/packages/kbn-ui-shared-deps-src/BUILD.bazel index 0b350c51331ff7..49c2cc62dcfe57 100644 --- a/packages/kbn-ui-shared-deps-src/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-src/BUILD.bazel @@ -45,9 +45,11 @@ webpack_cli( env = select({ "//:dist": { "NODE_ENV": "production", + "NODE_OPTIONS": "--openssl-legacy-provider", }, "//conditions:default": { "NODE_ENV": "development", + "NODE_OPTIONS": "--openssl-legacy-provider", }, }), visibility = ["//visibility:public"], diff --git a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts index ccaf01a70f5d13..569e8b81afd2dc 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts @@ -74,7 +74,7 @@ describe('checking migration metadata changes on all registered SO types', () => "cases-configure": "1afc414f5563a36e4612fa269193d3ed7277c7bd", "cases-connector-mappings": "4b16d440af966e5d6e0fa33368bfa15d987a4b69", "cases-telemetry": "16e261e7378a72acd0806f18df92525dd1da4f37", - "cases-user-actions": "3973dfcaacbe6ae147d7331699cfc25d2a27ca30", + "cases-user-actions": "f1b0dcfeb58a65e68b35c5e99ddee70e746a06c7", "config": "e3f0408976dbdd453641f5699927b28b188f6b8c", "config-global": "b8f559884931609a349e129c717af73d23e7bc76", "connector_token": "fa5301aa5a2914795d3b1b82d0a49939444009da", @@ -124,6 +124,7 @@ describe('checking migration metadata changes on all registered SO types', () => "osquery-pack-asset": "de8783298eb33a577bf1fa0caacd42121dcfae91", "osquery-saved-query": "7b213b4b7a3e59350e99c50e8df9948662ed493a", "query": "4640ef356321500a678869f24117b7091a911cb6", + "rules-settings": "1af4c9abd4b40a154e233c2af4867df7aab7ac24", "sample-data-telemetry": "8b10336d9efae6f3d5593c4cc89fb4abcdf84e04", "search": "c48f5ab5d94545780ea98de1bff9e39f17f3606b", "search-session": "ba383309da68a15be3765977f7a44c84f0ec7964", diff --git a/src/core/server/integration_tests/saved_objects/migrations/skip_reindex.test.ts b/src/core/server/integration_tests/saved_objects/migrations/skip_reindex.test.ts index df64ccb8537531..1699dbae466130 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/skip_reindex.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/skip_reindex.test.ts @@ -63,7 +63,8 @@ describe('skip reindexing', () => { logs = await fs.readFile(logFilePath, 'utf-8'); - expect(logs).toMatch('INIT -> PREPARE_COMPATIBLE_MIGRATION'); + expect(logs).toMatch('INIT -> WAIT_FOR_YELLOW_SOURCE'); + expect(logs).toMatch('WAIT_FOR_YELLOW_SOURCE -> PREPARE_COMPATIBLE_MIGRATION'); expect(logs).toMatch('PREPARE_COMPATIBLE_MIGRATION -> OUTDATED_DOCUMENTS_SEARCH_OPEN_PIT'); expect(logs).toMatch('CHECK_TARGET_MAPPINGS -> CHECK_VERSION_INDEX_READY_ACTIONS'); expect(logs).toMatch('CHECK_VERSION_INDEX_READY_ACTIONS -> DONE'); diff --git a/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts b/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts index 2cb85526f93408..2c8dbabf878a1e 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts @@ -92,6 +92,7 @@ const previouslyRegisteredTypes = [ 'osquery-usage-metric', 'osquery-manager-usage-metric', 'query', + 'rules-settings', 'sample-data-telemetry', 'search', 'search-session', diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index f820a141afdade..9c5f2511f1617a 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -381,6 +381,7 @@ kibana_vars=( xpack.security.sameSiteCookies xpack.security.secureCookies xpack.security.session.cleanupInterval + xpack.security.session.concurrentSessions.maxSessions xpack.security.session.idleTimeout xpack.security.session.lifespan xpack.security.sessionTimeout @@ -393,6 +394,7 @@ kibana_vars=( xpack.securitySolution.maxTimelineImportExportSize xpack.securitySolution.maxTimelineImportPayloadBytes xpack.securitySolution.packagerTaskInterval + xpack.securitySolution.prebuiltRulesPackageVersion xpack.spaces.maxSpaces xpack.task_manager.max_attempts xpack.task_manager.max_poll_inactivity_cycles diff --git a/src/dev/build/tasks/patch_native_modules_task.ts b/src/dev/build/tasks/patch_native_modules_task.ts index 1c1bebfa86c0e9..596b94933385e5 100644 --- a/src/dev/build/tasks/patch_native_modules_task.ts +++ b/src/dev/build/tasks/patch_native_modules_task.ts @@ -41,50 +41,50 @@ interface Package { const packages: Package[] = [ { name: 're2', - version: '1.17.4', + version: '1.17.7', destinationPath: 'node_modules/re2/build/Release/re2.node', extractMethod: 'gunzip', archives: { 'darwin-x64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/darwin-x64-93.gz', - sha256: '9558c5cb39622e9b3653203e772b129d6c634e7dbd7af1b244352fc1d704601f', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/darwin-x64-108.gz', + sha256: '4ed378c5a7fe6134b717afe7642254aff1ed7a881cbcaa53a012ac3efab49f99', }, 'linux-x64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/linux-x64-93.gz', - sha256: '4d06747b266c75b6f7ced93977692c0586ce6a52924cabb569bd966378941aa1', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/linux-x64-108.gz', + sha256: '197a617ca2965f220848561afed71ff6df653f6d79910cf38e866c84ab38a236', }, // ARM builds are currently done manually as Github Actions used in upstream project // do not natively support an ARM target. - // From a AWS Graviton instance running Ubuntu: - // * install build-essential package + // From an AWS Graviton instance running Ubuntu or a GCE T2A instance running Debian: + // * install build-essential package: `sudo apt-get update` + `sudo apt install build-essential` // * install nvm and the node version used by the Kibana repository - // * `npm install re2@1.17.4` + // * `npm install re2@1.17.7` // * re2 will build itself on install - // * `cp node_modules/re2/build/Release/re2.node > linux-arm64-$(node -e "console.log(process.versions.modules)") + // * `cp node_modules/re2/build/Release/re2.node linux-arm64-$(node -e "console.log(process.versions.modules)")` // * `gzip linux-arm64-*` // * capture the sha256 with: `shasum -a 256 linux-arm64-*` - // * upload the `linux-arm64-*.gz` artifact to the `yarn-prebuilt-assets` bucket in GCS using the correct version number + // * upload the `linux-arm64-*.gz` artifact to the `yarn-prebuilt-artifacts` bucket in GCS using the correct version number 'linux-arm64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/linux-arm64-93.gz', - sha256: '25409584f76f3d6ed85463d84adf094eb6e256ed1cb0b754b95bcbda6691fc26', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/linux-arm64-108.gz', + sha256: 'a690087a1a1fd9887aac1abdab68d1992600e218be10783da6d3381cca950c1a', }, // A similar process is necessary for building on ARM macs: // * bootstrap and re2 will build itself on install - // * `cp node_modules/re2/build/Release/re2.node > darwin-arm64-$(node -e "console.log(process.versions.modules)") + // * `cp node_modules/re2/build/Release/re2.node darwin-arm64-$(node -e "console.log(process.versions.modules)")` // * `gzip darwin-arm64-*` // * capture the sha256 with: `shasum -a 256 darwin-arm64-*` - // * upload the `darwin-arm64-*.gz` artifact to the `yarn-prebuilt-assets` bucket in GCS using the correct version number + // * upload the `darwin-arm64-*.gz` artifact to the `yarn-prebuilt-artifacts` bucket in GCS using the correct version number 'darwin-arm64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/darwin-arm64-93.gz', - sha256: 'd4b708749ddef1c87019f6b80e051ed0c29ccd1de34f233c47d8dcaddf803872', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/darwin-arm64-108.gz', + sha256: '42afc32137ff5c5bebae5d68347a9786906748c2f28e06194d8950707f2ae90e', }, 'win32-x64': { - url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.4/win32-x64-93.gz', - sha256: '0320d0c0385432944c6fb3c8c8fcd78d440ce5626f7618f9ec71d88e44820674', + url: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2/uhop/node-re2/releases/download/1.17.7/win32-x64-108.gz', + sha256: 'ff72fe02de652262659c8e17e44a932f3c873362233756b40d1a97538d05de92', }, }, }, diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 05ae1c3048d171..99918241190df0 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -10,6 +10,7 @@ export const storybookAliases = { apm: 'x-pack/plugins/apm/.storybook', canvas: 'x-pack/plugins/canvas/storybook', + cases: 'packages/kbn-cases-components/.storybook', ci_composite: '.ci/.storybook', cloud_chat: 'x-pack/plugins/cloud_integrations/cloud_chat/.storybook', coloring: 'packages/kbn-coloring/.storybook', diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.delete_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.delete_transform.json index 48df0c5df1548e..df821d3c2fccaf 100644 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.delete_transform.json +++ b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.delete_transform.json @@ -1,7 +1,8 @@ { "transform.delete_transform": { "url_params": { - "force": "__flag__" + "force": "__flag__", + "timeout": "" }, "methods": [ "DELETE" diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.get_transform_stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.get_transform_stats.json index 445de6ffc51018..75f6f7286d2c24 100644 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.get_transform_stats.json +++ b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.get_transform_stats.json @@ -3,6 +3,7 @@ "url_params": { "from": "", "size": "", + "timeout": "", "allow_no_match": "__flag__" }, "methods": [ diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.preview_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.preview_transform.json index 2e7b48f8528f6d..a5c95a88392b41 100644 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.preview_transform.json +++ b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.preview_transform.json @@ -1,9 +1,14 @@ { "transform.preview_transform": { + "url_params": { + "timeout": "" + }, "methods": [ + "GET", "POST" ], "patterns": [ + "_transform/{transform_id}/_preview", "_transform/_preview" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/preview-transform.html" diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.put_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.put_transform.json index 00658134594e7d..7833ce27d67886 100644 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.put_transform.json +++ b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.put_transform.json @@ -1,7 +1,8 @@ { "transform.put_transform": { "url_params": { - "defer_validation": "__flag__" + "defer_validation": "__flag__", + "timeout": "" }, "methods": [ "PUT" diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.reset_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.reset_transform.json new file mode 100644 index 00000000000000..6770d47b220073 --- /dev/null +++ b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.reset_transform.json @@ -0,0 +1,15 @@ +{ + "transform.reset_transform": { + "url_params": { + "force": "__flag__", + "timeout": "" + }, + "methods": [ + "POST" + ], + "patterns": [ + "_transform/{transform_id}/_reset" + ], + "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reset-transform.html" + } +} diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.update_transform.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.update_transform.json index 307f31b1d706b0..46bc351aa1956e 100644 --- a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.update_transform.json +++ b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.update_transform.json @@ -1,7 +1,8 @@ { "transform.update_transform": { "url_params": { - "defer_validation": "__flag__" + "defer_validation": "__flag__", + "timeout": "" }, "methods": [ "POST" diff --git a/src/plugins/console/server/lib/spec_definitions/json/generated/transform.upgrade_transforms.json b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.upgrade_transforms.json new file mode 100644 index 00000000000000..01381b30d35ea9 --- /dev/null +++ b/src/plugins/console/server/lib/spec_definitions/json/generated/transform.upgrade_transforms.json @@ -0,0 +1,15 @@ +{ + "transform.upgrade_transforms": { + "url_params": { + "dry_run": "__flag__", + "timeout": "" + }, + "methods": [ + "POST" + ], + "patterns": [ + "_transform/_upgrade" + ], + "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/upgrade-transforms.html" + } +} diff --git a/src/plugins/controls/common/options_list/types.ts b/src/plugins/controls/common/options_list/types.ts index eb1f7b886d427a..8835c7f5767f6f 100644 --- a/src/plugins/controls/common/options_list/types.ts +++ b/src/plugins/controls/common/options_list/types.ts @@ -40,6 +40,7 @@ export interface OptionsListSuggestions { * The Options list response is returned from the serverside Options List route. */ export interface OptionsListResponse { + rejected: boolean; suggestions: OptionsListSuggestions; totalCardinality: number; invalidSelections?: string[]; diff --git a/src/plugins/controls/public/__stories__/controls.stories.tsx b/src/plugins/controls/public/__stories__/controls.stories.tsx index 02a13125ba49c2..7f091abe34a566 100644 --- a/src/plugins/controls/public/__stories__/controls.stories.tsx +++ b/src/plugins/controls/public/__stories__/controls.stories.tsx @@ -61,6 +61,7 @@ const storybookStubOptionsListRequest = async ( {} ), totalCardinality: 100, + rejected: false, }), 120 ) diff --git a/src/plugins/controls/public/options_list/components/options_list.scss b/src/plugins/controls/public/options_list/components/options_list.scss index c737dd6dc02159..e88208ee4c6238 100644 --- a/src/plugins/controls/public/options_list/components/options_list.scss +++ b/src/plugins/controls/public/options_list/components/options_list.scss @@ -7,15 +7,6 @@ height: 100%; } -.optionsList__items { - @include euiScrollBar; - - overflow-y: auto; - max-height: $euiSize * 30; - width: $euiSize * 25; - max-width: 100%; -} - .optionsList__actions { padding: $euiSizeS; border-bottom: $euiBorderThin; diff --git a/src/plugins/controls/public/options_list/components/options_list_control.tsx b/src/plugins/controls/public/options_list/components/options_list_control.tsx index 43742a817e3ec6..3035eada20caf4 100644 --- a/src/plugins/controls/public/options_list/components/options_list_control.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_control.tsx @@ -43,18 +43,22 @@ export const OptionsListControl = ({ typeaheadSubject }: { typeaheadSubject: Sub const existsSelected = select((state) => state.explicitInput.existsSelected); const controlStyle = select((state) => state.explicitInput.controlStyle); const singleSelect = select((state) => state.explicitInput.singleSelect); + const fieldName = select((state) => state.explicitInput.fieldName); const exclude = select((state) => state.explicitInput.exclude); const id = select((state) => state.explicitInput.id); const loading = select((state) => state.output.loading); // debounce loading state so loading doesn't flash when user types - const [buttonLoading, setButtonLoading] = useState(true); - const debounceSetButtonLoading = useMemo( - () => debounce((latestLoading: boolean) => setButtonLoading(latestLoading), 100), + const [debouncedLoading, setDebouncedLoading] = useState(true); + const debounceSetLoading = useMemo( + () => + debounce((latestLoading: boolean) => { + setDebouncedLoading(latestLoading); + }, 100), [] ); - useEffect(() => debounceSetButtonLoading(loading ?? false), [loading, debounceSetButtonLoading]); + useEffect(() => debounceSetLoading(loading ?? false), [loading, debounceSetLoading]); // remove all other selections if this control is single select useEffect(() => { @@ -111,7 +115,7 @@ export const OptionsListControl = ({ typeaheadSubject }: { typeaheadSubject: Sub
    setIsPopoverOpen(false)} anchorClassName="optionsList__anchorOverride" - aria-labelledby={`control-popover-${id}`} + aria-label={OptionsListStrings.popover.getAriaLabel(fieldName)} > - + ); diff --git a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx index b1315be51ae1e2..acb5d24d806596 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx @@ -21,6 +21,7 @@ import { ControlOutput, OptionsListEmbeddableInput } from '../..'; describe('Options list popover', () => { const defaultProps = { width: 500, + isLoading: false, updateSearchString: jest.fn(), }; @@ -56,13 +57,13 @@ describe('Options list popover', () => { test('available options list width responds to container size', async () => { let popover = await mountComponent({ popoverProps: { width: 301 } }); - let availableOptionsDiv = findTestSubject(popover, 'optionsList-control-available-options'); - expect(availableOptionsDiv.getDOMNode().getAttribute('style')).toBe('width: 301px;'); + let popoverDiv = findTestSubject(popover, 'optionsList-control-popover'); + expect(popoverDiv.getDOMNode().getAttribute('style')).toBe('width: 301px;'); // the div cannot be smaller than 301 pixels wide popover = await mountComponent({ popoverProps: { width: 300 } }); - availableOptionsDiv = findTestSubject(popover, 'optionsList-control-available-options'); - expect(availableOptionsDiv.getDOMNode().getAttribute('style')).toBe(null); + popoverDiv = findTestSubject(popover, 'optionsList-control-available-options'); + expect(popoverDiv.getDOMNode().getAttribute('style')).toBe(null); }); test('no available options', async () => { @@ -92,13 +93,12 @@ describe('Options list popover', () => { explicitInput: { selectedOptions: selections }, }); clickShowOnlySelections(popover); - const availableOptionsDiv = findTestSubject(popover, 'optionsList-control-available-options'); - availableOptionsDiv - .childAt(0) - .children() - .forEach((child, i) => { - expect(child.text()).toBe(selections[i]); - }); + const availableOptions = popover.find( + '[data-test-subj="optionsList-control-available-options"] ul' + ); + availableOptions.children().forEach((child, i) => { + expect(child.text()).toBe(`${selections[i]} - Checked option.`); + }); }); test('disable search and sort when show only selected toggle is true', async () => { @@ -132,11 +132,18 @@ describe('Options list popover', () => { }, }); const validSelection = findTestSubject(popover, 'optionsList-control-selection-bark'); - expect(validSelection.text()).toEqual('bark75'); + expect(validSelection.find('.euiSelectableListItem__text').text()).toEqual( + 'bark - Checked option.' + ); + expect( + validSelection.find('div[data-test-subj="optionsList-document-count-badge"]').text().trim() + ).toEqual('75'); const title = findTestSubject(popover, 'optionList__ignoredSelectionLabel').text(); expect(title).toEqual('Ignored selection'); const invalidSelection = findTestSubject(popover, 'optionsList-control-ignored-selection-woof'); - expect(invalidSelection.text()).toEqual('woof'); + expect(invalidSelection.find('.euiSelectableListItem__text').text()).toEqual( + 'woof - Checked option.' + ); expect(invalidSelection.hasClass('optionsList__selectionInvalid')).toBe(true); }); @@ -221,8 +228,10 @@ describe('Options list popover', () => { explicitInput: { existsSelected: true }, }); clickShowOnlySelections(popover); - const availableOptionsDiv = findTestSubject(popover, 'optionsList-control-available-options'); - expect(availableOptionsDiv.children().at(0).text()).toBe('Exists'); + const availableOptions = popover.find( + '[data-test-subj="optionsList-control-available-options"] ul' + ); + expect(availableOptions.text()).toBe('Exists - Checked option.'); }); test('when sorting suggestions, show both sorting types for keyword field', async () => { diff --git a/src/plugins/controls/public/options_list/components/options_list_popover.tsx b/src/plugins/controls/public/options_list/components/options_list_popover.tsx index 6ad39e0b3dbd9a..70353524068cda 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover.tsx @@ -22,10 +22,15 @@ import { OptionsListPopoverInvalidSelections } from './options_list_popover_inva export interface OptionsListPopoverProps { width: number; + isLoading: boolean; updateSearchString: (newSearchString: string) => void; } -export const OptionsListPopover = ({ width, updateSearchString }: OptionsListPopoverProps) => { +export const OptionsListPopover = ({ + width, + isLoading, + updateSearchString, +}: OptionsListPopoverProps) => { // Redux embeddable container Context const { useEmbeddableSelector: select } = useReduxEmbeddableContext< OptionsListReduxState, @@ -45,9 +50,10 @@ export const OptionsListPopover = ({ width, updateSearchString }: OptionsListPop const [showOnlySelected, setShowOnlySelected] = useState(false); return ( - 300 ? width : undefined }} + data-test-subj={`optionsList-control-popover`} aria-label={OptionsListStrings.popover.getAriaLabel(fieldName)} > {title} @@ -59,17 +65,15 @@ export const OptionsListPopover = ({ width, updateSearchString }: OptionsListPop /> )}
    300 ? width : undefined }} data-test-subj={`optionsList-control-available-options`} - data-option-count={Object.keys(availableOptions ?? {}).length} + data-option-count={isLoading ? 0 : Object.keys(availableOptions ?? {}).length} > - + {!showOnlySelected && invalidSelections && !isEmpty(invalidSelections) && ( )}
    {!hideExclude && } -
    +
    ); }; diff --git a/src/plugins/controls/public/options_list/components/options_list_popover_empty_message.tsx b/src/plugins/controls/public/options_list/components/options_list_popover_empty_message.tsx new file mode 100644 index 00000000000000..69c819a3caca27 --- /dev/null +++ b/src/plugins/controls/public/options_list/components/options_list_popover_empty_message.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { EuiIcon, EuiSpacer } from '@elastic/eui'; + +import { OptionsListStrings } from './options_list_strings'; + +export const OptionsListPopoverEmptyMessage = ({ + showOnlySelected, +}: { + showOnlySelected: boolean; +}) => { + return ( + + + + + {showOnlySelected + ? OptionsListStrings.popover.getSelectionsEmptyMessage() + : OptionsListStrings.popover.getEmptyMessage()} + + + ); +}; diff --git a/src/plugins/controls/public/options_list/components/options_list_popover_invalid_selections.tsx b/src/plugins/controls/public/options_list/components/options_list_popover_invalid_selections.tsx index 01c9f14363a4c6..424ae37da4bcb1 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover_invalid_selections.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover_invalid_selections.tsx @@ -6,9 +6,15 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { useEffect, useState } from 'react'; -import { EuiFilterSelectItem, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { + EuiSelectableOption, + EuiSelectable, + EuiSpacer, + EuiTitle, + EuiScreenReaderOnly, +} from '@elastic/eui'; import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public'; import { OptionsListReduxState } from '../types'; @@ -26,6 +32,31 @@ export const OptionsListPopoverInvalidSelections = () => { // Select current state from Redux using multiple selectors to avoid rerenders. const invalidSelections = select((state) => state.componentState.invalidSelections); + const fieldName = select((state) => state.explicitInput.fieldName); + + const [selectableOptions, setSelectableOptions] = useState([]); // will be set in following useEffect + useEffect(() => { + /* This useEffect makes selectableOptions responsive to unchecking options */ + const options: EuiSelectableOption[] = (invalidSelections ?? []).map((key) => { + return { + key, + label: key, + checked: 'on', + className: 'optionsList__selectionInvalid', + 'data-test-subj': `optionsList-control-ignored-selection-${key}`, + prepend: ( + +
    + {OptionsListStrings.popover.getInvalidSelectionScreenReaderText()} + {'" "'} {/* Adds a pause for the screen reader */} +
    +
    + ), + }; + }); + setSelectableOptions(options); + }, [invalidSelections]); + return ( <> @@ -40,18 +71,20 @@ export const OptionsListPopoverInvalidSelections = () => { )} - {invalidSelections?.map((ignoredSelection, index) => ( - dispatch(deselectOption(ignoredSelection))} - aria-label={OptionsListStrings.popover.getInvalidSelectionAriaLabel(ignoredSelection)} - > - {`${ignoredSelection}`} - - ))} + { + setSelectableOptions(newSuggestions); + dispatch(deselectOption(changedOption.label)); + }} + > + {(list) => list} + ); }; diff --git a/src/plugins/controls/public/options_list/components/options_list_popover_suggestion_badge.tsx b/src/plugins/controls/public/options_list/components/options_list_popover_suggestion_badge.tsx new file mode 100644 index 00000000000000..6c50d92ba81b50 --- /dev/null +++ b/src/plugins/controls/public/options_list/components/options_list_popover_suggestion_badge.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +import { css } from '@emotion/react'; +import { EuiScreenReaderOnly, EuiText, EuiToolTip, useEuiTheme } from '@elastic/eui'; + +import { OptionsListStrings } from './options_list_strings'; + +export const OptionsListPopoverSuggestionBadge = ({ documentCount }: { documentCount: number }) => { + const { euiTheme } = useEuiTheme(); + + return ( + <> + + + {`${documentCount.toLocaleString()}`} + + + +
    + {'" "'} {/* Adds a pause for the screen reader */} + {OptionsListStrings.popover.getDocumentCountScreenReaderText(documentCount)} +
    +
    + + ); +}; diff --git a/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx b/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx index 7983043ae1d8a9..8bd8e361e7081a 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover_suggestions.tsx @@ -6,30 +6,25 @@ * Side Public License, v 1. */ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; -import { - EuiFilterSelectItem, - EuiFlexGroup, - EuiFlexItem, - EuiToolTip, - EuiSpacer, - EuiIcon, - useEuiTheme, - EuiText, -} from '@elastic/eui'; -import { css } from '@emotion/react'; +import { EuiLoadingSpinner, EuiSelectable, EuiSpacer } from '@elastic/eui'; import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public'; +import { EuiSelectableOption } from '@elastic/eui/src/components/selectable/selectable_option'; import { OptionsListReduxState } from '../types'; import { OptionsListStrings } from './options_list_strings'; import { optionsListReducers } from '../options_list_reducers'; +import { OptionsListPopoverEmptyMessage } from './options_list_popover_empty_message'; +import { OptionsListPopoverSuggestionBadge } from './options_list_popover_suggestion_badge'; interface OptionsListPopoverSuggestionsProps { + isLoading: boolean; showOnlySelected: boolean; } export const OptionsListPopoverSuggestions = ({ + isLoading, showOnlySelected, }: OptionsListPopoverSuggestionsProps) => { // Redux embeddable container Context @@ -39,7 +34,6 @@ export const OptionsListPopoverSuggestions = ({ actions: { replaceSelection, deselectOption, selectOption, selectExists }, } = useReduxEmbeddableContext(); const dispatch = useEmbeddableDispatch(); - const { euiTheme } = useEuiTheme(); // Select current state from Redux using multiple selectors to avoid rerenders. const invalidSelections = select((state) => state.componentState.invalidSelections); @@ -49,130 +43,97 @@ export const OptionsListPopoverSuggestions = ({ const existsSelected = select((state) => state.explicitInput.existsSelected); const singleSelect = select((state) => state.explicitInput.singleSelect); const hideExists = select((state) => state.explicitInput.hideExists); + const fieldName = select((state) => state.explicitInput.fieldName); - const loading = select((state) => state.output.loading); // track selectedOptions and invalidSelections in sets for more efficient lookup const selectedOptionsSet = useMemo(() => new Set(selectedOptions), [selectedOptions]); const invalidSelectionsSet = useMemo( () => new Set(invalidSelections), [invalidSelections] ); - const suggestions = showOnlySelected ? selectedOptions : Object.keys(availableOptions ?? {}); - if ( - !loading && - (!suggestions || suggestions.length === 0) && - !(showOnlySelected && existsSelected) - ) { - return ( -
    -
    - - -

    - {showOnlySelected - ? OptionsListStrings.popover.getSelectionsEmptyMessage() - : OptionsListStrings.popover.getEmptyMessage()} -

    -
    -
    - ); - } + const suggestions = useMemo(() => { + return showOnlySelected ? selectedOptions : Object.keys(availableOptions ?? {}); + }, [availableOptions, selectedOptions, showOnlySelected]); + + const existsSelectableOption = useMemo(() => { + if (hideExists || (!existsSelected && (showOnlySelected || suggestions?.length === 0))) return; + + return { + key: 'exists-option', + checked: existsSelected ? 'on' : undefined, + label: OptionsListStrings.controlAndPopover.getExists(), + className: 'optionsList__existsFilter', + 'data-test-subj': 'optionsList-control-selection-exists', + }; + }, [suggestions, existsSelected, showOnlySelected, hideExists]); + + const [selectableOptions, setSelectableOptions] = useState([]); // will be set in following useEffect + useEffect(() => { + /* This useEffect makes selectableOptions responsive to search, show only selected, and clear selections */ + const options: EuiSelectableOption[] = (suggestions ?? []).map((key) => { + return { + key, + label: key, + checked: selectedOptionsSet?.has(key) ? 'on' : undefined, + 'data-test-subj': `optionsList-control-selection-${key}`, + className: + showOnlySelected && invalidSelectionsSet.has(key) + ? 'optionsList__selectionInvalid' + : 'optionsList__validSuggestion', + append: + !showOnlySelected && availableOptions?.[key] ? ( + + ) : undefined, + }; + }); + const suggestionsSelectableOptions = existsSelectableOption + ? [existsSelectableOption, ...options] + : options; + setSelectableOptions(suggestionsSelectableOptions); + }, [ + suggestions, + availableOptions, + showOnlySelected, + selectedOptionsSet, + invalidSelectionsSet, + existsSelectableOption, + ]); return ( - <> - {!hideExists && !(showOnlySelected && !existsSelected) && ( - { - dispatch(selectExists(!Boolean(existsSelected))); - }} - className="optionsList__existsFilter" - > - {OptionsListStrings.controlAndPopover.getExists()} - + + + + {OptionsListStrings.popover.getLoadingMessage()} + + } + options={selectableOptions} + listProps={{ onFocusBadge: false }} + aria-label={OptionsListStrings.popover.getSuggestionsAriaLabel( + fieldName, + selectableOptions.length )} - {suggestions?.map((key: string) => ( - { - if (showOnlySelected) { - dispatch(deselectOption(key)); - return; - } - if (singleSelect) { - dispatch(replaceSelection(key)); - return; - } - if (selectedOptionsSet.has(key)) { - dispatch(deselectOption(key)); - return; - } - dispatch(selectOption(key)); - }} - className={ - showOnlySelected && invalidSelectionsSet.has(key) - ? 'optionsList__selectionInvalid' - : 'optionsList__validSuggestion' - } - aria-label={ - availableOptions?.[key] - ? OptionsListStrings.popover.getSuggestionAriaLabel( - key, - availableOptions[key].doc_count ?? 0 - ) - : key - } - > - - - {`${key}`} - - {!showOnlySelected && ( - - {availableOptions && availableOptions[key] && ( - - - {`${availableOptions[key].doc_count.toLocaleString()}`} - - - )} - - )} - - - ))} - + emptyMessage={} + onChange={(newSuggestions, _, changedOption) => { + setSelectableOptions(newSuggestions); + + const key = changedOption.key ?? changedOption.label; + // the order of these checks matters, so be careful if rearranging them + if (key === 'exists-option') { + dispatch(selectExists(!Boolean(existsSelected))); + } else if (showOnlySelected || selectedOptionsSet.has(key)) { + dispatch(deselectOption(key)); + } else if (singleSelect) { + dispatch(replaceSelection(key)); + } else { + dispatch(selectOption(key)); + } + }} + > + {(list) => list} + ); }; diff --git a/src/plugins/controls/public/options_list/components/options_list_strings.ts b/src/plugins/controls/public/options_list/components/options_list_strings.ts index a75eb7913064c4..bef8a2cbc26ffc 100644 --- a/src/plugins/controls/public/options_list/components/options_list_strings.ts +++ b/src/plugins/controls/public/options_list/components/options_list_strings.ts @@ -48,11 +48,15 @@ export const OptionsListStrings = { defaultMessage: 'Popover for {fieldName} control', values: { fieldName }, }), - getSuggestionAriaLabel: (key: string, documentCount: number) => + getSuggestionsAriaLabel: (fieldName: string, optionCount: number) => i18n.translate('controls.optionsList.popover.suggestionsAriaLabel', { defaultMessage: - '{key}, which appears in {documentCount} {documentCount, plural, one {document} other {documents}}.', - values: { key, documentCount }, + 'Available {optionCount, plural, one {option} other {options}} for {fieldName}', + values: { fieldName, optionCount }, + }), + getLoadingMessage: () => + i18n.translate('controls.optionsList.popover.loading', { + defaultMessage: 'Loading options', }), getEmptyMessage: () => i18n.translate('controls.optionsList.popover.empty', { @@ -80,6 +84,12 @@ export const OptionsListStrings = { 'Search {totalOptions} available {totalOptions, plural, one {option} other {options}}', values: { totalOptions }, }), + getInvalidSelectionsSectionAriaLabel: (fieldName: string, invalidSelectionCount: number) => + i18n.translate('controls.optionsList.popover.invalidSelectionsAriaLabel', { + defaultMessage: + 'Ignored {invalidSelectionCount, plural, one {selection} other {selections}} for {fieldName}', + values: { fieldName, invalidSelectionCount }, + }), getInvalidSelectionsSectionTitle: (invalidSelectionCount: number) => i18n.translate('controls.optionsList.popover.invalidSelectionsSectionTitle', { defaultMessage: @@ -92,10 +102,9 @@ export const OptionsListStrings = { '{selectedOptions} selected {selectedOptions, plural, one {option} other {options}} {selectedOptions, plural, one {is} other {are}} ignored because {selectedOptions, plural, one {it is} other {they are}} no longer in the data.', values: { selectedOptions }, }), - getInvalidSelectionAriaLabel: (option: string) => - i18n.translate('controls.optionsList.popover.invalidSelectionAriaLabel', { - defaultMessage: 'Ignored selection: {option}', - values: { option }, + getInvalidSelectionScreenReaderText: () => + i18n.translate('controls.optionsList.popover.invalidSelectionScreenReaderText', { + defaultMessage: 'Invalid selection.', }), getIncludeLabel: () => i18n.translate('controls.optionsList.popover.includeLabel', { @@ -127,6 +136,12 @@ export const OptionsListStrings = { 'This value appears in {documentCount, number} {documentCount, plural, one {document} other {documents}}', values: { documentCount }, }), + getDocumentCountScreenReaderText: (documentCount: number) => + i18n.translate('controls.optionsList.popover.documentCountScreenReaderText', { + defaultMessage: + 'Appears in {documentCount, number} {documentCount, plural, one {document} other {documents}}', + values: { documentCount }, + }), }, controlAndPopover: { getExists: (negate: number = +false) => diff --git a/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx b/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx index 1153150143f895..2f710a56c4f879 100644 --- a/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx +++ b/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx @@ -307,7 +307,7 @@ export class OptionsListEmbeddable extends Embeddable ) => { state.explicitInput.selectedOptions = [action.payload]; + if (state.explicitInput.existsSelected) state.explicitInput.existsSelected = false; }, clearSelections: (state: WritableDraft) => { if (state.explicitInput.existsSelected) state.explicitInput.existsSelected = false; diff --git a/src/plugins/controls/public/services/options_list/options_list.story.ts b/src/plugins/controls/public/services/options_list/options_list.story.ts index a44f698c933953..62686feee7495e 100644 --- a/src/plugins/controls/public/services/options_list/options_list.story.ts +++ b/src/plugins/controls/public/services/options_list/options_list.story.ts @@ -20,6 +20,7 @@ let optionsListRequestMethod = async (request: OptionsListRequest, abortSignal: r({ suggestions: {}, totalCardinality: 100, + rejected: false, }), 120 ) diff --git a/src/plugins/controls/public/services/options_list/options_list_service.ts b/src/plugins/controls/public/services/options_list/options_list_service.ts index bc2934e9295a60..ab8e67666140b8 100644 --- a/src/plugins/controls/public/services/options_list/options_list_service.ts +++ b/src/plugins/controls/public/services/options_list/options_list_service.ts @@ -101,7 +101,7 @@ class OptionsListService implements ControlsOptionsListService { } catch (error) { // Remove rejected results from memoize cache this.cachedOptionsListRequest.cache.delete(this.optionsListCacheResolver(request)); - return {} as OptionsListResponse; + return { rejected: true } as OptionsListResponse; } }; } diff --git a/src/plugins/controls/server/options_list/options_list_suggestions_route.ts b/src/plugins/controls/server/options_list/options_list_suggestions_route.ts index 6e2f8f769815d4..0893d24ebacf0f 100644 --- a/src/plugins/controls/server/options_list/options_list_suggestions_route.ts +++ b/src/plugins/controls/server/options_list/options_list_suggestions_route.ts @@ -144,6 +144,7 @@ export const setupOptionsListSuggestionsRoute = ( suggestions, totalCardinality, invalidSelections, + rejected: false, }; }; }; diff --git a/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx b/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx index 247200de71e8fc..0847066e166cec 100644 --- a/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx +++ b/src/plugins/dashboard/public/dashboard_actions/filters_notification_action.tsx @@ -10,12 +10,10 @@ import React from 'react'; import { EditPanelAction, isFilterableEmbeddable, ViewMode } from '@kbn/embeddable-plugin/public'; import { type IEmbeddable, isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; import type { ApplicationStart } from '@kbn/core/public'; import { type AggregateQuery } from '@kbn/es-query'; -import { I18nProvider } from '@kbn/i18n-react'; import { FiltersNotificationPopover } from './filters_notification_popover'; import { dashboardFilterNotificationActionStrings } from './_dashboard_actions_strings'; @@ -60,19 +58,15 @@ export class FiltersNotificationAction implements Action - - - - - - + + + ); }; diff --git a/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx b/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx index 0d46aa66595ea3..8f677450dca150 100644 --- a/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx +++ b/src/plugins/dashboard/public/dashboard_actions/library_notification_action.tsx @@ -15,9 +15,7 @@ import { isReferenceOrValueEmbeddable, } from '@kbn/embeddable-plugin/public'; import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import { pluginServices } from '../services/plugin_services'; import { UnlinkFromLibraryAction } from './unlink_from_library_action'; import { LibraryNotificationPopover } from './library_notification_popover'; import { dashboardLibraryNotificationStrings } from './_dashboard_actions_strings'; @@ -33,15 +31,7 @@ export class LibraryNotificationAction implements Action { const { embeddable } = context; return ( - - - + ); }; diff --git a/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts b/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts index d32323d4d0b23f..455e01663acaee 100644 --- a/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/get_display_value.test.ts @@ -36,6 +36,33 @@ describe('getDisplayValueFromFilter', () => { expect(displayValue).toBe(''); }); + it('returns 0 if value undefined and numeric field', () => { + const filter = { + meta: { + negate: false, + index: 'logstash-*', + type: 'phrase', + key: 'bytes', + value: undefined, + disabled: false, + alias: null, + params: { + query: undefined, + }, + }, + $state: { + store: FilterStateStore.APP_STATE, + }, + query: { + match_phrase: { + bytes: '0', + }, + }, + }; + const displayValue = getDisplayValueFromFilter(filter, [stubIndexPattern]); + expect(displayValue).toBe('0'); + }); + it('phrase filters without formatter', () => { jest.spyOn(stubIndexPattern, 'getFormatterForField').mockImplementation(() => undefined!); const displayValue = getDisplayValueFromFilter(phraseFilter, [stubIndexPattern]); diff --git a/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts b/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts index 6a8f5d895728ac..bb1d6a464cb04c 100644 --- a/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts +++ b/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts @@ -61,10 +61,12 @@ export function getFieldDisplayValueFromFilter( export function getDisplayValueFromFilter(filter: Filter, indexPatterns: DataViewBase[]): string { const indexPattern = getIndexPatternFromFilter(filter, indexPatterns); const fieldName = getFilterField(filter); + const field = indexPattern?.fields.find((f) => f.name === fieldName); + const fieldType = field?.type; const valueFormatter = getValueFormatter(indexPattern, fieldName); if (isPhraseFilter(filter) || isScriptedPhraseFilter(filter)) { - return getPhraseDisplayValue(filter, valueFormatter); + return getPhraseDisplayValue(filter, valueFormatter, fieldType); } else if (isPhrasesFilter(filter)) { return getPhrasesDisplayValue(filter, valueFormatter); } else if (isRangeFilter(filter) || isScriptedRangeFilter(filter)) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts index 3bbe9b886cf6ad..6058a125c9a54d 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts @@ -22,13 +22,15 @@ const getScriptedPhraseValue = (filter: PhraseFilter) => export function getPhraseDisplayValue( filter: PhraseFilter | ScriptedPhraseFilter, - formatter?: FieldFormat + formatter?: FieldFormat, + fieldType?: string ): string { const value = filter.meta.value ?? filter.meta.params.query; + const updatedValue = fieldType === 'number' && !value ? 0 : value; if (formatter?.convert) { - return formatter.convert(value); + return formatter.convert(updatedValue); } - return value === undefined ? '' : `${value}`; + return updatedValue === undefined ? '' : `${updatedValue}`; } const getParams = (filter: PhraseFilter) => { diff --git a/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx b/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx index b28d8fdb7d2ddc..25e3b4e8c05f13 100644 --- a/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx +++ b/src/plugins/data_view_field_editor/__jest__/client_integration/helpers/setup_environment.tsx @@ -17,6 +17,7 @@ import { notificationServiceMock, uiSettingsServiceMock } from '@kbn/core/public import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { fieldFormatsMock as fieldFormats } from '@kbn/field-formats-plugin/common/mocks'; import { FieldFormat } from '@kbn/field-formats-plugin/common'; +import { createStubDataView } from '@kbn/data-views-plugin/common/data_views/data_view.stub'; import { FieldEditorProvider, Context } from '../../../public/components/field_editor_context'; import { FieldPreviewProvider } from '../../../public/components/preview'; import { initApi, ApiService } from '../../../public/lib'; @@ -115,14 +116,16 @@ export const WithFieldEditorDependencies = return new MockDefaultFieldFormat(); }); - const dependencies: Context = { - dataView: { + const dataView = createStubDataView({ + spec: { title: indexPatternNameForTest, - getIndexPattern: () => indexPatternNameForTest, - name: indexPatternNameForTest, - getName: () => indexPatternNameForTest, - fields: { getAll: spyIndexPatternGetAllFields }, - } as any, + }, + }); + + jest.spyOn(dataView.fields, 'getAll').mockImplementation(spyIndexPatternGetAllFields); + + const dependencies: Context = { + dataView, uiSettings: uiSettingsServiceMock.createStartContract(), fieldTypeToProcess: 'runtime', existingConcreteFields: [], diff --git a/src/plugins/data_view_field_editor/public/components/preview/field_list/field_list.tsx b/src/plugins/data_view_field_editor/public/components/preview/field_list/field_list.tsx index f0e606ad1e70bf..519b147ca77c35 100644 --- a/src/plugins/data_view_field_editor/public/components/preview/field_list/field_list.tsx +++ b/src/plugins/data_view_field_editor/public/components/preview/field_list/field_list.tsx @@ -12,7 +12,7 @@ import { get } from 'lodash'; import { EuiButtonEmpty, EuiButton, EuiSpacer, EuiEmptyPrompt, EuiTextColor } from '@elastic/eui'; import { useFieldEditorContext } from '../../field_editor_context'; -import { useFieldPreviewContext, defaultValueFormatter } from '../field_preview_context'; +import { useFieldPreviewContext } from '../field_preview_context'; import type { FieldPreview } from '../types'; import { PreviewListItem } from './field_list_item'; @@ -55,20 +55,15 @@ export const PreviewFieldList: React.FC = ({ height, clearSearch, searchV const [showAllFields, setShowAllFields] = useState(false); - const { - fields: { getAll: getAllFields }, - } = dataView; - - const indexPatternFields = useMemo(() => { - return getAllFields(); - }, [getAllFields]); - const fieldList: DocumentField[] = useMemo( () => - indexPatternFields - .map(({ name, displayName }) => { + dataView.fields + .getAll() + .map((field) => { + const { name, displayName } = field; + const formatter = dataView.getFormatterForField(field); const value = get(currentDocument?._source, name); - const formattedValue = defaultValueFormatter(value); + const formattedValue = formatter.convert(value, 'html'); return { key: displayName, @@ -78,7 +73,7 @@ export const PreviewFieldList: React.FC = ({ height, clearSearch, searchV }; }) .filter(({ value }) => value !== undefined), - [indexPatternFields, currentDocument?._source] + [dataView, currentDocument?._source] ); const fieldListWithPinnedFields: DocumentField[] = useMemo(() => { diff --git a/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap b/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap index 69a17834fc4d36..5ee8bb9a10d794 100644 --- a/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap +++ b/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap @@ -103,61 +103,37 @@ exports[`AddData render 1`] = ` - - - - - - - -

    - -

    -
    - - - - - - - - -
    -
    -
    +
    diff --git a/src/plugins/home/public/application/components/add_data/add_data.tsx b/src/plugins/home/public/application/components/add_data/add_data.tsx index 295c058e35e2cc..086e28cbb1f83a 100644 --- a/src/plugins/home/public/application/components/add_data/add_data.tsx +++ b/src/plugins/home/public/application/components/add_data/add_data.tsx @@ -14,7 +14,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiImage, - EuiPanel, EuiSpacer, EuiText, EuiTitle, @@ -24,6 +23,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { METRIC_TYPE } from '@kbn/analytics'; import { ApplicationStart } from '@kbn/core/public'; import { RedirectAppLinks } from '@kbn/kibana-react-plugin/public'; +import { MoveData } from '../move_data'; import { createAppNavigationHandler } from '../app_navigation_handler'; import { getServices } from '../../kibana_services'; @@ -140,62 +140,10 @@ export const AddData: FC = ({ addBasePath, application, isDarkMode, isClo - {!isCloudEnabled ? ( - - - - - - - - -

    - -

    -
    - - - - - - - - - - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - { - trackUiMetric(METRIC_TYPE.CLICK, 'migrate_data_to_cloud'); - createAppNavigationHandler('/app/management/data/migrate_data')(event); - }} - > - - -
    -
    -
    -
    - ) : ( - + + {!isCloudEnabled ? ( + + ) : ( = ({ addBasePath, application, isDarkMode, isClo : 'illustration_integrations_lightmode.svg') } /> - - )} + )} + ); diff --git a/src/plugins/home/public/application/components/move_data/index.tsx b/src/plugins/home/public/application/components/move_data/index.tsx new file mode 100644 index 00000000000000..f00275bf7b9240 --- /dev/null +++ b/src/plugins/home/public/application/components/move_data/index.tsx @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './move_data'; diff --git a/src/plugins/home/public/application/components/move_data/move_data.test.tsx b/src/plugins/home/public/application/components/move_data/move_data.test.tsx new file mode 100644 index 00000000000000..9c92afbf01ac37 --- /dev/null +++ b/src/plugins/home/public/application/components/move_data/move_data.test.tsx @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { MoveData } from './move_data'; +import { shallowWithIntl } from '@kbn/test-jest-helpers'; + +const addBasePathMock = jest.fn((path: string) => (path ? path : 'path')); + +describe('MoveData', () => { + test('renders as expected', () => { + const component = shallowWithIntl(); + + const $button = component.find('EuiButton'); + expect($button.props().href).toBe('/app/management/data/migrate_data'); + }); +}); diff --git a/src/plugins/home/public/application/components/move_data/move_data.tsx b/src/plugins/home/public/application/components/move_data/move_data.tsx new file mode 100644 index 00000000000000..ce97e71a6ecd89 --- /dev/null +++ b/src/plugins/home/public/application/components/move_data/move_data.tsx @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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, { FC, MouseEvent } from 'react'; +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiImage, + EuiPanel, + EuiSpacer, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { createAppNavigationHandler } from '../app_navigation_handler'; + +interface Props { + addBasePath: (path: string) => string; +} + +export const MoveData: FC = ({ addBasePath }) => { + const migrateDataUrl = '/app/management/data/migrate_data'; + const buttonLabel = ( + + ); + + return ( + + + + + + + +

    + +

    +
    + + + + + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} + { + createAppNavigationHandler(migrateDataUrl)(event); + }} + > + {buttonLabel} + +
    +
    +
    + ); +}; diff --git a/src/plugins/unified_field_list/public/utils/field_types/get_field_type_description.ts b/src/plugins/unified_field_list/public/utils/field_types/get_field_type_description.ts index a7b5b6ec3f05e8..8b7ab22b93ad56 100644 --- a/src/plugins/unified_field_list/public/utils/field_types/get_field_type_description.ts +++ b/src/plugins/unified_field_list/public/utils/field_types/get_field_type_description.ts @@ -34,7 +34,7 @@ export function getFieldTypeDescription(type?: string) { switch (knownType) { case KNOWN_FIELD_TYPES.DOCUMENT: return i18n.translate('unifiedFieldList.fieldNameDescription.recordField', { - defaultMessage: 'Number of records.', // TODO: add a better description + defaultMessage: 'Count of records.', }); case KNOWN_FIELD_TYPES.BOOLEAN: return i18n.translate('unifiedFieldList.fieldNameDescription.booleanField', { @@ -46,7 +46,8 @@ export function getFieldTypeDescription(type?: string) { }); case KNOWN_FIELD_TYPES.COUNTER: return i18n.translate('unifiedFieldList.fieldNameDescription.counterField', { - defaultMessage: 'Counter metric.', // TODO: add a better description + defaultMessage: + 'A number that only increases or resets to 0 (zero). Available only for numeric and aggregate_metric_double fields.', }); case KNOWN_FIELD_TYPES.DATE: return i18n.translate('unifiedFieldList.fieldNameDescription.dateField', { @@ -58,7 +59,8 @@ export function getFieldTypeDescription(type?: string) { }); case KNOWN_FIELD_TYPES.GAUGE: return i18n.translate('unifiedFieldList.fieldNameDescription.gaugeField', { - defaultMessage: 'Gauge metric.', // TODO: add a better description + defaultMessage: + 'A number that can increase or decrease. Available only for numeric and aggregate_metric_double fields.', }); case KNOWN_FIELD_TYPES.GEO_POINT: return i18n.translate('unifiedFieldList.fieldNameDescription.geoPointField', { diff --git a/src/plugins/unified_histogram/public/panels/panels_resizable.test.tsx b/src/plugins/unified_histogram/public/panels/panels_resizable.test.tsx index a21e137e87ed72..add0281cfc0fd5 100644 --- a/src/plugins/unified_histogram/public/panels/panels_resizable.test.tsx +++ b/src/plugins/unified_histogram/public/panels/panels_resizable.test.tsx @@ -176,22 +176,19 @@ describe('Panels resizable', () => { const attachTo = document.createElement('div'); document.body.appendChild(attachTo); const component = mountComponent({ attachTo }); - const wrapper = component.find('[data-test-subj="unifiedHistogramResizableContainerWrapper"]'); + const getContainer = () => + component.find('[data-test-subj="unifiedHistogramResizableContainer"]').at(0); const resizeButton = component.find('button[data-test-subj="unifiedHistogramResizableButton"]'); - const resizeButtonInner = component.find( - '[data-test-subj="unifiedHistogramResizableButtonInner"]' - ); - const mouseEvent = { - pageX: 0, - pageY: 0, - clientX: 0, - clientY: 0, - }; - resizeButtonInner.simulate('mousedown', mouseEvent); - resizeButton.simulate('mousedown', mouseEvent); + act(() => { + const onResizeStart = getContainer().prop('onResizeStart') as Function; + onResizeStart('pointer'); + }); (resizeButton.getDOMNode() as HTMLElement).focus(); - wrapper.simulate('mouseup', mouseEvent); - resizeButton.simulate('click', mouseEvent); + forceRender(component); + act(() => { + const onResizeEnd = getContainer().prop('onResizeEnd') as Function; + onResizeEnd(); + }); expect(resizeButton.getDOMNode()).toHaveFocus(); await waitFor(() => { expect(resizeButton.getDOMNode()).not.toHaveFocus(); diff --git a/src/plugins/unified_histogram/public/panels/panels_resizable.tsx b/src/plugins/unified_histogram/public/panels/panels_resizable.tsx index 76fecd42d2aedf..bbf4a70f90e9d4 100644 --- a/src/plugins/unified_histogram/public/panels/panels_resizable.tsx +++ b/src/plugins/unified_histogram/public/panels/panels_resizable.tsx @@ -12,6 +12,7 @@ import { useGeneratedHtmlId, useResizeObserver, } from '@elastic/eui'; +import type { ResizeTrigger } from '@elastic/eui/src/components/resizable_container/types'; import { css } from '@emotion/react'; import { isEqual, round } from 'lodash'; import type { ReactElement, RefObject } from 'react'; @@ -51,24 +52,23 @@ export const PanelsResizable = ({ // end to toggle the rendering of a transparent overlay which prevents the cancellation. // EUI issue: https://github.com/elastic/eui/issues/6199 const [resizeWithPortalsHackIsResizing, setResizeWithPortalsHackIsResizing] = useState(false); - const enableResizeWithPortalsHack = () => setResizeWithPortalsHackIsResizing(true); - const disableResizeWithPortalsHack = () => setResizeWithPortalsHackIsResizing(false); - const resizeWithPortalsHackFillCss = css` + const enableResizeWithPortalsHack = useCallback( + () => setResizeWithPortalsHackIsResizing(true), + [] + ); + const disableResizeWithPortalsHack = useCallback( + () => setResizeWithPortalsHackIsResizing(false), + [] + ); + const resizeWithPortalsHackButtonCss = css` + z-index: 3; + `; + const resizeWithPortalsHackOverlayCss = css` position: absolute; top: 0; left: 0; width: 100%; height: 100%; - `; - const resizeWithPortalsHackButtonCss = css` - z-index: 3; - `; - const resizeWithPortalsHackButtonInnerCss = css` - ${resizeWithPortalsHackFillCss} - z-index: 1; - `; - const resizeWithPortalsHackOverlayCss = css` - ${resizeWithPortalsHackFillCss} z-index: 2; `; @@ -133,11 +133,26 @@ export const PanelsResizable = ({ } }, [containerHeight, minMainPanelHeight, minTopPanelHeight, panelSizes, topPanelHeight]); - const onResizeEnd = () => { + const onResizeStart = useCallback( + (trigger: ResizeTrigger) => { + if (trigger !== 'pointer') { + return; + } + + enableResizeWithPortalsHack(); + }, + [enableResizeWithPortalsHack] + ); + + const onResizeEnd = useCallback(() => { + if (!resizeWithPortalsHackIsResizing) { + return; + } + // We don't want the resize button to retain focus after the resize is complete, // but EuiResizableContainer will force focus it onClick. To work around this we // use setTimeout to wait until after onClick has been called before blurring. - if (resizeWithPortalsHackIsResizing && document.activeElement instanceof HTMLElement) { + if (document.activeElement instanceof HTMLElement) { const button = document.activeElement; setTimeout(() => { button.blur(); @@ -145,7 +160,7 @@ export const PanelsResizable = ({ } disableResizeWithPortalsHack(); - }; + }, [disableResizeWithPortalsHack, resizeWithPortalsHackIsResizing]); const { euiTheme } = useEuiTheme(); const buttonCss = css` @@ -156,57 +171,40 @@ export const PanelsResizable = ({ `; return ( -
    - - {(EuiResizablePanel, EuiResizableButton) => ( - <> - - {topPanel} - - - - - - {mainPanel} - - {resizeWithPortalsHackIsResizing ? ( -
    - ) : ( - <> - )} - - )} - -
    + {(EuiResizablePanel, EuiResizableButton) => ( + <> + + {topPanel} + + + + {mainPanel} + + {resizeWithPortalsHackIsResizing ?
    : <>} + + )} + ); }; diff --git a/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx b/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx index d17ef6beeab605..50e246c089bca4 100644 --- a/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx +++ b/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx @@ -25,14 +25,13 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { + type Filter, BooleanRelation, buildCombinedFilter, buildCustomFilter, buildEmptyFilter, - cleanFilter, - Filter, + filterToQueryDsl, getFilterParams, - isCombinedFilter, } from '@kbn/es-query'; import { merge } from 'lodash'; import React, { Component } from 'react'; @@ -76,10 +75,6 @@ export const strings = { i18n.translate('unifiedSearch.filter.filterEditor.updateButtonLabel', { defaultMessage: 'Update filter', }), - getDisableToggleModeTooltip: () => - i18n.translate('unifiedSearch.filter.filterEditor.disableToggleModeTooltip', { - defaultMessage: '"Edit as Query DSL" operation is not supported for combined filters', - }), getSelectDataViewToolTip: () => i18n.translate('unifiedSearch.filter.filterEditor.chooseDataViewFirstToolTip', { defaultMessage: 'You need to select a data view first', @@ -159,13 +154,11 @@ class FilterEditorComponent extends Component { } private parseFilterToQueryDsl(filter: Filter) { - return JSON.stringify(cleanFilter(filter), null, 2); + const dsl = filterToQueryDsl(filter, this.props.indexPatterns); + return JSON.stringify(dsl, null, 2); } public render() { - const { localFilter } = this.state; - const shouldDisableToggle = isCombinedFilter(localFilter); - return (
    @@ -180,30 +173,23 @@ class FilterEditorComponent extends Component { - - - {this.state.isCustomEditorOpen ? ( - - ) : ( - - )} - - + {this.state.isCustomEditorOpen ? ( + + ) : ( + + )} + diff --git a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx index fcd6cb94a17472..d994f35c1ff376 100644 --- a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx +++ b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx @@ -389,7 +389,7 @@ function FilterItemComponent(props: FilterItemProps) { onSubmit={onSubmit} onLocalFilterUpdate={onLocalFilterUpdate} onLocalFilterCreate={onLocalFilterCreate} - onCancel={closePopover} + onCancel={() => setIsPopoverOpen(false)} timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} />
    , diff --git a/src/plugins/unified_search/public/query_string_input/add_filter_popover.tsx b/src/plugins/unified_search/public/query_string_input/add_filter_popover.tsx index 796db77c6be2f8..2f65274c99c13d 100644 --- a/src/plugins/unified_search/public/query_string_input/add_filter_popover.tsx +++ b/src/plugins/unified_search/public/query_string_input/add_filter_popover.tsx @@ -102,7 +102,9 @@ const AddFilterPopoverComponent = React.memo(function AddFilterPopover({ closePopoverOnAdd={() => { setShowAddFilterPopover(false); }} - closePopoverOnCancel={closePopover} + closePopoverOnCancel={() => { + setShowAddFilterPopover(false); + }} /> diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_menu.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_menu.tsx index 4a31214d2f6ae5..0c742daebd836d 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_menu.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_menu.tsx @@ -190,7 +190,7 @@ function QueryBarMenuComponent({ onLocalFilterUpdate={onLocalFilterUpdate} onLocalFilterCreate={onLocalFilterCreate} closePopoverOnAdd={plainClosePopover} - closePopoverOnCancel={closePopover} + closePopoverOnCancel={plainClosePopover} />, ]} /> 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 d522991778eadf..9ef1772ed47d8c 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 @@ -193,45 +193,47 @@ export function createSearchBar({ ...core, }} > - + + + ); }; diff --git a/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.test.ts b/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.test.ts index 0b2bab509341df..de88fb0a7a866b 100644 --- a/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.test.ts +++ b/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.test.ts @@ -68,7 +68,7 @@ describe('getConfiguration', () => { }) ).toEqual({ colorMode: 'palette', - labelMajorMode: 'none', + labelMajorMode: 'auto', labelMinor: undefined, layerId: 'layer-id', layerType: 'data', diff --git a/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.ts b/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.ts index 9a5483d038c2ec..9da64a38f88117 100644 --- a/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.ts +++ b/src/plugins/vis_types/gauge/public/convert_to_lens/configurations/gauge.ts @@ -34,7 +34,7 @@ export const getConfiguration = ( maxAccessor, shape: 'horizontalBullet', ticksPosition: 'bands', - labelMajorMode: showLabels ? 'auto' : 'none', + labelMajorMode: 'auto', colorMode: palette ? 'palette' : 'none', labelMinor: showLabels ? params.gauge.style.subText : undefined, }; diff --git a/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts b/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts index b70404f1338bf7..4fc9101ed67a5a 100644 --- a/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts +++ b/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts @@ -196,7 +196,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('Creating "does not exist" query from first control filters the second and third controls', async () => { await dashboardControls.optionsListOpenPopover(controlIds[0]); - await dashboardControls.optionsListPopoverSelectOption('exists'); + await dashboardControls.optionsListPopoverSelectExists(); await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); await dashboard.waitForRenderComplete(); diff --git a/test/functional/apps/dashboard_elements/controls/options_list.ts b/test/functional/apps/dashboard_elements/controls/options_list.ts deleted file mode 100644 index 8186d9702ae3eb..00000000000000 --- a/test/functional/apps/dashboard_elements/controls/options_list.ts +++ /dev/null @@ -1,783 +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 { pick } from 'lodash'; - -import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; -import expect from '@kbn/expect'; - -import { OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS } from '../../../page_objects/dashboard_page_controls'; -import { FtrProviderContext } from '../../../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const retry = getService('retry'); - const queryBar = getService('queryBar'); - const pieChart = getService('pieChart'); - const security = getService('security'); - const elasticChart = getService('elasticChart'); - const filterBar = getService('filterBar'); - const testSubjects = getService('testSubjects'); - const dashboardAddPanel = getService('dashboardAddPanel'); - const dashboardPanelActions = getService('dashboardPanelActions'); - - const { dashboardControls, timePicker, console, common, dashboard, header, settings } = - getPageObjects([ - 'dashboardControls', - 'timePicker', - 'dashboard', - 'settings', - 'console', - 'common', - 'header', - ]); - - const DASHBOARD_NAME = 'Test Options List Control'; - - describe('Dashboard options list integration', () => { - let controlId: string; - - const returnToDashboard = async () => { - await common.navigateToApp('dashboard'); - await header.waitUntilLoadingHasFinished(); - await elasticChart.setNewChartUiDebugFlag(); - await dashboard.loadSavedDashboard(DASHBOARD_NAME); - if (await dashboard.getIsInViewMode()) { - await dashboard.switchToEditMode(); - } - await dashboard.waitForRenderComplete(); - }; - - before(async () => { - await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']); - - await common.navigateToApp('dashboard'); - await dashboard.gotoDashboardLandingPage(); - await dashboard.clickNewDashboard(); - await timePicker.setDefaultDataRange(); - await elasticChart.setNewChartUiDebugFlag(); - await dashboard.saveDashboard(DASHBOARD_NAME, { - exitFromEditMode: false, - storeTimeWithDashboard: true, - }); - }); - - describe('Options List Control Editor selects relevant data views', async () => { - it('selects the default data view when the dashboard is blank', async () => { - expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( - 'logstash-*' - ); - }); - - it('selects a relevant data view based on the panels on the dashboard', async () => { - await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie'); - await dashboard.waitForRenderComplete(); - expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( - 'animals-*' - ); - await dashboardPanelActions.removePanelByTitle('Rendering Test: animal sounds pie'); - await dashboard.waitForRenderComplete(); - expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( - 'logstash-*' - ); - }); - - it('selects the last used data view by default', async () => { - await dashboardControls.createControl({ - controlType: OPTIONS_LIST_CONTROL, - dataViewTitle: 'animals-*', - fieldName: 'sound.keyword', - }); - expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( - 'animals-*' - ); - await dashboardControls.deleteAllControls(); - }); - }); - - // Skip on cloud until issue is fixed - // Issue: https://github.com/elastic/kibana/issues/141280 - describe('Options List Control creation and editing experience', function () { - this.tags(['skipCloudFailedTest']); - it('can add a new options list control from a blank state', async () => { - await dashboardControls.createControl({ - controlType: OPTIONS_LIST_CONTROL, - dataViewTitle: 'logstash-*', - fieldName: 'machine.os.raw', - }); - expect(await dashboardControls.getControlsCount()).to.be(1); - await dashboard.clearUnsavedChanges(); - }); - - it('can add a second options list control with a non-default data view', async () => { - await dashboardControls.createControl({ - controlType: OPTIONS_LIST_CONTROL, - dataViewTitle: 'animals-*', - fieldName: 'sound.keyword', - }); - expect(await dashboardControls.getControlsCount()).to.be(2); - - // data views should be properly propagated from the control group to the dashboard - expect(await filterBar.getIndexPatterns()).to.be('logstash-*,animals-*'); - await dashboard.clearUnsavedChanges(); - }); - - it('renames an existing control', async () => { - const secondId = (await dashboardControls.getAllControlIds())[1]; - - const newTitle = 'wow! Animal sounds?'; - await dashboardControls.editExistingControl(secondId); - await dashboardControls.controlEditorSetTitle(newTitle); - await dashboardControls.controlEditorSave(); - expect(await dashboardControls.doesControlTitleExist(newTitle)).to.be(true); - await dashboard.clearUnsavedChanges(); - }); - - it('can change the data view and field of an existing options list', async () => { - const firstId = (await dashboardControls.getAllControlIds())[0]; - await dashboardControls.editExistingControl(firstId); - - const saveButton = await testSubjects.find('control-editor-save'); - expect(await saveButton.isEnabled()).to.be(true); - await dashboardControls.controlsEditorSetDataView('animals-*'); - expect(await saveButton.isEnabled()).to.be(false); - await dashboardControls.controlsEditorSetfield('animal.keyword', OPTIONS_LIST_CONTROL); - await dashboardControls.controlEditorSave(); - - // when creating a new filter, the ability to select a data view should be removed, because the dashboard now only has one data view - await retry.try(async () => { - await testSubjects.click('addFilter'); - const indexPatternSelectExists = await testSubjects.exists('filterIndexPatternsSelect'); - await filterBar.ensureFieldEditorModalIsClosed(); - expect(indexPatternSelectExists).to.be(false); - }); - await dashboard.clearUnsavedChanges(); - }); - - it('editing field clears selections', async () => { - const secondId = (await dashboardControls.getAllControlIds())[1]; - await dashboardControls.optionsListOpenPopover(secondId); - await dashboardControls.optionsListPopoverSelectOption('hiss'); - await dashboardControls.optionsListEnsurePopoverIsClosed(secondId); - - await dashboardControls.editExistingControl(secondId); - await dashboardControls.controlsEditorSetfield('animal.keyword', OPTIONS_LIST_CONTROL); - await dashboardControls.controlEditorSave(); - - const selectionString = await dashboardControls.optionsListGetSelectionsString(secondId); - expect(selectionString).to.be('Any'); - }); - - it('editing other control settings keeps selections', async () => { - const secondId = (await dashboardControls.getAllControlIds())[1]; - await dashboardControls.optionsListOpenPopover(secondId); - await dashboardControls.optionsListPopoverSelectOption('dog'); - await dashboardControls.optionsListPopoverSelectOption('cat'); - await dashboardControls.optionsListEnsurePopoverIsClosed(secondId); - - await dashboardControls.editExistingControl(secondId); - await dashboardControls.controlEditorSetTitle('Animal'); - await dashboardControls.controlEditorSetWidth('large'); - await dashboardControls.controlEditorSave(); - - const selectionString = await dashboardControls.optionsListGetSelectionsString(secondId); - expect(selectionString).to.be('dog, cat'); - }); - - it('deletes an existing control', async () => { - const firstId = (await dashboardControls.getAllControlIds())[0]; - - await dashboardControls.removeExistingControl(firstId); - expect(await dashboardControls.getControlsCount()).to.be(1); - await dashboard.clearUnsavedChanges(); - }); - - it('cannot create options list for scripted field', async () => { - await dashboardControls.openCreateControlFlyout(); - expect(await dashboardControls.optionsListEditorGetCurrentDataView(false)).to.eql( - 'animals-*' - ); - await testSubjects.missingOrFail('field-picker-select-isDog'); - await dashboardControls.controlEditorCancel(true); - }); - - after(async () => { - await dashboardControls.clearAllControls(); - }); - }); - - describe('Options List Control suggestions', async () => { - before(async () => { - await dashboardControls.createControl({ - controlType: OPTIONS_LIST_CONTROL, - dataViewTitle: 'animals-*', - fieldName: 'sound.keyword', - }); - controlId = (await dashboardControls.getAllControlIds())[0]; - await dashboard.clickQuickSave(); - await header.waitUntilLoadingHasFinished(); - - await dashboardControls.optionsListOpenPopover(controlId); - }); - - it('sort alphabetically - descending', async () => { - await dashboardControls.optionsListPopoverSetSort({ by: '_key', direction: 'desc' }); - await dashboardControls.optionsListWaitForLoading(controlId); - - const sortedSuggestions = Object.keys(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS) - .sort() - .reverse() - .reduce((result, key) => { - return { ...result, [key]: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS[key] }; - }, {}); - await dashboardControls.ensureAvailableOptionsEqual( - controlId, - { suggestions: sortedSuggestions, invalidSelections: [] }, - true - ); - }); - - it('sort alphabetically - ascending', async () => { - await dashboardControls.optionsListPopoverSetSort({ by: '_key', direction: 'asc' }); - await dashboardControls.optionsListWaitForLoading(controlId); - - const sortedSuggestions = Object.keys(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS) - .sort() - .reduce((result, key) => { - return { ...result, [key]: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS[key] }; - }, {}); - await dashboardControls.ensureAvailableOptionsEqual( - controlId, - { suggestions: sortedSuggestions, invalidSelections: [] }, - true - ); - }); - - it('sort by document count - descending', async () => { - await dashboardControls.optionsListPopoverSetSort({ by: '_count', direction: 'desc' }); - await dashboardControls.optionsListWaitForLoading(controlId); - await dashboardControls.ensureAvailableOptionsEqual( - controlId, - { - suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, // keys are already sorted descending by doc count - invalidSelections: [], - }, - true - ); - }); - - it('sort by document count - ascending', async () => { - await dashboardControls.optionsListPopoverSetSort({ by: '_count', direction: 'asc' }); - await dashboardControls.optionsListWaitForLoading(controlId); - const sortedSuggestions = Object.entries(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS) - .sort(([, docCountA], [, docCountB]) => { - return docCountB - docCountA; - }) - .reduce((result, [key, docCount]) => { - return { ...result, [key]: docCount }; - }, {}); - await dashboardControls.ensureAvailableOptionsEqual( - controlId, - { suggestions: sortedSuggestions, invalidSelections: [] }, - true - ); - }); - - it('non-default value should cause unsaved changes', async () => { - await testSubjects.existOrFail('dashboardUnsavedChangesBadge'); - }); - - it('returning to default value should remove unsaved changes', async () => { - await dashboardControls.optionsListPopoverSetSort({ by: '_count', direction: 'desc' }); - await dashboardControls.optionsListWaitForLoading(controlId); - await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); - }); - - after(async () => { - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - }); - }); - - describe('Interactions between options list and dashboard', async () => { - before(async () => { - await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie'); - }); - - describe('Applies query settings to controls', async () => { - it('Applies dashboard query to options list control', async () => { - await queryBar.setQuery('animal.keyword : "dog" '); - await queryBar.submitQuery(); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - - const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ - 'ruff', - 'bark', - 'grrr', - 'bow ow ow', - 'grr', - ]); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: { ...suggestions, grr: suggestions.grr - 1 }, - invalidSelections: [], - }); - await queryBar.setQuery(''); - await queryBar.submitQuery(); - - // using the query hides the time range. Clicking anywhere else shows it again. - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - }); - - it('Applies dashboard time range to options list control', async () => { - // set time range to time with no documents - await timePicker.setAbsoluteRange( - 'Jan 1, 2017 @ 00:00:00.000', - 'Jan 1, 2017 @ 00:00:00.000' - ); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - - await dashboardControls.optionsListOpenPopover(controlId); - expect(await dashboardControls.optionsListPopoverGetAvailableOptionsCount()).to.be(0); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await timePicker.setDefaultDataRange(); - }); - - describe('dashboard filters', async () => { - before(async () => { - await filterBar.addFilter({ - field: 'sound.keyword', - operation: 'is one of', - value: ['bark', 'bow ow ow', 'ruff'], - }); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - }); - - it('Applies dashboard filters to options list control', async () => { - const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ - 'ruff', - 'bark', - 'bow ow ow', - ]); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions, - invalidSelections: [], - }); - }); - - it('Does not apply disabled dashboard filters to options list control', async () => { - await filterBar.toggleFilterEnabled('sound.keyword'); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, - invalidSelections: [], - }); - await filterBar.toggleFilterEnabled('sound.keyword'); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - }); - - it('Negated filters apply to options control', async () => { - await filterBar.toggleFilterNegated('sound.keyword'); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - - const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ - 'hiss', - 'grrr', - 'meow', - 'growl', - 'grr', - ]); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions, - invalidSelections: [], - }); - }); - - after(async () => { - await filterBar.removeAllFilters(); - }); - }); - }); - - describe('Selections made in control apply to dashboard', async () => { - it('Shows available options in options list', async () => { - await queryBar.setQuery(''); - await queryBar.submitQuery(); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, - invalidSelections: [], - }); - }); - - it('Can search options list for available options', async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSearchForOption('meo'); - await dashboardControls.ensureAvailableOptionsEqual( - controlId, - { - suggestions: { meow: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.meow }, - invalidSelections: [], - }, - true - ); - await dashboardControls.optionsListPopoverClearSearch(); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - }); - - it('Can search options list for available options case insensitive', async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSearchForOption('MEO'); - await dashboardControls.ensureAvailableOptionsEqual( - controlId, - { - suggestions: { meow: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.meow }, - invalidSelections: [], - }, - true - ); - await dashboardControls.optionsListPopoverClearSearch(); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - }); - - it('Can select multiple available options', async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSelectOption('hiss'); - await dashboardControls.optionsListPopoverSelectOption('grr'); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - }); - - it('Selected options appear in control', async () => { - const selectionString = await dashboardControls.optionsListGetSelectionsString(controlId); - expect(selectionString).to.be('hiss, grr'); - }); - - it('Applies options list control options to dashboard', async () => { - await retry.try(async () => { - expect(await pieChart.getPieSliceCount()).to.be(2); - }); - }); - - it('Applies options list control options to dashboard by default on open', async () => { - await dashboard.gotoDashboardLandingPage(); - await header.waitUntilLoadingHasFinished(); - await dashboard.clickUnsavedChangesContinueEditing(DASHBOARD_NAME); - await header.waitUntilLoadingHasFinished(); - expect(await pieChart.getPieSliceCount()).to.be(2); - - const selectionString = await dashboardControls.optionsListGetSelectionsString(controlId); - expect(selectionString).to.be('hiss, grr'); - }); - - it('excluding selections has expected results', async () => { - await dashboard.clickQuickSave(); - await dashboard.waitForRenderComplete(); - - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSetIncludeSelections(false); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); - - expect(await pieChart.getPieSliceCount()).to.be(5); - await dashboard.clearUnsavedChanges(); - }); - - it('including selections has expected results', async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSetIncludeSelections(true); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); - - expect(await pieChart.getPieSliceCount()).to.be(2); - await dashboard.clearUnsavedChanges(); - }); - - it('changes to selections can be discarded', async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSelectOption('bark'); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - let selections = await dashboardControls.optionsListGetSelectionsString(controlId); - expect(selections).to.equal('hiss, grr, bark'); - - await dashboard.clickCancelOutOfEditMode(); - selections = await dashboardControls.optionsListGetSelectionsString(controlId); - expect(selections).to.equal('hiss, grr'); - }); - - it('dashboard does not load with unsaved changes when changes are discarded', async () => { - await dashboard.switchToEditMode(); - await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); - }); - }); - - describe('test data view runtime field', async () => { - const FIELD_NAME = 'testRuntimeField'; - const FIELD_VALUES = { - G: - OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.growl + - OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.grr + - OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.grrr, - H: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.hiss, - B: - OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.bark + - OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS['bow ow ow'], - R: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.ruff, - M: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.meow, - }; - - before(async () => { - await common.navigateToApp('settings'); - await settings.clickKibanaIndexPatterns(); - await settings.clickIndexPatternByName('animals-*'); - await settings.addRuntimeField( - FIELD_NAME, - 'keyword', - `emit(doc['sound.keyword'].value.substring(0, 1).toUpperCase())` - ); - await header.waitUntilLoadingHasFinished(); - - await returnToDashboard(); - await dashboardControls.deleteAllControls(); - }); - - it('can create options list control on runtime field', async () => { - await dashboardControls.createControl({ - controlType: OPTIONS_LIST_CONTROL, - fieldName: FIELD_NAME, - dataViewTitle: 'animals-*', - }); - expect(await dashboardControls.getControlsCount()).to.be(1); - }); - - it('new control has expected suggestions', async () => { - controlId = (await dashboardControls.getAllControlIds())[0]; - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: FIELD_VALUES, - invalidSelections: [], - }); - }); - - it('making selection has expected results', async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSelectOption('B'); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); - - expect(await pieChart.getPieChartLabels()).to.eql(['bark', 'bow ow ow']); - }); - - after(async () => { - await dashboardControls.deleteAllControls(); - await dashboard.clickQuickSave(); - await header.waitUntilLoadingHasFinished(); - - await common.navigateToApp('settings'); - await settings.clickKibanaIndexPatterns(); - await settings.clickIndexPatternByName('animals-*'); - await settings.filterField('testRuntimeField'); - await testSubjects.click('deleteField'); - await settings.confirmDelete(); - }); - }); - - describe('test exists query', async () => { - const newDocuments: Array<{ index: string; id: string }> = []; - - const addDocument = async (index: string, document: string) => { - await console.enterRequest('\nPOST ' + index + '/_doc/ \n{\n ' + document); - await console.clickPlay(); - await header.waitUntilLoadingHasFinished(); - const response = JSON.parse(await console.getResponse()); - newDocuments.push({ index, id: response._id }); - }; - - before(async () => { - await common.navigateToApp('console'); - await console.collapseHelp(); - await console.clearTextArea(); - await addDocument( - 'animals-cats-2018-01-01', - '"@timestamp": "2018-01-01T16:00:00.000Z", \n"name": "Rosie", \n"sound": "hiss"' - ); - await returnToDashboard(); - - await dashboardControls.createControl({ - controlType: OPTIONS_LIST_CONTROL, - dataViewTitle: 'animals-*', - fieldName: 'animal.keyword', - title: 'Animal', - }); - controlId = (await dashboardControls.getAllControlIds())[0]; - await header.waitUntilLoadingHasFinished(); - await dashboard.waitForRenderComplete(); - }); - - it('creating exists query has expected results', async () => { - expect((await pieChart.getPieChartValues())[0]).to.be(6); - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSelectOption('exists'); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); - - expect(await pieChart.getPieSliceCount()).to.be(5); - expect((await pieChart.getPieChartValues())[0]).to.be(5); - }); - - it('negating exists query has expected results', async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSetIncludeSelections(false); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); - - expect(await pieChart.getPieSliceCount()).to.be(1); - expect((await pieChart.getPieChartValues())[0]).to.be(1); - }); - - after(async () => { - await common.navigateToApp('console'); - await console.clearTextArea(); - for (const { index, id } of newDocuments) { - await console.enterRequest(`\nDELETE /${index}/_doc/${id}`); - await console.clickPlay(); - await header.waitUntilLoadingHasFinished(); - } - - await returnToDashboard(); - await dashboardControls.deleteAllControls(); - }); - }); - - describe('Options List dashboard validation', async () => { - before(async () => { - await dashboardControls.createControl({ - controlType: OPTIONS_LIST_CONTROL, - dataViewTitle: 'animals-*', - fieldName: 'sound.keyword', - title: 'Animal Sounds', - }); - controlId = (await dashboardControls.getAllControlIds())[0]; - - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSelectOption('meow'); - await dashboardControls.optionsListPopoverSelectOption('bark'); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - }); - - after(async () => { - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverClearSelections(); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await filterBar.removeAllFilters(); - }); - - it('Can mark selections invalid with Query', async () => { - await queryBar.setQuery('NOT animal.keyword : "dog" '); - await queryBar.submitQuery(); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - - const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ - 'hiss', - 'meow', - 'growl', - 'grr', - ]); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: { ...suggestions, grr: suggestions.grr - 1 }, - invalidSelections: ['bark'], - }); - // only valid selections are applied as filters. - expect(await pieChart.getPieSliceCount()).to.be(1); - }); - - it('can make invalid selections valid again if the parent filter changes', async () => { - await queryBar.setQuery(''); - await queryBar.submitQuery(); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, - invalidSelections: [], - }); - expect(await pieChart.getPieSliceCount()).to.be(2); - }); - - it('Can mark multiple selections invalid with Filter', async () => { - await filterBar.addFilter({ field: 'sound.keyword', operation: 'is', value: 'hiss' }); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: { - hiss: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.hiss, - }, - invalidSelections: ['meow', 'bark'], - }); - // only valid selections are applied as filters. - expect(await pieChart.getPieSliceCount()).to.be(1); - }); - }); - - describe('Options List dashboard no validation', async () => { - before(async () => { - await filterBar.removeAllFilters(); - await queryBar.clickQuerySubmitButton(); - await dashboardControls.optionsListOpenPopover(controlId); - await dashboardControls.optionsListPopoverSelectOption('meow'); - await dashboardControls.optionsListPopoverSelectOption('bark'); - await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboardControls.updateValidationSetting(false); - }); - - it('Does not mark selections invalid with Query', async () => { - await queryBar.setQuery('NOT animal.keyword : "dog" '); - await queryBar.submitQuery(); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - - const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ - 'hiss', - 'meow', - 'growl', - 'grr', - ]); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: { ...suggestions, grr: suggestions.grr - 1 }, - invalidSelections: [], - }); - }); - - it('Does not mark multiple selections invalid with Filter', async () => { - await filterBar.addFilter({ field: 'sound.keyword', operation: 'is', value: 'hiss' }); - await dashboard.waitForRenderComplete(); - await header.waitUntilLoadingHasFinished(); - await dashboardControls.ensureAvailableOptionsEqual(controlId, { - suggestions: { - hiss: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.hiss, - }, - invalidSelections: [], - }); - }); - }); - - after(async () => { - await filterBar.removeAllFilters(); - await queryBar.clickQuerySubmitButton(); - await dashboardControls.clearAllControls(); - }); - }); - - after(async () => { - await security.testUser.restoreDefaults(); - }); - }); -} diff --git a/test/functional/apps/dashboard_elements/controls/options_list/index.ts b/test/functional/apps/dashboard_elements/controls/options_list/index.ts new file mode 100644 index 00000000000000..9d4cb7d18d525d --- /dev/null +++ b/test/functional/apps/dashboard_elements/controls/options_list/index.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export const OPTIONS_LIST_DASHBOARD_NAME = 'Test Options List Control'; + +export default function ({ loadTestFile, getService, getPageObjects }: FtrProviderContext) { + const elasticChart = getService('elasticChart'); + const security = getService('security'); + + const { timePicker, dashboard } = getPageObjects([ + 'dashboardControls', + 'timePicker', + 'dashboard', + 'common', + ]); + + async function setup() { + await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']); + + await dashboard.gotoDashboardLandingPage(); + await dashboard.clickNewDashboard(); + await timePicker.setDefaultDataRange(); + await elasticChart.setNewChartUiDebugFlag(); + await dashboard.saveDashboard(OPTIONS_LIST_DASHBOARD_NAME, { + exitFromEditMode: false, + storeTimeWithDashboard: true, + }); + } + + async function teardown() { + await security.testUser.restoreDefaults(); + } + + describe('Options list control', function () { + before(setup); + after(teardown); + + loadTestFile(require.resolve('./options_list_creation_and_editing')); + loadTestFile(require.resolve('./options_list_dashboard_interaction')); + loadTestFile(require.resolve('./options_list_suggestions')); + loadTestFile(require.resolve('./options_list_validation')); + }); +} diff --git a/test/functional/apps/dashboard_elements/controls/options_list/options_list_creation_and_editing.ts b/test/functional/apps/dashboard_elements/controls/options_list/options_list_creation_and_editing.ts new file mode 100644 index 00000000000000..2281c5ce112be3 --- /dev/null +++ b/test/functional/apps/dashboard_elements/controls/options_list/options_list_creation_and_editing.ts @@ -0,0 +1,181 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const retry = getService('retry'); + const filterBar = getService('filterBar'); + const testSubjects = getService('testSubjects'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const dashboardPanelActions = getService('dashboardPanelActions'); + + const { dashboardControls, dashboard } = getPageObjects([ + 'dashboardControls', + 'timePicker', + 'dashboard', + 'settings', + 'console', + 'common', + 'header', + ]); + + describe('Dashboard options list creation and editing', () => { + before(async () => { + await dashboard.ensureDashboardIsInEditMode(); + }); + + after(async () => { + await dashboardControls.deleteAllControls(); + await dashboard.clickQuickSave(); + }); + + describe('Options List Control Editor selects relevant data views', async () => { + it('selects the default data view when the dashboard is blank', async () => { + expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( + 'logstash-*' + ); + }); + + it('selects a relevant data view based on the panels on the dashboard', async () => { + await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie'); + await dashboard.waitForRenderComplete(); + expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( + 'animals-*' + ); + await dashboard.waitForRenderComplete(); + await dashboardPanelActions.removePanelByTitle('Rendering Test: animal sounds pie'); + expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( + 'logstash-*' + ); + }); + + it('selects the last used data view by default', async () => { + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'sound.keyword', + }); + expect(await dashboardControls.optionsListEditorGetCurrentDataView(true)).to.eql( + 'animals-*' + ); + await dashboardControls.deleteAllControls(); + }); + }); + + // Skip on cloud until issue is fixed + // Issue: https://github.com/elastic/kibana/issues/141280 + describe('Options List Control creation and editing experience', function () { + this.tags(['skipCloudFailedTest']); + it('can add a new options list control from a blank state', async () => { + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'logstash-*', + fieldName: 'machine.os.raw', + }); + expect(await dashboardControls.getControlsCount()).to.be(1); + await dashboard.clearUnsavedChanges(); + }); + + it('can add a second options list control with a non-default data view', async () => { + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'sound.keyword', + }); + expect(await dashboardControls.getControlsCount()).to.be(2); + + // data views should be properly propagated from the control group to the dashboard + expect(await filterBar.getIndexPatterns()).to.be('logstash-*,animals-*'); + await dashboard.clearUnsavedChanges(); + }); + + it('renames an existing control', async () => { + const secondId = (await dashboardControls.getAllControlIds())[1]; + + const newTitle = 'wow! Animal sounds?'; + await dashboardControls.editExistingControl(secondId); + await dashboardControls.controlEditorSetTitle(newTitle); + await dashboardControls.controlEditorSave(); + expect(await dashboardControls.doesControlTitleExist(newTitle)).to.be(true); + await dashboard.clearUnsavedChanges(); + }); + + it('can change the data view and field of an existing options list', async () => { + const firstId = (await dashboardControls.getAllControlIds())[0]; + await dashboardControls.editExistingControl(firstId); + + const saveButton = await testSubjects.find('control-editor-save'); + expect(await saveButton.isEnabled()).to.be(true); + await dashboardControls.controlsEditorSetDataView('animals-*'); + expect(await saveButton.isEnabled()).to.be(false); + await dashboardControls.controlsEditorSetfield('animal.keyword', OPTIONS_LIST_CONTROL); + await dashboardControls.controlEditorSave(); + + // when creating a new filter, the ability to select a data view should be removed, because the dashboard now only has one data view + await retry.try(async () => { + await testSubjects.click('addFilter'); + const indexPatternSelectExists = await testSubjects.exists('filterIndexPatternsSelect'); + await filterBar.ensureFieldEditorModalIsClosed(); + expect(indexPatternSelectExists).to.be(false); + }); + await dashboard.clearUnsavedChanges(); + }); + + it('editing field clears selections', async () => { + const secondId = (await dashboardControls.getAllControlIds())[1]; + await dashboardControls.optionsListOpenPopover(secondId); + await dashboardControls.optionsListPopoverSelectOption('hiss'); + await dashboardControls.optionsListEnsurePopoverIsClosed(secondId); + + await dashboardControls.editExistingControl(secondId); + await dashboardControls.controlsEditorSetfield('animal.keyword', OPTIONS_LIST_CONTROL); + await dashboardControls.controlEditorSave(); + + const selectionString = await dashboardControls.optionsListGetSelectionsString(secondId); + expect(selectionString).to.be('Any'); + }); + + it('editing other control settings keeps selections', async () => { + const secondId = (await dashboardControls.getAllControlIds())[1]; + await dashboardControls.optionsListOpenPopover(secondId); + await dashboardControls.optionsListPopoverSelectOption('dog'); + await dashboardControls.optionsListPopoverSelectOption('cat'); + await dashboardControls.optionsListEnsurePopoverIsClosed(secondId); + + await dashboardControls.editExistingControl(secondId); + await dashboardControls.controlEditorSetTitle('Animal'); + await dashboardControls.controlEditorSetWidth('large'); + await dashboardControls.controlEditorSave(); + + const selectionString = await dashboardControls.optionsListGetSelectionsString(secondId); + expect(selectionString).to.be('dog, cat'); + }); + + it('deletes an existing control', async () => { + const firstId = (await dashboardControls.getAllControlIds())[0]; + + await dashboardControls.removeExistingControl(firstId); + expect(await dashboardControls.getControlsCount()).to.be(1); + await dashboard.clearUnsavedChanges(); + }); + + it('cannot create options list for scripted field', async () => { + await dashboardControls.openCreateControlFlyout(); + expect(await dashboardControls.optionsListEditorGetCurrentDataView(false)).to.eql( + 'animals-*' + ); + await testSubjects.missingOrFail('field-picker-select-isDog'); + await dashboardControls.controlEditorCancel(true); + }); + }); + }); +} diff --git a/test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts b/test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts new file mode 100644 index 00000000000000..43bde4798e3d53 --- /dev/null +++ b/test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts @@ -0,0 +1,413 @@ +/* + * Copyright 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 { pick } from 'lodash'; + +import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; +import expect from '@kbn/expect'; + +import { OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS } from '../../../../page_objects/dashboard_page_controls'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; +import { OPTIONS_LIST_DASHBOARD_NAME } from '.'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const retry = getService('retry'); + const queryBar = getService('queryBar'); + const pieChart = getService('pieChart'); + const elasticChart = getService('elasticChart'); + const filterBar = getService('filterBar'); + const testSubjects = getService('testSubjects'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const dashboardPanelActions = getService('dashboardPanelActions'); + + const { dashboardControls, timePicker, console, common, dashboard, header, settings } = + getPageObjects([ + 'dashboardControls', + 'timePicker', + 'dashboard', + 'settings', + 'console', + 'common', + 'header', + ]); + + describe('Interactions between options list and dashboard', () => { + let controlId: string; + + const returnToDashboard = async () => { + await common.navigateToApp('dashboard'); + await header.waitUntilLoadingHasFinished(); + await elasticChart.setNewChartUiDebugFlag(); + await dashboard.loadSavedDashboard(OPTIONS_LIST_DASHBOARD_NAME); + await dashboard.ensureDashboardIsInEditMode(); + }; + + before(async () => { + await dashboard.ensureDashboardIsInEditMode(); + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'sound.keyword', + }); + controlId = (await dashboardControls.getAllControlIds())[0]; + await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie'); + await dashboard.clickQuickSave(); + await header.waitUntilLoadingHasFinished(); + }); + + after(async () => { + await dashboardControls.deleteAllControls(); + await dashboardPanelActions.removePanelByTitle('Rendering Test: animal sounds pie'); + await dashboard.clickQuickSave(); + }); + + describe('Applies query settings to controls', async () => { + it('Applies dashboard query to options list control', async () => { + await queryBar.setQuery('animal.keyword : "dog" '); + await queryBar.submitQuery(); // quicker than clicking the submit button, but hides the time picker + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + + const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ + 'ruff', + 'bark', + 'grrr', + 'bow ow ow', + 'grr', + ]); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: { ...suggestions, grr: suggestions.grr - 1 }, + invalidSelections: [], + }); + await queryBar.setQuery(''); + await queryBar.clickQuerySubmitButton(); // ensures that the time picker is visible for the next test + }); + + it('Applies dashboard time range to options list control', async () => { + // set time range to time with no documents + await timePicker.setAbsoluteRange( + 'Jan 1, 2017 @ 00:00:00.000', + 'Jan 1, 2017 @ 00:00:00.000' + ); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + + await dashboardControls.optionsListOpenPopover(controlId); + expect(await dashboardControls.optionsListPopoverGetAvailableOptionsCount()).to.be(0); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await timePicker.setDefaultDataRange(); + }); + + describe('dashboard filters', async () => { + before(async () => { + await filterBar.addFilter({ + field: 'sound.keyword', + operation: 'is one of', + value: ['bark', 'bow ow ow', 'ruff'], + }); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + }); + + it('Applies dashboard filters to options list control', async () => { + const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ + 'ruff', + 'bark', + 'bow ow ow', + ]); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions, + invalidSelections: [], + }); + }); + + it('Does not apply disabled dashboard filters to options list control', async () => { + await filterBar.toggleFilterEnabled('sound.keyword'); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, + invalidSelections: [], + }); + await filterBar.toggleFilterEnabled('sound.keyword'); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + }); + + it('Negated filters apply to options control', async () => { + await filterBar.toggleFilterNegated('sound.keyword'); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + + const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ + 'hiss', + 'grrr', + 'meow', + 'growl', + 'grr', + ]); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions, + invalidSelections: [], + }); + }); + + after(async () => { + await filterBar.removeAllFilters(); + }); + }); + }); + + describe('Selections made in control apply to dashboard', async () => { + it('Shows available options in options list', async () => { + await queryBar.setQuery(''); + await queryBar.submitQuery(); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, + invalidSelections: [], + }); + }); + + it('Can search options list for available options', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSearchForOption('meo'); + await dashboardControls.ensureAvailableOptionsEqual( + controlId, + { + suggestions: { meow: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.meow }, + invalidSelections: [], + }, + true + ); + await dashboardControls.optionsListPopoverClearSearch(); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + }); + + it('Can search options list for available options case insensitive', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSearchForOption('MEO'); + await dashboardControls.ensureAvailableOptionsEqual( + controlId, + { + suggestions: { meow: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.meow }, + invalidSelections: [], + }, + true + ); + await dashboardControls.optionsListPopoverClearSearch(); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + }); + + it('Can select multiple available options', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectOption('hiss'); + await dashboardControls.optionsListPopoverSelectOption('grr'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + }); + + it('Selected options appear in control', async () => { + const selectionString = await dashboardControls.optionsListGetSelectionsString(controlId); + expect(selectionString).to.be('hiss, grr'); + }); + + it('Applies options list control options to dashboard', async () => { + await retry.try(async () => { + expect(await pieChart.getPieSliceCount()).to.be(2); + }); + }); + + it('Applies options list control options to dashboard by default on open', async () => { + await dashboard.gotoDashboardLandingPage(); + await header.waitUntilLoadingHasFinished(); + await dashboard.clickUnsavedChangesContinueEditing(OPTIONS_LIST_DASHBOARD_NAME); + await header.waitUntilLoadingHasFinished(); + expect(await pieChart.getPieSliceCount()).to.be(2); + + const selectionString = await dashboardControls.optionsListGetSelectionsString(controlId); + expect(selectionString).to.be('hiss, grr'); + }); + + it('excluding selections has expected results', async () => { + await dashboard.clickQuickSave(); + await dashboard.waitForRenderComplete(); + + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSetIncludeSelections(false); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await dashboard.waitForRenderComplete(); + + expect(await pieChart.getPieSliceCount()).to.be(5); + await dashboard.clearUnsavedChanges(); + }); + + it('including selections has expected results', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSetIncludeSelections(true); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await dashboard.waitForRenderComplete(); + + expect(await pieChart.getPieSliceCount()).to.be(2); + await dashboard.clearUnsavedChanges(); + }); + + it('changes to selections can be discarded', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectOption('bark'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + let selections = await dashboardControls.optionsListGetSelectionsString(controlId); + expect(selections).to.equal('hiss, grr, bark'); + + await dashboard.clickCancelOutOfEditMode(); + selections = await dashboardControls.optionsListGetSelectionsString(controlId); + expect(selections).to.equal('hiss, grr'); + }); + + it('dashboard does not load with unsaved changes when changes are discarded', async () => { + await dashboard.switchToEditMode(); + await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); + }); + }); + + describe('Test data view runtime field', async () => { + const FIELD_NAME = 'testRuntimeField'; + const FIELD_VALUES = { + G: + OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.growl + + OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.grr + + OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.grrr, + H: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.hiss, + B: + OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.bark + + OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS['bow ow ow'], + R: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.ruff, + M: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.meow, + }; + + before(async () => { + await common.navigateToApp('settings'); + await settings.clickKibanaIndexPatterns(); + await settings.clickIndexPatternByName('animals-*'); + await settings.addRuntimeField( + FIELD_NAME, + 'keyword', + `emit(doc['sound.keyword'].value.substring(0, 1).toUpperCase())` + ); + await header.waitUntilLoadingHasFinished(); + + await returnToDashboard(); + await dashboardControls.deleteAllControls(); + }); + + it('can create options list control on runtime field', async () => { + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + fieldName: FIELD_NAME, + dataViewTitle: 'animals-*', + }); + expect(await dashboardControls.getControlsCount()).to.be(1); + }); + + it('new control has expected suggestions', async () => { + controlId = (await dashboardControls.getAllControlIds())[0]; + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: FIELD_VALUES, + invalidSelections: [], + }); + }); + + it('making selection has expected results', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectOption('B'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await dashboard.waitForRenderComplete(); + + expect(await pieChart.getPieChartLabels()).to.eql(['bark', 'bow ow ow']); + }); + + after(async () => { + await dashboardControls.deleteAllControls(); + await dashboard.clickQuickSave(); + await header.waitUntilLoadingHasFinished(); + + await common.navigateToApp('settings'); + await settings.clickKibanaIndexPatterns(); + await settings.clickIndexPatternByName('animals-*'); + await settings.filterField('testRuntimeField'); + await testSubjects.click('deleteField'); + await settings.confirmDelete(); + }); + }); + + describe('Test exists query', async () => { + const newDocuments: Array<{ index: string; id: string }> = []; + + const addDocument = async (index: string, document: string) => { + await console.enterRequest('\nPOST ' + index + '/_doc/ \n{\n ' + document); + await console.clickPlay(); + await header.waitUntilLoadingHasFinished(); + const response = JSON.parse(await console.getResponse()); + newDocuments.push({ index, id: response._id }); + }; + + before(async () => { + await common.navigateToApp('console'); + await console.collapseHelp(); + await console.clearTextArea(); + await addDocument( + 'animals-cats-2018-01-01', + '"@timestamp": "2018-01-01T16:00:00.000Z", \n"name": "Rosie", \n"sound": "hiss"' + ); + await returnToDashboard(); + + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'animal.keyword', + title: 'Animal', + }); + controlId = (await dashboardControls.getAllControlIds())[0]; + await header.waitUntilLoadingHasFinished(); + await dashboard.waitForRenderComplete(); + }); + + it('creating exists query has expected results', async () => { + expect((await pieChart.getPieChartValues())[0]).to.be(6); + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectExists(); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await dashboard.waitForRenderComplete(); + + expect(await pieChart.getPieSliceCount()).to.be(5); + expect((await pieChart.getPieChartValues())[0]).to.be(5); + }); + + it('negating exists query has expected results', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSetIncludeSelections(false); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await dashboard.waitForRenderComplete(); + + expect(await pieChart.getPieSliceCount()).to.be(1); + expect((await pieChart.getPieChartValues())[0]).to.be(1); + }); + + after(async () => { + await common.navigateToApp('console'); + await console.clearTextArea(); + for (const { index, id } of newDocuments) { + await console.enterRequest(`\nDELETE /${index}/_doc/${id}`); + await console.clickPlay(); + await header.waitUntilLoadingHasFinished(); + } + await returnToDashboard(); + }); + }); + }); +} diff --git a/test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts b/test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts new file mode 100644 index 00000000000000..6c69dc99bc4d3a --- /dev/null +++ b/test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts @@ -0,0 +1,116 @@ +/* + * Copyright 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 { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; + +import { OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS } from '../../../../page_objects/dashboard_page_controls'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + + const { dashboardControls, dashboard, header } = getPageObjects([ + 'dashboardControls', + 'timePicker', + 'dashboard', + 'settings', + 'console', + 'common', + 'header', + ]); + + describe('Dashboard options list suggestions', () => { + let controlId: string; + + before(async () => { + await dashboard.ensureDashboardIsInEditMode(); + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'sound.keyword', + }); + controlId = (await dashboardControls.getAllControlIds())[0]; + await dashboard.clickQuickSave(); + await header.waitUntilLoadingHasFinished(); + + await dashboardControls.optionsListOpenPopover(controlId); + }); + + after(async () => { + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await dashboardControls.deleteAllControls(); + await dashboard.clickQuickSave(); + }); + + it('sort alphabetically - descending', async () => { + await dashboardControls.optionsListPopoverSetSort({ by: '_key', direction: 'desc' }); + const sortedSuggestions = Object.keys(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS) + .sort() + .reverse() + .reduce((result, key) => { + return { ...result, [key]: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS[key] }; + }, {}); + await dashboardControls.ensureAvailableOptionsEqual( + controlId, + { suggestions: sortedSuggestions, invalidSelections: [] }, + true + ); + }); + + it('sort alphabetically - ascending', async () => { + await dashboardControls.optionsListPopoverSetSort({ by: '_key', direction: 'asc' }); + const sortedSuggestions = Object.keys(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS) + .sort() + .reduce((result, key) => { + return { ...result, [key]: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS[key] }; + }, {}); + await dashboardControls.ensureAvailableOptionsEqual( + controlId, + { suggestions: sortedSuggestions, invalidSelections: [] }, + true + ); + }); + + it('sort by document count - descending', async () => { + await dashboardControls.optionsListPopoverSetSort({ by: '_count', direction: 'desc' }); + await dashboardControls.ensureAvailableOptionsEqual( + controlId, + { + suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, // keys are already sorted descending by doc count + invalidSelections: [], + }, + true + ); + }); + + it('sort by document count - ascending', async () => { + await dashboardControls.optionsListPopoverSetSort({ by: '_count', direction: 'asc' }); + const sortedSuggestions = Object.entries(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS) + .sort(([, docCountA], [, docCountB]) => { + return docCountB - docCountA; + }) + .reduce((result, [key, docCount]) => { + return { ...result, [key]: docCount }; + }, {}); + await dashboardControls.ensureAvailableOptionsEqual( + controlId, + { suggestions: sortedSuggestions, invalidSelections: [] }, + true + ); + }); + + it('non-default sort value should cause unsaved changes', async () => { + await testSubjects.existOrFail('dashboardUnsavedChangesBadge'); + }); + + it('returning to default sort value should remove unsaved changes', async () => { + await dashboardControls.optionsListPopoverSetSort({ by: '_count', direction: 'desc' }); + await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); + }); + }); +} diff --git a/test/functional/apps/dashboard_elements/controls/options_list/options_list_validation.ts b/test/functional/apps/dashboard_elements/controls/options_list/options_list_validation.ts new file mode 100644 index 00000000000000..f48bc5d9e4c423 --- /dev/null +++ b/test/functional/apps/dashboard_elements/controls/options_list/options_list_validation.ts @@ -0,0 +1,161 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { pick } from 'lodash'; + +import expect from '@kbn/expect'; +import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; + +import { FtrProviderContext } from '../../../../ftr_provider_context'; +import { OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS } from '../../../../page_objects/dashboard_page_controls'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const queryBar = getService('queryBar'); + const pieChart = getService('pieChart'); + const filterBar = getService('filterBar'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const dashboardPanelActions = getService('dashboardPanelActions'); + + const { dashboardControls, dashboard, header } = getPageObjects([ + 'dashboardControls', + 'timePicker', + 'dashboard', + 'settings', + 'console', + 'common', + 'header', + ]); + + describe('Dashboard options list validation', () => { + let controlId: string; + + before(async () => { + await dashboard.ensureDashboardIsInEditMode(); + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'sound.keyword', + title: 'Animal Sounds', + }); + controlId = (await dashboardControls.getAllControlIds())[0]; + await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie'); + await dashboard.clickQuickSave(); + await header.waitUntilLoadingHasFinished(); + }); + + after(async () => { + await filterBar.removeAllFilters(); + await dashboardControls.deleteAllControls(); + await dashboardPanelActions.removePanelByTitle('Rendering Test: animal sounds pie'); + await dashboard.clickQuickSave(); + }); + + describe('Options List dashboard validation', async () => { + before(async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectOption('meow'); + await dashboardControls.optionsListPopoverSelectOption('bark'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + }); + + after(async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverClearSelections(); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await filterBar.removeAllFilters(); + await queryBar.clickQuerySubmitButton(); + }); + + it('Can mark selections invalid with Query', async () => { + await queryBar.setQuery('NOT animal.keyword : "dog" '); + await queryBar.submitQuery(); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + + const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ + 'hiss', + 'meow', + 'growl', + 'grr', + ]); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: { ...suggestions, grr: suggestions.grr - 1 }, + invalidSelections: ['bark'], + }); + // only valid selections are applied as filters. + expect(await pieChart.getPieSliceCount()).to.be(1); + }); + + it('can make invalid selections valid again if the parent filter changes', async () => { + await queryBar.setQuery(''); + await queryBar.submitQuery(); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, + invalidSelections: [], + }); + expect(await pieChart.getPieSliceCount()).to.be(2); + }); + + it('Can mark multiple selections invalid with Filter', async () => { + await filterBar.addFilter({ field: 'sound.keyword', operation: 'is', value: 'hiss' }); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: { + hiss: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.hiss, + }, + invalidSelections: ['meow', 'bark'], + }); + // only valid selections are applied as filters. + expect(await pieChart.getPieSliceCount()).to.be(1); + }); + }); + + describe('Options List dashboard no validation', async () => { + before(async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectOption('meow'); + await dashboardControls.optionsListPopoverSelectOption('bark'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + await dashboardControls.updateValidationSetting(false); + }); + + it('Does not mark selections invalid with Query', async () => { + await queryBar.setQuery('NOT animal.keyword : "dog" '); + await queryBar.submitQuery(); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + + const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ + 'hiss', + 'meow', + 'growl', + 'grr', + ]); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: { ...suggestions, grr: suggestions.grr - 1 }, + invalidSelections: [], + }); + }); + + it('Does not mark multiple selections invalid with Filter', async () => { + await filterBar.addFilter({ field: 'sound.keyword', operation: 'is', value: 'hiss' }); + await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); + await dashboardControls.ensureAvailableOptionsEqual(controlId, { + suggestions: { + hiss: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS.hiss, + }, + invalidSelections: [], + }); + }); + }); + }); +} diff --git a/test/functional/page_objects/dashboard_page.ts b/test/functional/page_objects/dashboard_page.ts index 0f5a6d41e6fe0b..1f9656c9ff548e 100644 --- a/test/functional/page_objects/dashboard_page.ts +++ b/test/functional/page_objects/dashboard_page.ts @@ -281,6 +281,13 @@ export class DashboardPageObject extends FtrService { return await this.testSubjects.exists('dashboardEditMode'); } + public async ensureDashboardIsInEditMode() { + if (await this.getIsInViewMode()) { + await this.switchToEditMode(); + } + await this.waitForRenderComplete(); + } + public async clickCancelOutOfEditMode(accept = true) { this.log.debug('clickCancelOutOfEditMode'); if (await this.getIsInViewMode()) return; diff --git a/test/functional/page_objects/dashboard_page_controls.ts b/test/functional/page_objects/dashboard_page_controls.ts index cdb48b067aec5a..85908bce3d35cd 100644 --- a/test/functional/page_objects/dashboard_page_controls.ts +++ b/test/functional/page_objects/dashboard_page_controls.ts @@ -14,8 +14,8 @@ import { } from '@kbn/controls-plugin/common'; import { ControlGroupChainingSystem } from '@kbn/controls-plugin/common/control_group/types'; import { OptionsListSortingType } from '@kbn/controls-plugin/common/options_list/suggestions_sorting'; -import { WebElementWrapper } from '../services/lib/web_element_wrapper'; +import { WebElementWrapper } from '../services/lib/web_element_wrapper'; import { FtrService } from '../ftr_provider_context'; const CONTROL_DISPLAY_NAMES: { [key: string]: string } = { @@ -48,6 +48,7 @@ export class DashboardPageControls extends FtrService { private readonly log = this.ctx.getService('log'); private readonly find = this.ctx.getService('find'); private readonly retry = this.ctx.getService('retry'); + private readonly browser = this.ctx.getService('browser'); private readonly testSubjects = this.ctx.getService('testSubjects'); private readonly common = this.ctx.getPageObject('common'); @@ -354,6 +355,7 @@ export class DashboardPageControls extends FtrService { public async optionsListGetSelectionsString(controlId: string) { this.log.debug(`Getting selections string for Options List: ${controlId}`); + await this.optionsListWaitForLoading(controlId); const controlElement = await this.getControlElementById(controlId); return (await controlElement.getVisibleText()).split('\n')[1]; } @@ -362,7 +364,7 @@ export class DashboardPageControls extends FtrService { this.log.debug(`Opening popover for Options List: ${controlId}`); await this.testSubjects.click(`optionsList-control-${controlId}`); await this.retry.try(async () => { - await this.testSubjects.existOrFail(`optionsList-control-available-options`); + await this.testSubjects.existOrFail(`optionsList-control-popover`); }); } @@ -382,25 +384,27 @@ export class DashboardPageControls extends FtrService { public async optionsListPopoverGetAvailableOptionsCount() { this.log.debug(`getting available options count from options list`); + await this.optionsListPopoverWaitForLoading(); const availableOptions = await this.testSubjects.find(`optionsList-control-available-options`); return +(await availableOptions.getAttribute('data-option-count')); } public async optionsListPopoverGetAvailableOptions() { this.log.debug(`getting available options from options list`); + await this.optionsListPopoverWaitForLoading(); const availableOptions = await this.testSubjects.find(`optionsList-control-available-options`); - - const suggestionElements = await availableOptions.findAllByClassName( - 'optionsList__validSuggestion' - ); - const suggestions: { [key: string]: number } = await suggestionElements.reduce( - async (promise, option) => { - const acc = await promise; - const [key, docCount] = (await option.getVisibleText()).split('\n'); - return { ...acc, [key]: Number(docCount) }; - }, - Promise.resolve({} as { [key: string]: number }) - ); + const optionsCount = await this.optionsListPopoverGetAvailableOptionsCount(); + + const selectableListItems = await availableOptions.findByClassName('euiSelectableList__list'); + const suggestions: { [key: string]: number } = {}; + while (Object.keys(suggestions).length < optionsCount) { + await selectableListItems._webElement.sendKeys(this.browser.keys.ARROW_DOWN); + const currentOption = await selectableListItems.findByCssSelector('[aria-selected="true"]'); + const [suggestion, docCount] = (await currentOption.getVisibleText()).split('\n'); + if (suggestion !== 'Exists') { + suggestions[suggestion] = Number(docCount); + } + } const invalidSelectionElements = await availableOptions.findAllByClassName( 'optionsList__selectionInvalid' @@ -419,6 +423,7 @@ export class DashboardPageControls extends FtrService { expectation: { suggestions: { [key: string]: number }; invalidSelections: string[] }, skipOpen?: boolean ) { + await this.optionsListWaitForLoading(controlId); if (!skipOpen) await this.optionsListOpenPopover(controlId); await this.retry.try(async () => { expect(await this.optionsListPopoverGetAvailableOptions()).to.eql(expectation); @@ -456,10 +461,25 @@ export class DashboardPageControls extends FtrService { }); } + public async optionsListPopoverSelectExists() { + await this.retry.try(async () => { + await this.testSubjects.existOrFail(`optionsList-control-selection-exists`); + await this.testSubjects.click(`optionsList-control-selection-exists`); + }); + } + public async optionsListPopoverSelectOption(availableOption: string) { this.log.debug(`selecting ${availableOption} from options list`); - await this.optionsListPopoverAssertOpen(); - await this.testSubjects.click(`optionsList-control-selection-${availableOption}`); + await this.optionsListPopoverSearchForOption(availableOption); + await this.optionsListPopoverWaitForLoading(); + + await this.retry.try(async () => { + await this.testSubjects.existOrFail(`optionsList-control-selection-${availableOption}`); + await this.testSubjects.click(`optionsList-control-selection-${availableOption}`); + }); + + await this.optionsListPopoverClearSearch(); + await this.optionsListPopoverWaitForLoading(); } public async optionsListPopoverClearSelections() { @@ -482,9 +502,16 @@ export class DashboardPageControls extends FtrService { } public async optionsListWaitForLoading(controlId: string) { + this.log.debug(`wait for ${controlId} to load`); await this.testSubjects.waitForEnabled(`optionsList-control-${controlId}`); } + public async optionsListPopoverWaitForLoading() { + this.log.debug(`wait for the suggestions in the popover to load`); + await this.optionsListPopoverAssertOpen(); + await this.testSubjects.waitForDeleted('optionsList-control-popover-loading'); + } + /* ----------------------------------------------------------- Control editor flyout ----------------------------------------------------------- */ diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 5c51d00f5afd1f..a13d19e5246eba 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -218,6 +218,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.security.sameSiteCookies (alternatives)', 'xpack.security.showInsecureClusterWarning (boolean)', 'xpack.securitySolution.enableExperimental (array)', + 'xpack.securitySolution.prebuiltRulesPackageVersion (string)', 'xpack.snapshot_restore.slm_ui.enabled (boolean)', 'xpack.snapshot_restore.ui.enabled (boolean)', 'xpack.trigger_actions_ui.enableExperimental (array)', diff --git a/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts b/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts index fc32c62ce6bae6..c63f239c5a4918 100644 --- a/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts +++ b/x-pack/performance/journeys/ecommerce_dashboard_saved_search_only.ts @@ -10,8 +10,6 @@ import { subj } from '@kbn/test-subj-selector'; import { waitForVisualizations } from '../utils'; export const journey = new Journey({ - // FAILING: https://github.com/elastic/kibana/issues/148221 - skipped: true, esArchives: ['x-pack/performance/es_archives/sample_data_ecommerce'], kbnArchives: ['x-pack/performance/kbn_archives/ecommerce_saved_search_only_dashboard'], }) diff --git a/x-pack/plugins/actions/docs/openapi/bundled.json b/x-pack/plugins/actions/docs/openapi/bundled.json index 85c2d1ec66a55a..0919fea40668ba 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.json +++ b/x-pack/plugins/actions/docs/openapi/bundled.json @@ -25,6 +25,146 @@ } ], "paths": { + "/s/{spaceId}/api/actions/connector": { + "post": { + "summary": "Creates a connector.", + "operationId": "createConnector", + "description": "You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges.\n", + "tags": [ + "connectors" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "title": "Create connector request body properties", + "description": "The properties vary depending on the connector type.", + "oneOf": [ + { + "$ref": "#/components/schemas/create_connector_request_cases_webhook" + }, + { + "$ref": "#/components/schemas/create_connector_request_email" + }, + { + "$ref": "#/components/schemas/create_connector_request_index" + }, + { + "$ref": "#/components/schemas/create_connector_request_jira" + }, + { + "$ref": "#/components/schemas/create_connector_request_opsgenie" + }, + { + "$ref": "#/components/schemas/create_connector_request_pagerduty" + }, + { + "$ref": "#/components/schemas/create_connector_request_resilient" + }, + { + "$ref": "#/components/schemas/create_connector_request_serverlog" + }, + { + "$ref": "#/components/schemas/create_connector_request_servicenow" + }, + { + "$ref": "#/components/schemas/create_connector_request_servicenow_itom" + }, + { + "$ref": "#/components/schemas/create_connector_request_servicenow_sir" + }, + { + "$ref": "#/components/schemas/create_connector_request_slack" + }, + { + "$ref": "#/components/schemas/create_connector_request_swimlane" + }, + { + "$ref": "#/components/schemas/create_connector_request_teams" + }, + { + "$ref": "#/components/schemas/create_connector_request_tines" + }, + { + "$ref": "#/components/schemas/create_connector_request_webhook" + }, + { + "$ref": "#/components/schemas/create_connector_request_xmatters" + } + ], + "discriminator": { + "propertyName": "connector_type_id" + } + }, + "examples": { + "createIndexConnectorRequest": { + "$ref": "#/components/examples/create_index_connector_request" + } + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connector_response_properties" + }, + "examples": { + "createIndexConnectorResponse": { + "$ref": "#/components/examples/create_index_connector_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, "/s/{spaceId}/api/actions/connector/{connectorId}": { "get": { "summary": "Retrieves a connector by ID.", @@ -44,52 +184,62 @@ "responses": { "200": { "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connector_response_properties" + }, + "examples": { + "getConnectorResponse": { + "$ref": "#/components/examples/get_connector_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", "content": { "application/json": { "schema": { "type": "object", - "required": [ - "connector_type_id", - "id", - "is_deprecated", - "is_preconfigured", - "name" - ], "properties": { - "config": { - "type": "object", - "description": "The configuration for the connector. Configuration properties vary depending on the connector type.", - "additionalProperties": true, - "nullable": true - }, - "connector_type_id": { - "$ref": "#/components/schemas/connector_types" - }, - "id": { + "error": { "type": "string", - "description": "The identifier for the connector.", - "example": "b0766e10-d190-11ec-b04c-776c77d14fca" + "example": "Unauthorized" }, - "is_deprecated": { - "$ref": "#/components/schemas/is_deprecated" + "message": { + "type": "string" }, - "is_missing_secrets": { - "$ref": "#/components/schemas/is_missing_secrets" - }, - "is_preconfigured": { - "$ref": "#/components/schemas/is_preconfigured" + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found" }, - "name": { + "message": { "type": "string", - "description": "The display name for the connector.", - "example": "my-connector" + "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404 } } - }, - "examples": { - "getConnectorResponse": { - "$ref": "#/components/examples/get_connector_response" - } } } } @@ -122,6 +272,205 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found" + }, + "message": { + "type": "string", + "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404 + } + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "put": { + "summary": "Updates the attributes for a connector.", + "operationId": "updateConnector", + "description": "You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges.\n", + "tags": [ + "connectors" + ], + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + }, + { + "$ref": "#/components/parameters/connector_id" + }, + { + "$ref": "#/components/parameters/space_id" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "title": "Update connector request body properties", + "description": "The properties vary depending on the connector type.", + "oneOf": [ + { + "$ref": "#/components/schemas/update_connector_request_cases_webhook" + }, + { + "$ref": "#/components/schemas/update_connector_request_index" + }, + { + "$ref": "#/components/schemas/update_connector_request_jira" + }, + { + "$ref": "#/components/schemas/update_connector_request_opsgenie" + }, + { + "$ref": "#/components/schemas/update_connector_request_resilient" + }, + { + "$ref": "#/components/schemas/update_connector_request_serverlog" + }, + { + "$ref": "#/components/schemas/update_connector_request_servicenow" + }, + { + "$ref": "#/components/schemas/update_connector_request_servicenow_itom" + }, + { + "$ref": "#/components/schemas/update_connector_request_swimlane" + } + ] + }, + "examples": { + "updateIndexConnectorRequest": { + "$ref": "#/components/examples/update_index_connector_request" + } + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connector_response_properties" + } + } + } + }, + "400": { + "description": "Indicates a bad request.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Bad Request" + }, + "message": { + "type": "string", + "example": "error validating action type config: [index]: expected value of type [string] but got [undefined]" + }, + "statusCode": { + "type": "integer", + "example": 400 + } + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found" + }, + "message": { + "type": "string", + "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404 + } + } + } + } + } } }, "servers": [ @@ -157,6 +506,8 @@ "schema": { "type": "array", "items": { + "title": "Get connectors response body properties", + "description": "The properties vary for each connector type.", "type": "object", "required": [ "connector_type_id", @@ -211,6 +562,29 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } } }, "servers": [ @@ -252,6 +626,8 @@ "content": { "application/json": { "schema": { + "title": "Get connector types response body properties", + "description": "The properties vary for each connector type.", "type": "array", "items": { "type": "object", @@ -306,6 +682,29 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + } + } + } } }, "servers": [ @@ -334,15 +733,13 @@ } }, "parameters": { - "connector_id": { - "in": "path", - "name": "connectorId", - "description": "An identifier for the connector.", - "required": true, + "kbn_xsrf": { "schema": { - "type": "string", - "example": "df770e30-8b8b-11ed-a780-3b746c987a81" - } + "type": "string" + }, + "in": "header", + "name": "kbn-xsrf", + "required": true }, "space_id": { "in": "path", @@ -354,17 +751,2176 @@ "example": "default" } }, - "kbn_xsrf": { + "connector_id": { + "in": "path", + "name": "connectorId", + "description": "An identifier for the connector.", + "required": true, "schema": { - "type": "string" - }, - "in": "header", - "name": "kbn-xsrf", - "required": true - } - }, + "type": "string", + "example": "df770e30-8b8b-11ed-a780-3b746c987a81" + } + } + }, "schemas": { + "config_properties_cases_webhook": { + "title": "Connector request properties for Webhook - Case Management connector", + "required": [ + "createIncidentJson", + "createIncidentResponseKey", + "createIncidentUrl", + "getIncidentResponseExternalTitleKey", + "getIncidentUrl", + "updateIncidentJson", + "updateIncidentUrl", + "viewIncidentUrl" + ], + "description": "Defines properties for connectors when type is `.cases-webhook`.", + "type": "object", + "properties": { + "createCommentJson": { + "type": "string", + "description": "A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", + "example": { + "body": { + "[object Object]": null + } + } + }, + "createCommentMethod": { + "type": "string", + "description": "The REST API HTTP request method to create a case comment in the third-party system. Valid values are `patch`, `post`, and `put`.\n", + "default": "put", + "enum": [ + "patch", + "post", + "put" + ] + }, + "createCommentUrl": { + "type": "string", + "description": "The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts.\n", + "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment" + }, + "createIncidentJson": { + "type": "string", + "description": "A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", + "example": { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } + } + } + }, + "createIncidentMethod": { + "type": "string", + "description": "The REST API HTTP request method to create a case in the third-party system. Valid values are `patch`, `post`, and `put`.\n", + "enum": [ + "patch", + "post", + "put" + ], + "default": "post" + }, + "createIncidentResponseKey": { + "type": "string", + "description": "The JSON key in the create case response that contains the external case ID." + }, + "createIncidentUrl": { + "type": "string", + "description": "The REST API URL to create a case in the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n" + }, + "getIncidentResponseExternalTitleKey": { + "type": "string", + "description": "The JSON key in get case response that contains the external case title." + }, + "getIncidentUrl": { + "type": "string", + "description": "The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", + "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}" + }, + "hasAuth": { + "type": "boolean", + "description": "If true, a username and password for login type authentication must be provided.", + "default": true + }, + "headers": { + "type": "string", + "description": "A set of key-value pairs sent as headers with the request URLs for the create case, update case, get case, and create comment methods.\n" + }, + "updateIncidentJson": { + "type": "string", + "description": "The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", + "example": { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } + } + } + }, + "updateIncidentMethod": { + "type": "string", + "description": "The REST API HTTP request method to update the case in the third-party system. Valid values are `patch`, `post`, and `put`.\n", + "default": "put", + "enum": [ + "patch", + "post", + "put" + ] + }, + "updateIncidentUrl": { + "type": "string", + "description": "The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n", + "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}}" + }, + "viewIncidentUrl": { + "type": "string", + "description": "The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL.\n", + "example": "https://testing-jira.atlassian.net/browse/{{{external.system.title}}}" + } + } + }, + "secrets_properties_cases_webhook": { + "title": "Connector secrets properties for Webhook - Case Management connector", + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "The password for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required." + }, + "user": { + "type": "string", + "description": "The username for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required." + } + } + }, + "create_connector_request_cases_webhook": { + "title": "Create Webhook - Case Managment connector request", + "description": "The Webhook - Case Management connector uses axios to send POST, PUT, and GET requests to a case management RESTful API web service.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_cases_webhook" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".cases-webhook" + ], + "example": ".cases-webhook" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_cases_webhook" + } + } + }, + "config_properties_email": { + "title": "Connector request properties for an email connector", + "description": "Defines properties for connectors when type is `.email`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_email": { + "title": "Connector secrets properties for an email connector", + "description": "Defines secrets for connectors when type is `.email`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_email": { + "title": "Create email connector request", + "description": "The email connector uses the SMTP protocol to send mail messages, using an integration of Nodemailer. An exception is Microsoft Exchange, which uses HTTP protocol for sending emails, Send mail. Email message text is sent as both plain text and html text.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_email" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".email" + ], + "example": ".email" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_email" + } + } + }, + "config_properties_index": { + "title": "Connector request properties for an index connector", + "required": [ + "index" + ], + "description": "Defines properties for connectors when type is `.index`.", + "type": "object", + "properties": { + "executionTimeField": { + "description": "Specifies a field that will contain the time the alert condition was detected.", + "default": null, + "type": "string", + "nullable": true + }, + "index": { + "description": "The Elasticsearch index to be written to.", + "type": "string" + }, + "refresh": { + "description": "The refresh policy for the write request, which affects when changes are made visible to search. Refer to the refresh setting for Elasticsearch document APIs.\n", + "default": false, + "type": "boolean" + } + } + }, + "create_connector_request_index": { + "title": "Create index connector request", + "description": "The index connector indexes a document into Elasticsearch.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_index" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".index" + ], + "example": ".index" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + } + } + }, + "config_properties_jira": { + "title": "Connector request properties for a Jira connector", + "required": [ + "apiUrl", + "projectKey" + ], + "description": "Defines properties for connectors when type is `.jira`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The Jira instance URL.", + "type": "string" + }, + "projectKey": { + "description": "The Jira project key.", + "type": "string" + } + } + }, + "secrets_properties_jira": { + "title": "Connector secrets properties for a Jira connector", + "required": [ + "apiToken", + "email" + ], + "description": "Defines secrets for connectors when type is `.jira`.", + "type": "object", + "properties": { + "apiToken": { + "description": "The Jira API authentication token for HTTP basic authentication.", + "type": "string" + }, + "email": { + "description": "The account email for HTTP Basic authentication.", + "type": "string" + } + } + }, + "create_connector_request_jira": { + "title": "Create Jira connector request", + "description": "The Jira connector uses the REST API v2 to create Jira issues.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_jira" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".jira" + ], + "example": ".jira" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_jira" + } + } + }, + "config_properties_opsgenie": { + "title": "Connector request properties for an Opsgenie connector", + "required": [ + "apiUrl" + ], + "description": "Defines properties for connectors when type is `.opsgenie`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The Opsgenie URL. For example, `https://api.opsgenie.com` or `https://api.eu.opsgenie.com`. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n", + "type": "string" + } + } + }, + "secrets_properties_opsgenie": { + "title": "Connector secrets properties for an Opsgenie connector", + "required": [ + "apiKey" + ], + "description": "Defines secrets for connectors when type is `.opsgenie`.", + "type": "object", + "properties": { + "apiKey": { + "description": "The Opsgenie API authentication key for HTTP Basic authentication.", + "type": "string" + } + } + }, + "create_connector_request_opsgenie": { + "title": "Create Opsgenie connector request", + "description": "The Opsgenie connector uses the Opsgenie alert API.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_opsgenie" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".opsgenie" + ], + "example": ".opsgenie" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_opsgenie" + } + } + }, + "config_properties_pagerduty": { + "title": "Connector request properties for a PagerDuty connector", + "description": "Defines properties for connectors when type is `.pagerduty`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_pagerduty": { + "title": "Connector secrets properties for a PagerDuty connector", + "description": "Defines secrets for connectors when type is `.pagerduty`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_pagerduty": { + "title": "Create PagerDuty connector request", + "description": "The PagerDuty connector uses the v2 Events API to trigger, acknowledge, and resolve PagerDuty alerts.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_pagerduty" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".pagerduty" + ], + "example": ".pagerduty" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_pagerduty" + } + } + }, + "config_properties_resilient": { + "title": "Connector request properties for a IBM Resilient connector", + "required": [ + "apiUrl", + "orgId" + ], + "description": "Defines properties for connectors when type is `.resilient`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The IBM Resilient instance URL.", + "type": "string" + }, + "orgId": { + "description": "The IBM Resilient organization ID.", + "type": "string" + } + } + }, + "secrets_properties_resilient": { + "title": "Connector secrets properties for IBM Resilient connector", + "required": [ + "apiKeyId", + "apiKeySecret" + ], + "description": "Defines secrets for connectors when type is `.resilient`.", + "type": "object", + "properties": { + "apiKeyId": { + "type": "string", + "description": "The authentication key ID for HTTP Basic authentication." + }, + "apiKeySecret": { + "type": "string", + "description": "The authentication key secret for HTTP Basic authentication." + } + } + }, + "create_connector_request_resilient": { + "title": "Create IBM Resilient connector request", + "description": "The IBM Resilient connector uses the RESILIENT REST v2 to create IBM Resilient incidents.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_resilient" + }, + "connector_type_id": { + "description": "The type of connector.", + "type": "string", + "example": ".resilient", + "enum": [ + ".resilient" + ] + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_resilient" + } + } + }, + "create_connector_request_serverlog": { + "title": "Create server log connector request", + "description": "This connector writes an entry to the Kibana server log.", + "type": "object", + "required": [ + "connector_type_id", + "name" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".server-log" + ], + "example": ".server-log" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + } + } + }, + "config_properties_servicenow": { + "title": "Connector request properties for a ServiceNow ITSM connector", + "required": [ + "apiUrl" + ], + "description": "Defines properties for connectors when type is `.servicenow`.", + "type": "object", + "properties": { + "apiUrl": { + "type": "string", + "description": "The ServiceNow instance URL." + }, + "clientId": { + "description": "The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "isOAuth": { + "description": "The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth).\n", + "default": false, + "type": "string" + }, + "jwtKeyId": { + "description": "The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "userIdentifierValue": { + "description": "The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "usesTableApi": { + "description": "Determines whether the connector uses the Table API or the Import Set API. This property is supported only for ServiceNow ITSM and ServiceNow SecOps connectors. NOTE: If this property is set to `false`, the Elastic application should be installed in ServiceNow.\n", + "default": true, + "type": "boolean" + } + } + }, + "secrets_properties_servicenow": { + "title": "Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors", + "description": "Defines secrets for connectors when type is `.servicenow`, `.servicenow-sir`, or `.servicenow-itom`.", + "type": "object", + "properties": { + "clientSecret": { + "type": "string", + "description": "The client secret assigned to your OAuth application. This property is required when `isOAuth` is `true`." + }, + "password": { + "type": "string", + "description": "The password for HTTP basic authentication. This property is required when `isOAuth` is `false`." + }, + "privateKey": { + "type": "string", + "description": "The RSA private key that you created for use in ServiceNow. This property is required when `isOAuth` is `true`." + }, + "privateKeyPassword": { + "type": "string", + "description": "The password for the RSA private key. This property is required when `isOAuth` is `true` and you set a password on your private key." + }, + "username": { + "type": "string", + "description": "The username for HTTP basic authentication. This property is required when `isOAuth` is `false`." + } + } + }, + "create_connector_request_servicenow": { + "title": "Create ServiceNow ITSM connector request", + "description": "The ServiceNow ITSM connector uses the import set API to create ServiceNow incidents. You can use the connector for rule actions and cases.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow" + ], + "example": ".servicenow" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "config_properties_servicenow_itom": { + "title": "Connector request properties for a ServiceNow ITSM connector", + "required": [ + "apiUrl" + ], + "description": "Defines properties for connectors when type is `.servicenow`.", + "type": "object", + "properties": { + "apiUrl": { + "type": "string", + "description": "The ServiceNow instance URL." + }, + "clientId": { + "description": "The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "isOAuth": { + "description": "The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth).\n", + "default": false, + "type": "string" + }, + "jwtKeyId": { + "description": "The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`.\n", + "type": "string" + }, + "userIdentifierValue": { + "description": "The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`.\n", + "type": "string" + } + } + }, + "create_connector_request_servicenow_itom": { + "title": "Create ServiceNow ITOM connector request", + "description": "The ServiceNow ITOM connector uses the event API to create ServiceNow events. You can use the connector for rule actions.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow_itom" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-itom" + ], + "example": ".servicenow-itom" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "create_connector_request_servicenow_sir": { + "title": "Create ServiceNow SecOps connector request", + "description": "The ServiceNow SecOps connector uses the import set API to create ServiceNow security incidents. You can use the connector for rule actions and cases.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-sir" + ], + "example": ".servicenow-sir" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "secrets_properties_slack": { + "title": "Connector secrets properties for a Slack connector", + "description": "Defines secrets for connectors when type is `.slack`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_slack": { + "title": "Create Slack connector request", + "description": "The Slack connector uses Slack Incoming Webhooks.", + "type": "object", + "required": [ + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".slack" + ], + "example": ".slack" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_slack" + } + } + }, + "config_properties_swimlane": { + "title": "Connector request properties for a Swimlane connector", + "required": [ + "apiUrl", + "appId", + "connectorType" + ], + "description": "Defines properties for connectors when type is `.swimlane`.", + "type": "object", + "properties": { + "apiUrl": { + "description": "The Swimlane instance URL.", + "type": "string" + }, + "appId": { + "description": "The Swimlane application ID.", + "type": "string" + }, + "connectorType": { + "description": "The type of connector. Valid values are `all`, `alerts`, and `cases`.", + "type": "string", + "enum": [ + "all", + "alerts", + "cases" + ] + }, + "mappings": { + "title": "Connector mappings properties for a Swimlane connector", + "description": "The field mapping.", + "type": "object", + "properties": { + "alertIdConfig": { + "title": "Alert identifier mapping", + "description": "Mapping for the alert ID.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "caseIdConfig": { + "title": "Case identifier mapping", + "description": "Mapping for the case ID.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "caseNameConfig": { + "title": "Case name mapping", + "description": "Mapping for the case name.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "commentsConfig": { + "title": "Case comment mapping", + "description": "Mapping for the case comments.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "descriptionConfig": { + "title": "Case description mapping", + "description": "Mapping for the case description.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "ruleNameConfig": { + "title": "Rule name mapping", + "description": "Mapping for the name of the alert's rule.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + }, + "severityConfig": { + "title": "Severity mapping", + "description": "Mapping for the severity.", + "type": "object", + "required": [ + "fieldType", + "id", + "key", + "name" + ], + "properties": { + "fieldType": { + "type": "string", + "description": "The type of field in Swimlane." + }, + "id": { + "type": "string", + "description": "The identifier for the field in Swimlane." + }, + "key": { + "type": "string", + "description": "The key for the field in Swimlane." + }, + "name": { + "type": "string", + "description": "The name of the field in Swimlane." + } + } + } + } + } + } + }, + "secrets_properties_swimlane": { + "title": "Connector secrets properties for a Swimlane connector", + "description": "Defines secrets for connectors when type is `.swimlane`.", + "type": "object", + "properties": { + "apiToken": { + "description": "Swimlane API authentication token.", + "type": "string" + } + } + }, + "create_connector_request_swimlane": { + "title": "Create Swimlane connector request", + "description": "The Swimlane connector uses the Swimlane REST API to create Swimlane records.", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_swimlane" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".swimlane" + ], + "example": ".swimlane" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_swimlane" + } + } + }, + "secrets_properties_teams": { + "title": "Connector secrets properties for a Microsoft Teams connector", + "description": "Defines secrets for connectors when type is `.teams`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_teams": { + "title": "Create Microsoft Teams connector request", + "description": "The Microsoft Teams connector uses Incoming Webhooks.", + "type": "object", + "required": [ + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".teams" + ], + "example": ".teams" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_teams" + } + } + }, + "config_properties_tines": { + "title": "Connector request properties for a Tines connector", + "description": "Defines properties for connectors when type is `.tines`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_tines": { + "title": "Connector secrets properties for a Tines connector", + "description": "Defines secrets for connectors when type is `.tines`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_tines": { + "title": "Create Tines connector request", + "description": "The Tines connector uses Tines Webhook actions to send events via POST request.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_tines" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".tines" + ], + "example": ".tines" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_tines" + } + } + }, + "config_properties_webhook": { + "title": "Connector request properties for a Webhook connector", + "description": "Defines properties for connectors when type is `.webhook`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_webhook": { + "title": "Connector secrets properties for a Webhook connector", + "description": "Defines secrets for connectors when type is `.webhook`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_webhook": { + "title": "Create Webhook connector request", + "description": "The Webhook connector uses axios to send a POST or PUT request to a web service.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_webhook" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".webhook" + ], + "example": ".webhook" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_webhook" + } + } + }, + "config_properties_xmatters": { + "title": "Connector request properties for a xMatters connector", + "description": "Defines properties for connectors when type is `.xmatters`.", + "type": "object", + "additionalProperties": true + }, + "secrets_properties_xmatters": { + "title": "Connector secrets properties for an xMatters connector", + "description": "Defines secrets for connectors when type is `.xmatters`.", + "type": "object", + "additionalProperties": true + }, + "create_connector_request_xmatters": { + "title": "Create xMatters connector request", + "description": "The xMatters connector uses the xMatters Workflow for Elastic to send actionable alerts to on-call xMatters resources.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_xmatters" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".xmatters" + ], + "example": ".xmatters" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_xmatters" + } + } + }, + "is_deprecated": { + "type": "boolean", + "description": "Indicates whether the connector type is deprecated.", + "example": false + }, + "is_missing_secrets": { + "type": "boolean", + "description": "Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.", + "example": false + }, + "is_preconfigured": { + "type": "boolean", + "description": "Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response.", + "example": false + }, + "connector_response_properties_cases_webhook": { + "title": "Connector request properties for a Webhook - Case Management connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_cases_webhook" + }, + "connector_type_id": { + "description": "The type of connector.", + "type": "string", + "enum": [ + ".cases-webhook" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_email": { + "title": "Connector response properties for an email connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_email" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".email" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_index": { + "title": "Connector response properties for an index connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_index" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".index" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_jira": { + "title": "Connector response properties for a Jira connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_jira" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".jira" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_opsgenie": { + "title": "Connector response properties for an Opsgenie connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_opsgenie" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".opsgenie" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_pagerduty": { + "title": "Connector response properties for a PagerDuty connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_pagerduty" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".pagerduty" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_resilient": { + "title": "Connector response properties for a IBM Resilient connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_resilient" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".resilient" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_serverlog": { + "title": "Connector response properties for a server log connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "type": "object", + "nullable": true + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".server-log" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_servicenow": { + "title": "Connector response properties for a ServiceNow ITSM connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_servicenow_itom": { + "title": "Connector response properties for a ServiceNow ITOM connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow_itom" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-itom" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_servicenow_sir": { + "title": "Connector response properties for a ServiceNow SecOps connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".servicenow-sir" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_slack": { + "title": "Connector response properties for a Slack connector", + "type": "object", + "required": [ + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".slack" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_swimlane": { + "title": "Connector response properties for a Swimlane connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_swimlane" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".swimlane" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_teams": { + "title": "Connector response properties for a Microsoft Teams connector", + "type": "object", + "required": [ + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".teams" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_tines": { + "title": "Connector response properties for a Tines connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_tines" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".tines" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_webhook": { + "title": "Connector response properties for a Webhook connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_webhook" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".webhook" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties_xmatters": { + "title": "Connector response properties for an xMatters connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_xmatters" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".xmatters" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "connector_response_properties": { + "title": "Connector response properties", + "description": "The properties vary depending on the connector type.", + "oneOf": [ + { + "$ref": "#/components/schemas/connector_response_properties_cases_webhook" + }, + { + "$ref": "#/components/schemas/connector_response_properties_email" + }, + { + "$ref": "#/components/schemas/connector_response_properties_index" + }, + { + "$ref": "#/components/schemas/connector_response_properties_jira" + }, + { + "$ref": "#/components/schemas/connector_response_properties_opsgenie" + }, + { + "$ref": "#/components/schemas/connector_response_properties_pagerduty" + }, + { + "$ref": "#/components/schemas/connector_response_properties_resilient" + }, + { + "$ref": "#/components/schemas/connector_response_properties_serverlog" + }, + { + "$ref": "#/components/schemas/connector_response_properties_servicenow" + }, + { + "$ref": "#/components/schemas/connector_response_properties_servicenow_itom" + }, + { + "$ref": "#/components/schemas/connector_response_properties_servicenow_sir" + }, + { + "$ref": "#/components/schemas/connector_response_properties_slack" + }, + { + "$ref": "#/components/schemas/connector_response_properties_swimlane" + }, + { + "$ref": "#/components/schemas/connector_response_properties_teams" + }, + { + "$ref": "#/components/schemas/connector_response_properties_tines" + }, + { + "$ref": "#/components/schemas/connector_response_properties_webhook" + }, + { + "$ref": "#/components/schemas/connector_response_properties_xmatters" + } + ], + "discriminator": { + "propertyName": "connector_type_id" + } + }, + "update_connector_request_cases_webhook": { + "title": "Update Webhook - Case Managment connector request", + "type": "object", + "required": [ + "config", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_cases_webhook" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_cases_webhook" + } + } + }, + "update_connector_request_index": { + "title": "Update index connector request", + "type": "object", + "required": [ + "config", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_index" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "update_connector_request_jira": { + "title": "Update Jira connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_jira" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_jira" + } + } + }, + "update_connector_request_opsgenie": { + "title": "Update Opsgenie connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_opsgenie" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_opsgenie" + } + } + }, + "update_connector_request_resilient": { + "title": "Update IBM Resilient connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_resilient" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_resilient" + } + } + }, + "update_connector_request_serverlog": { + "title": "Update server log connector request", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, + "update_connector_request_servicenow": { + "title": "Update ServiceNow ITSM connector or ServiceNow SecOps request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "update_connector_request_servicenow_itom": { + "title": "Create ServiceNow ITOM connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_servicenow_itom" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_servicenow" + } + } + }, + "update_connector_request_swimlane": { + "title": "Update Swimlane connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_swimlane" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_swimlane" + } + } + }, "connector_types": { + "title": "Connector types", "type": "string", "description": "The type of connector. For example, `.email`, `.index`, `.jira`, `.opsgenie`, or `.server-log`.", "enum": [ @@ -388,21 +2944,6 @@ ], "example": ".server-log" }, - "is_deprecated": { - "type": "boolean", - "description": "Indicates whether the connector type is deprecated.", - "example": false - }, - "is_missing_secrets": { - "type": "boolean", - "description": "Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.", - "example": false - }, - "is_preconfigured": { - "type": "boolean", - "description": "Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response.", - "example": false - }, "features": { "type": "string", "description": "The feature that uses the connector. Valid values are `alerting`, `cases`, `uptime`, and `siem`.\n", @@ -415,6 +2956,32 @@ } }, "examples": { + "create_index_connector_request": { + "summary": "Create an index connector.", + "value": { + "name": "my-connector", + "connector_type_id": ".index", + "config": { + "index": "test-index" + } + } + }, + "create_index_connector_response": { + "summary": "A new index connector.", + "value": { + "id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad", + "connector_type_id": ".index", + "name": "my-connector", + "config": { + "index": "test-index", + "refresh": false, + "executionTimeField": null + }, + "is_preconfigured": false, + "is_deprecated": false, + "is_missing_secrets": false + } + }, "get_connector_response": { "summary": "A list of connector types", "value": { @@ -427,6 +2994,15 @@ "is_missing_secrets": false } }, + "update_index_connector_request": { + "summary": "Update an index connector.", + "value": { + "name": "updated-connector", + "config": { + "index": "updated-index" + } + } + }, "get_connectors_response": { "summary": "A list of connectors", "value": [ diff --git a/x-pack/plugins/actions/docs/openapi/bundled.yaml b/x-pack/plugins/actions/docs/openapi/bundled.yaml index 8d52047d1181b8..1ffc0dc5da1eba 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.yaml +++ b/x-pack/plugins/actions/docs/openapi/bundled.yaml @@ -15,6 +15,76 @@ servers: - url: http://localhost:5601 description: local paths: + /s/{spaceId}/api/actions/connector: + post: + summary: Creates a connector. + operationId: createConnector + description: | + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + - $ref: '#/components/parameters/space_id' + requestBody: + required: true + content: + application/json: + schema: + title: Create connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '#/components/schemas/create_connector_request_cases_webhook' + - $ref: '#/components/schemas/create_connector_request_email' + - $ref: '#/components/schemas/create_connector_request_index' + - $ref: '#/components/schemas/create_connector_request_jira' + - $ref: '#/components/schemas/create_connector_request_opsgenie' + - $ref: '#/components/schemas/create_connector_request_pagerduty' + - $ref: '#/components/schemas/create_connector_request_resilient' + - $ref: '#/components/schemas/create_connector_request_serverlog' + - $ref: '#/components/schemas/create_connector_request_servicenow' + - $ref: '#/components/schemas/create_connector_request_servicenow_itom' + - $ref: '#/components/schemas/create_connector_request_servicenow_sir' + - $ref: '#/components/schemas/create_connector_request_slack' + - $ref: '#/components/schemas/create_connector_request_swimlane' + - $ref: '#/components/schemas/create_connector_request_teams' + - $ref: '#/components/schemas/create_connector_request_tines' + - $ref: '#/components/schemas/create_connector_request_webhook' + - $ref: '#/components/schemas/create_connector_request_xmatters' + discriminator: + propertyName: connector_type_id + examples: + createIndexConnectorRequest: + $ref: '#/components/examples/create_index_connector_request' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '#/components/schemas/connector_response_properties' + examples: + createIndexConnectorResponse: + $ref: '#/components/examples/create_index_connector_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + servers: + - url: https://localhost:5601 + servers: + - url: https://localhost:5601 /s/{spaceId}/api/actions/connector/{connectorId}: get: summary: Retrieves a connector by ID. @@ -29,41 +99,44 @@ paths: responses: '200': description: Indicates a successful call. + content: + application/json: + schema: + $ref: '#/components/schemas/connector_response_properties' + examples: + getConnectorResponse: + $ref: '#/components/examples/get_connector_response' + '401': + description: Authorization information is missing or invalid. content: application/json: schema: type: object - required: - - connector_type_id - - id - - is_deprecated - - is_preconfigured - - name properties: - config: - type: object - description: The configuration for the connector. Configuration properties vary depending on the connector type. - additionalProperties: true - nullable: true - connector_type_id: - $ref: '#/components/schemas/connector_types' - id: + error: type: string - description: The identifier for the connector. - example: b0766e10-d190-11ec-b04c-776c77d14fca - is_deprecated: - $ref: '#/components/schemas/is_deprecated' - is_missing_secrets: - $ref: '#/components/schemas/is_missing_secrets' - is_preconfigured: - $ref: '#/components/schemas/is_preconfigured' - name: + example: Unauthorized + message: type: string - description: The display name for the connector. - example: my-connector - examples: - getConnectorResponse: - $ref: '#/components/examples/get_connector_response' + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 delete: @@ -80,6 +153,124 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 + servers: + - url: https://localhost:5601 + put: + summary: Updates the attributes for a connector. + operationId: updateConnector + description: | + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + - $ref: '#/components/parameters/connector_id' + - $ref: '#/components/parameters/space_id' + requestBody: + required: true + content: + application/json: + schema: + title: Update connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '#/components/schemas/update_connector_request_cases_webhook' + - $ref: '#/components/schemas/update_connector_request_index' + - $ref: '#/components/schemas/update_connector_request_jira' + - $ref: '#/components/schemas/update_connector_request_opsgenie' + - $ref: '#/components/schemas/update_connector_request_resilient' + - $ref: '#/components/schemas/update_connector_request_serverlog' + - $ref: '#/components/schemas/update_connector_request_servicenow' + - $ref: '#/components/schemas/update_connector_request_servicenow_itom' + - $ref: '#/components/schemas/update_connector_request_swimlane' + examples: + updateIndexConnectorRequest: + $ref: '#/components/examples/update_index_connector_request' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '#/components/schemas/connector_response_properties' + '400': + description: Indicates a bad request. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Bad Request + message: + type: string + example: 'error validating action type config: [index]: expected value of type [string] but got [undefined]' + statusCode: + type: integer + example: 400 + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 servers: @@ -102,6 +293,8 @@ paths: schema: type: array items: + title: Get connectors response body properties + description: The properties vary for each connector type. type: object required: - connector_type_id @@ -140,6 +333,21 @@ paths: examples: getConnectorsResponse: $ref: '#/components/examples/get_connectors_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: @@ -165,6 +373,8 @@ paths: content: application/json: schema: + title: Get connector types response body properties + description: The properties vary for each connector type. type: array items: type: object @@ -203,6 +413,21 @@ paths: examples: getConnectorTypesResponse: $ref: '#/components/examples/get_connector_types_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: @@ -217,14 +442,12 @@ components: in: header name: ApiKey parameters: - connector_id: - in: path - name: connectorId - description: An identifier for the connector. - required: true + kbn_xsrf: schema: type: string - example: df770e30-8b8b-11ed-a780-3b746c987a81 + in: header + name: kbn-xsrf + required: true space_id: in: path name: spaceId @@ -233,14 +456,1630 @@ components: schema: type: string example: default - kbn_xsrf: + connector_id: + in: path + name: connectorId + description: An identifier for the connector. + required: true schema: type: string - in: header - name: kbn-xsrf - required: true + example: df770e30-8b8b-11ed-a780-3b746c987a81 schemas: + config_properties_cases_webhook: + title: Connector request properties for Webhook - Case Management connector + required: + - createIncidentJson + - createIncidentResponseKey + - createIncidentUrl + - getIncidentResponseExternalTitleKey + - getIncidentUrl + - updateIncidentJson + - updateIncidentUrl + - viewIncidentUrl + description: Defines properties for connectors when type is `.cases-webhook`. + type: object + properties: + createCommentJson: + type: string + description: | + A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. + example: + body: + '[object Object]': null + createCommentMethod: + type: string + description: | + The REST API HTTP request method to create a case comment in the third-party system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + createCommentUrl: + type: string + description: | + The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment + createIncidentJson: + type: string + description: | + A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. + example: + fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null + createIncidentMethod: + type: string + description: | + The REST API HTTP request method to create a case in the third-party system. Valid values are `patch`, `post`, and `put`. + enum: + - patch + - post + - put + default: post + createIncidentResponseKey: + type: string + description: The JSON key in the create case response that contains the external case ID. + createIncidentUrl: + type: string + description: | + The REST API URL to create a case in the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + getIncidentResponseExternalTitleKey: + type: string + description: The JSON key in get case response that contains the external case title. + getIncidentUrl: + type: string + description: | + The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} + hasAuth: + type: boolean + description: If true, a username and password for login type authentication must be provided. + default: true + headers: + type: string + description: | + A set of key-value pairs sent as headers with the request URLs for the create case, update case, get case, and create comment methods. + updateIncidentJson: + type: string + description: | + The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. + example: + fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null + updateIncidentMethod: + type: string + description: | + The REST API HTTP request method to update the case in the third-party system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + updateIncidentUrl: + type: string + description: | + The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} + viewIncidentUrl: + type: string + description: | + The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL. + example: https://testing-jira.atlassian.net/browse/{{{external.system.title}}} + secrets_properties_cases_webhook: + title: Connector secrets properties for Webhook - Case Management connector + type: object + properties: + password: + type: string + description: The password for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. + user: + type: string + description: The username for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. + create_connector_request_cases_webhook: + title: Create Webhook - Case Managment connector request + description: | + The Webhook - Case Management connector uses axios to send POST, PUT, and GET requests to a case management RESTful API web service. + type: object + required: + - config + - connector_type_id + - name + properties: + config: + $ref: '#/components/schemas/config_properties_cases_webhook' + connector_type_id: + type: string + description: The type of connector. + enum: + - .cases-webhook + example: .cases-webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_cases_webhook' + config_properties_email: + title: Connector request properties for an email connector + description: Defines properties for connectors when type is `.email`. + type: object + additionalProperties: true + secrets_properties_email: + title: Connector secrets properties for an email connector + description: Defines secrets for connectors when type is `.email`. + type: object + additionalProperties: true + create_connector_request_email: + title: Create email connector request + description: | + The email connector uses the SMTP protocol to send mail messages, using an integration of Nodemailer. An exception is Microsoft Exchange, which uses HTTP protocol for sending emails, Send mail. Email message text is sent as both plain text and html text. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_email' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + example: .email + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_email' + config_properties_index: + title: Connector request properties for an index connector + required: + - index + description: Defines properties for connectors when type is `.index`. + type: object + properties: + executionTimeField: + description: Specifies a field that will contain the time the alert condition was detected. + default: null + type: string + nullable: true + index: + description: The Elasticsearch index to be written to. + type: string + refresh: + description: | + The refresh policy for the write request, which affects when changes are made visible to search. Refer to the refresh setting for Elasticsearch document APIs. + default: false + type: boolean + create_connector_request_index: + title: Create index connector request + description: The index connector indexes a document into Elasticsearch. + type: object + required: + - config + - connector_type_id + - name + properties: + config: + $ref: '#/components/schemas/config_properties_index' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + example: .index + name: + type: string + description: The display name for the connector. + example: my-connector + config_properties_jira: + title: Connector request properties for a Jira connector + required: + - apiUrl + - projectKey + description: Defines properties for connectors when type is `.jira`. + type: object + properties: + apiUrl: + description: The Jira instance URL. + type: string + projectKey: + description: The Jira project key. + type: string + secrets_properties_jira: + title: Connector secrets properties for a Jira connector + required: + - apiToken + - email + description: Defines secrets for connectors when type is `.jira`. + type: object + properties: + apiToken: + description: The Jira API authentication token for HTTP basic authentication. + type: string + email: + description: The account email for HTTP Basic authentication. + type: string + create_connector_request_jira: + title: Create Jira connector request + description: The Jira connector uses the REST API v2 to create Jira issues. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_jira' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + example: .jira + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_jira' + config_properties_opsgenie: + title: Connector request properties for an Opsgenie connector + required: + - apiUrl + description: Defines properties for connectors when type is `.opsgenie`. + type: object + properties: + apiUrl: + description: | + The Opsgenie URL. For example, `https://api.opsgenie.com` or `https://api.eu.opsgenie.com`. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + type: string + secrets_properties_opsgenie: + title: Connector secrets properties for an Opsgenie connector + required: + - apiKey + description: Defines secrets for connectors when type is `.opsgenie`. + type: object + properties: + apiKey: + description: The Opsgenie API authentication key for HTTP Basic authentication. + type: string + create_connector_request_opsgenie: + title: Create Opsgenie connector request + description: The Opsgenie connector uses the Opsgenie alert API. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_opsgenie' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + example: .opsgenie + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_opsgenie' + config_properties_pagerduty: + title: Connector request properties for a PagerDuty connector + description: Defines properties for connectors when type is `.pagerduty`. + type: object + additionalProperties: true + secrets_properties_pagerduty: + title: Connector secrets properties for a PagerDuty connector + description: Defines secrets for connectors when type is `.pagerduty`. + type: object + additionalProperties: true + create_connector_request_pagerduty: + title: Create PagerDuty connector request + description: | + The PagerDuty connector uses the v2 Events API to trigger, acknowledge, and resolve PagerDuty alerts. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_pagerduty' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + example: .pagerduty + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_pagerduty' + config_properties_resilient: + title: Connector request properties for a IBM Resilient connector + required: + - apiUrl + - orgId + description: Defines properties for connectors when type is `.resilient`. + type: object + properties: + apiUrl: + description: The IBM Resilient instance URL. + type: string + orgId: + description: The IBM Resilient organization ID. + type: string + secrets_properties_resilient: + title: Connector secrets properties for IBM Resilient connector + required: + - apiKeyId + - apiKeySecret + description: Defines secrets for connectors when type is `.resilient`. + type: object + properties: + apiKeyId: + type: string + description: The authentication key ID for HTTP Basic authentication. + apiKeySecret: + type: string + description: The authentication key secret for HTTP Basic authentication. + create_connector_request_resilient: + title: Create IBM Resilient connector request + description: The IBM Resilient connector uses the RESILIENT REST v2 to create IBM Resilient incidents. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_resilient' + connector_type_id: + description: The type of connector. + type: string + example: .resilient + enum: + - .resilient + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_resilient' + create_connector_request_serverlog: + title: Create server log connector request + description: This connector writes an entry to the Kibana server log. + type: object + required: + - connector_type_id + - name + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + example: .server-log + name: + type: string + description: The display name for the connector. + example: my-connector + config_properties_servicenow: + title: Connector request properties for a ServiceNow ITSM connector + required: + - apiUrl + description: Defines properties for connectors when type is `.servicenow`. + type: object + properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: | + The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: | + The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: | + The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: | + The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`. + type: string + usesTableApi: + description: | + Determines whether the connector uses the Table API or the Import Set API. This property is supported only for ServiceNow ITSM and ServiceNow SecOps connectors. NOTE: If this property is set to `false`, the Elastic application should be installed in ServiceNow. + default: true + type: boolean + secrets_properties_servicenow: + title: Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors + description: Defines secrets for connectors when type is `.servicenow`, `.servicenow-sir`, or `.servicenow-itom`. + type: object + properties: + clientSecret: + type: string + description: The client secret assigned to your OAuth application. This property is required when `isOAuth` is `true`. + password: + type: string + description: The password for HTTP basic authentication. This property is required when `isOAuth` is `false`. + privateKey: + type: string + description: The RSA private key that you created for use in ServiceNow. This property is required when `isOAuth` is `true`. + privateKeyPassword: + type: string + description: The password for the RSA private key. This property is required when `isOAuth` is `true` and you set a password on your private key. + username: + type: string + description: The username for HTTP basic authentication. This property is required when `isOAuth` is `false`. + create_connector_request_servicenow: + title: Create ServiceNow ITSM connector request + description: | + The ServiceNow ITSM connector uses the import set API to create ServiceNow incidents. You can use the connector for rule actions and cases. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + example: .servicenow + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + config_properties_servicenow_itom: + title: Connector request properties for a ServiceNow ITSM connector + required: + - apiUrl + description: Defines properties for connectors when type is `.servicenow`. + type: object + properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: | + The client ID assigned to your OAuth application. This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: | + The type of authentication to use. The default value is false, which means basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: | + The key identifier assigned to the JWT verifier map of your OAuth application. This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: | + The identifier to use for OAuth authentication. This identifier should be the user field you selected when you created an OAuth JWT API endpoint for external clients in your ServiceNow instance. For example, if the selected user field is `Email`, the user identifier should be the user's email address. This property is required when `isOAuth` is `true`. + type: string + create_connector_request_servicenow_itom: + title: Create ServiceNow ITOM connector request + description: | + The ServiceNow ITOM connector uses the event API to create ServiceNow events. You can use the connector for rule actions. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow_itom' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + example: .servicenow-itom + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + create_connector_request_servicenow_sir: + title: Create ServiceNow SecOps connector request + description: | + The ServiceNow SecOps connector uses the import set API to create ServiceNow security incidents. You can use the connector for rule actions and cases. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + example: .servicenow-sir + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + secrets_properties_slack: + title: Connector secrets properties for a Slack connector + description: Defines secrets for connectors when type is `.slack`. + type: object + additionalProperties: true + create_connector_request_slack: + title: Create Slack connector request + description: The Slack connector uses Slack Incoming Webhooks. + type: object + required: + - connector_type_id + - name + - secrets + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + example: .slack + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_slack' + config_properties_swimlane: + title: Connector request properties for a Swimlane connector + required: + - apiUrl + - appId + - connectorType + description: Defines properties for connectors when type is `.swimlane`. + type: object + properties: + apiUrl: + description: The Swimlane instance URL. + type: string + appId: + description: The Swimlane application ID. + type: string + connectorType: + description: The type of connector. Valid values are `all`, `alerts`, and `cases`. + type: string + enum: + - all + - alerts + - cases + mappings: + title: Connector mappings properties for a Swimlane connector + description: The field mapping. + type: object + properties: + alertIdConfig: + title: Alert identifier mapping + description: Mapping for the alert ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + caseIdConfig: + title: Case identifier mapping + description: Mapping for the case ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + caseNameConfig: + title: Case name mapping + description: Mapping for the case name. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + commentsConfig: + title: Case comment mapping + description: Mapping for the case comments. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + descriptionConfig: + title: Case description mapping + description: Mapping for the case description. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + ruleNameConfig: + title: Rule name mapping + description: Mapping for the name of the alert's rule. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + severityConfig: + title: Severity mapping + description: Mapping for the severity. + type: object + required: + - fieldType + - id + - key + - name + properties: + fieldType: + type: string + description: The type of field in Swimlane. + id: + type: string + description: The identifier for the field in Swimlane. + key: + type: string + description: The key for the field in Swimlane. + name: + type: string + description: The name of the field in Swimlane. + secrets_properties_swimlane: + title: Connector secrets properties for a Swimlane connector + description: Defines secrets for connectors when type is `.swimlane`. + type: object + properties: + apiToken: + description: Swimlane API authentication token. + type: string + create_connector_request_swimlane: + title: Create Swimlane connector request + description: The Swimlane connector uses the Swimlane REST API to create Swimlane records. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_swimlane' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + example: .swimlane + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_swimlane' + secrets_properties_teams: + title: Connector secrets properties for a Microsoft Teams connector + description: Defines secrets for connectors when type is `.teams`. + type: object + additionalProperties: true + create_connector_request_teams: + title: Create Microsoft Teams connector request + description: The Microsoft Teams connector uses Incoming Webhooks. + type: object + required: + - connector_type_id + - name + - secrets + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + example: .teams + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_teams' + config_properties_tines: + title: Connector request properties for a Tines connector + description: Defines properties for connectors when type is `.tines`. + type: object + additionalProperties: true + secrets_properties_tines: + title: Connector secrets properties for a Tines connector + description: Defines secrets for connectors when type is `.tines`. + type: object + additionalProperties: true + create_connector_request_tines: + title: Create Tines connector request + description: | + The Tines connector uses Tines Webhook actions to send events via POST request. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_tines' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + example: .tines + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_tines' + config_properties_webhook: + title: Connector request properties for a Webhook connector + description: Defines properties for connectors when type is `.webhook`. + type: object + additionalProperties: true + secrets_properties_webhook: + title: Connector secrets properties for a Webhook connector + description: Defines secrets for connectors when type is `.webhook`. + type: object + additionalProperties: true + create_connector_request_webhook: + title: Create Webhook connector request + description: | + The Webhook connector uses axios to send a POST or PUT request to a web service. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_webhook' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + example: .webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_webhook' + config_properties_xmatters: + title: Connector request properties for a xMatters connector + description: Defines properties for connectors when type is `.xmatters`. + type: object + additionalProperties: true + secrets_properties_xmatters: + title: Connector secrets properties for an xMatters connector + description: Defines secrets for connectors when type is `.xmatters`. + type: object + additionalProperties: true + create_connector_request_xmatters: + title: Create xMatters connector request + description: | + The xMatters connector uses the xMatters Workflow for Elastic to send actionable alerts to on-call xMatters resources. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_xmatters' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + example: .xmatters + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_xmatters' + is_deprecated: + type: boolean + description: Indicates whether the connector type is deprecated. + example: false + is_missing_secrets: + type: boolean + description: Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type. + example: false + is_preconfigured: + type: boolean + description: Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. + example: false + connector_response_properties_cases_webhook: + title: Connector request properties for a Webhook - Case Management connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_cases_webhook' + connector_type_id: + description: The type of connector. + type: string + enum: + - .cases-webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_email: + title: Connector response properties for an email connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_email' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_index: + title: Connector response properties for an index connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_index' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_jira: + title: Connector response properties for a Jira connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_jira' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_opsgenie: + title: Connector response properties for an Opsgenie connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_opsgenie' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_pagerduty: + title: Connector response properties for a PagerDuty connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_pagerduty' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_resilient: + title: Connector response properties for a IBM Resilient connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_resilient' + connector_type_id: + type: string + description: The type of connector. + enum: + - .resilient + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_serverlog: + title: Connector response properties for a server log connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + type: object + nullable: true + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_servicenow: + title: Connector response properties for a ServiceNow ITSM connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_servicenow_itom: + title: Connector response properties for a ServiceNow ITOM connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow_itom' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_servicenow_sir: + title: Connector response properties for a ServiceNow SecOps connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_slack: + title: Connector response properties for a Slack connector + type: object + required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_swimlane: + title: Connector response properties for a Swimlane connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_swimlane' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_teams: + title: Connector response properties for a Microsoft Teams connector + type: object + required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_tines: + title: Connector response properties for a Tines connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_tines' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_webhook: + title: Connector response properties for a Webhook connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_webhook' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties_xmatters: + title: Connector response properties for an xMatters connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_xmatters' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + name: + type: string + description: The display name for the connector. + connector_response_properties: + title: Connector response properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '#/components/schemas/connector_response_properties_cases_webhook' + - $ref: '#/components/schemas/connector_response_properties_email' + - $ref: '#/components/schemas/connector_response_properties_index' + - $ref: '#/components/schemas/connector_response_properties_jira' + - $ref: '#/components/schemas/connector_response_properties_opsgenie' + - $ref: '#/components/schemas/connector_response_properties_pagerduty' + - $ref: '#/components/schemas/connector_response_properties_resilient' + - $ref: '#/components/schemas/connector_response_properties_serverlog' + - $ref: '#/components/schemas/connector_response_properties_servicenow' + - $ref: '#/components/schemas/connector_response_properties_servicenow_itom' + - $ref: '#/components/schemas/connector_response_properties_servicenow_sir' + - $ref: '#/components/schemas/connector_response_properties_slack' + - $ref: '#/components/schemas/connector_response_properties_swimlane' + - $ref: '#/components/schemas/connector_response_properties_teams' + - $ref: '#/components/schemas/connector_response_properties_tines' + - $ref: '#/components/schemas/connector_response_properties_webhook' + - $ref: '#/components/schemas/connector_response_properties_xmatters' + discriminator: + propertyName: connector_type_id + update_connector_request_cases_webhook: + title: Update Webhook - Case Managment connector request + type: object + required: + - config + - name + properties: + config: + $ref: '#/components/schemas/config_properties_cases_webhook' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_cases_webhook' + update_connector_request_index: + title: Update index connector request + type: object + required: + - config + - name + properties: + config: + $ref: '#/components/schemas/config_properties_index' + name: + type: string + description: The display name for the connector. + update_connector_request_jira: + title: Update Jira connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_jira' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_jira' + update_connector_request_opsgenie: + title: Update Opsgenie connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_opsgenie' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_opsgenie' + update_connector_request_resilient: + title: Update IBM Resilient connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_resilient' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_resilient' + update_connector_request_serverlog: + title: Update server log connector request + type: object + required: + - name + properties: + name: + type: string + description: The display name for the connector. + update_connector_request_servicenow: + title: Update ServiceNow ITSM connector or ServiceNow SecOps request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + update_connector_request_servicenow_itom: + title: Create ServiceNow ITOM connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_servicenow_itom' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_servicenow' + update_connector_request_swimlane: + title: Update Swimlane connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_swimlane' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_swimlane' connector_types: + title: Connector types type: string description: The type of connector. For example, `.email`, `.index`, `.jira`, `.opsgenie`, or `.server-log`. enum: @@ -262,18 +2101,6 @@ components: - .webhook - .xmatters example: .server-log - is_deprecated: - type: boolean - description: Indicates whether the connector type is deprecated. - example: false - is_missing_secrets: - type: boolean - description: Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type. - example: false - is_preconfigured: - type: boolean - description: Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. - example: false features: type: string description: | @@ -284,6 +2111,26 @@ components: - uptime - siem examples: + create_index_connector_request: + summary: Create an index connector. + value: + name: my-connector + connector_type_id: .index + config: + index: test-index + create_index_connector_response: + summary: A new index connector. + value: + id: c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad + connector_type_id: .index + name: my-connector + config: + index: test-index + refresh: false + executionTimeField: null + is_preconfigured: false + is_deprecated: false + is_missing_secrets: false get_connector_response: summary: A list of connector types value: @@ -294,6 +2141,12 @@ components: is_preconfigured: false is_deprecated: false is_missing_secrets: false + update_index_connector_request: + summary: Update an index connector. + value: + name: updated-connector + config: + index: updated-index get_connectors_response: summary: A list of connectors value: diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_request.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_request.yaml new file mode 100644 index 00000000000000..3a0a3daa043ddb --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_request.yaml @@ -0,0 +1,6 @@ +summary: Create an index connector. +value: + name: my-connector + connector_type_id: .index + config: + index: test-index \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_response.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_response.yaml new file mode 100644 index 00000000000000..4d13a5d4135981 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/create_index_connector_response.yaml @@ -0,0 +1,12 @@ +summary: A new index connector. +value: + id: c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad + connector_type_id: .index + name: my-connector + config: + index: test-index + refresh: false + executionTimeField: null + is_preconfigured: false + is_deprecated: false + is_missing_secrets: false \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/update_index_connector_request.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/update_index_connector_request.yaml new file mode 100644 index 00000000000000..79b9463a6be51d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/update_index_connector_request.yaml @@ -0,0 +1,5 @@ +summary: Update an index connector. +value: + name: updated-connector + config: + index: updated-index \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml new file mode 100644 index 00000000000000..43945fbb241a2f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml @@ -0,0 +1,135 @@ +title: Connector request properties for Webhook - Case Management connector +required: + - createIncidentJson + - createIncidentResponseKey + - createIncidentUrl + - getIncidentResponseExternalTitleKey + - getIncidentUrl + - updateIncidentJson + - updateIncidentUrl + - viewIncidentUrl +description: Defines properties for connectors when type is `.cases-webhook`. +type: object +properties: + createCommentJson: + type: string + description: > + A JSON payload sent to the create comment URL to create a case comment. + You can use variables to add Kibana Cases data to the payload. + The required variable is `case.comment`. Due to Mustache template + variables (the text enclosed in triple braces, for example, + `{{{case.title}}}`), the JSON is not validated when you create the + connector. The JSON is validated once the Mustache variables have been + placed when the REST method runs. Manually ensure that the JSON is valid, + disregarding the Mustache variables, so the later validation will pass. + example: {"body": {{{case.comment}}}} + createCommentMethod: + type: string + description: > + The REST API HTTP request method to create a case comment in the + third-party system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + createCommentUrl: + type: string + description: > + The REST API URL to create a case comment by ID in the third-party system. + You can use a variable to add the external system ID to the URL. If you + are using the `xpack.actions.allowedHosts setting`, add the hostname to + the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment + createIncidentJson: + type: string + description: > + A JSON payload sent to the create case URL to create a case. You can use + variables to add case data to the payload. Required variables are + `case.title` and `case.description`. Due to Mustache template variables + (which is the text enclosed in triple braces, for example, + `{{{case.title}}}`), the JSON is not validated when you create the + connector. The JSON is validated after the Mustache variables have been + placed when REST method runs. Manually ensure that the JSON is valid to + avoid future validation errors; disregard Mustache variables during your review. + example: {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} + createIncidentMethod: + type: string + description: > + The REST API HTTP request method to create a case in the third-party + system. Valid values are `patch`, `post`, and `put`. + enum: + - patch + - post + - put + default: post + createIncidentResponseKey: + type: string + description: The JSON key in the create case response that contains the external case ID. + createIncidentUrl: + type: string + description: > + The REST API URL to create a case in the third-party system. If you are + using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + getIncidentResponseExternalTitleKey: + type: string + description: The JSON key in get case response that contains the external case title. + getIncidentUrl: + type: string + description: > + The REST API URL to get the case by ID from the third-party system. If you + are using the `xpack.actions.allowedHosts` setting, add the hostname to + the allowed hosts. You can use a variable to add the external system ID to + the URL. Due to Mustache template variables (the text enclosed in triple + braces, for example, `{{{case.title}}}`), the JSON is not validated when + you create the connector. The JSON is validated after the Mustache + variables have been placed when REST method runs. Manually ensure that the + JSON is valid, disregarding the Mustache variables, so the later + validation will pass. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} + hasAuth: + type: boolean + description: If true, a username and password for login type authentication must be provided. + default: true + headers: + type: string + description: > + A set of key-value pairs sent as headers with the request URLs for the + create case, update case, get case, and create comment methods. + updateIncidentJson: + type: string + description: > + The JSON payload sent to the update case URL to update the case. You can + use variables to add Kibana Cases data to the payload. Required variables + are `case.title` and `case.description`. Due to Mustache template + variables (which is the text enclosed in triple braces, for example, + `{{{case.title}}}`), the JSON is not validated when you create the + connector. The JSON is validated after the Mustache variables have been + placed when REST method runs. Manually ensure that the JSON is valid to + avoid future validation errors; disregard Mustache variables during your review. + example: {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} + updateIncidentMethod: + type: string + description: > + The REST API HTTP request method to update the case in the third-party + system. Valid values are `patch`, `post`, and `put`. + default: put + enum: + - patch + - post + - put + updateIncidentUrl: + type: string + description: > + The REST API URL to update the case by ID in the third-party system. You + can use a variable to add the external system ID to the URL. If you are + using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} + viewIncidentUrl: + type: string + description: > + The URL to view the case in the external system. You can use variables to + add the external system ID or external system title to the URL. + example: https://testing-jira.atlassian.net/browse/{{{external.system.title}}} + + diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml new file mode 100644 index 00000000000000..d87c36be089368 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for an email connector +description: Defines properties for connectors when type is `.email`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml new file mode 100644 index 00000000000000..c82f775fe15dc7 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml @@ -0,0 +1,21 @@ +title: Connector request properties for an index connector +required: + - index +description: Defines properties for connectors when type is `.index`. +type: object +properties: + executionTimeField: + description: Specifies a field that will contain the time the alert condition was detected. + default: null + type: string + nullable: true + index: + description: The Elasticsearch index to be written to. + type: string + refresh: + description: > + The refresh policy for the write request, which affects when changes are + made visible to search. Refer to the refresh setting for Elasticsearch + document APIs. + default: false + type: boolean diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_jira.yaml new file mode 100644 index 00000000000000..1634eb83cbf594 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_jira.yaml @@ -0,0 +1,13 @@ +title: Connector request properties for a Jira connector +required: + - apiUrl + - projectKey +description: Defines properties for connectors when type is `.jira`. +type: object +properties: + apiUrl: + description: The Jira instance URL. + type: string + projectKey: + description: The Jira project key. + type: string diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_opsgenie.yaml new file mode 100644 index 00000000000000..504d536cbde3e8 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_opsgenie.yaml @@ -0,0 +1,12 @@ +title: Connector request properties for an Opsgenie connector +required: + - apiUrl +description: Defines properties for connectors when type is `.opsgenie`. +type: object +properties: + apiUrl: + description: > + The Opsgenie URL. For example, `https://api.opsgenie.com` or + `https://api.eu.opsgenie.com`. If you are using the + `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml new file mode 100644 index 00000000000000..c9a98a9619d85d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a PagerDuty connector +description: Defines properties for connectors when type is `.pagerduty`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_resilient.yaml new file mode 100644 index 00000000000000..444be13ce4885d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_resilient.yaml @@ -0,0 +1,13 @@ +title: Connector request properties for a IBM Resilient connector +required: + - apiUrl + - orgId +description: Defines properties for connectors when type is `.resilient`. +type: object +properties: + apiUrl: + description: The IBM Resilient instance URL. + type: string + orgId: + description: The IBM Resilient organization ID. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow.yaml new file mode 100644 index 00000000000000..f7013535f2e51f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow.yaml @@ -0,0 +1,41 @@ +title: Connector request properties for a ServiceNow ITSM connector +required: + - apiUrl +description: Defines properties for connectors when type is `.servicenow`. +type: object +properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: > + The client ID assigned to your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: > + The type of authentication to use. The default value is false, which means + basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: > + The key identifier assigned to the JWT verifier map of your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: > + The identifier to use for OAuth authentication. This identifier should be + the user field you selected when you created an OAuth JWT API endpoint for + external clients in your ServiceNow instance. For example, if the selected + user field is `Email`, the user identifier should be the user's email + address. This property is required when `isOAuth` is `true`. + type: string + usesTableApi: + description: > + Determines whether the connector uses the Table API or the Import Set API. + This property is supported only for ServiceNow ITSM and ServiceNow SecOps + connectors. NOTE: If this property is set to `false`, the Elastic + application should be installed in ServiceNow. + default: true + type: boolean \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow_itom.yaml new file mode 100644 index 00000000000000..f35f96629c861b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_servicenow_itom.yaml @@ -0,0 +1,33 @@ +title: Connector request properties for a ServiceNow ITSM connector +required: + - apiUrl +description: Defines properties for connectors when type is `.servicenow`. +type: object +properties: + apiUrl: + type: string + description: The ServiceNow instance URL. + clientId: + description: > + The client ID assigned to your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + isOAuth: + description: > + The type of authentication to use. The default value is false, which means + basic authentication is used instead of open authorization (OAuth). + default: false + type: string + jwtKeyId: + description: > + The key identifier assigned to the JWT verifier map of your OAuth application. + This property is required when `isOAuth` is `true`. + type: string + userIdentifierValue: + description: > + The identifier to use for OAuth authentication. This identifier should be + the user field you selected when you created an OAuth JWT API endpoint for + external clients in your ServiceNow instance. For example, if the selected + user field is `Email`, the user identifier should be the user's email + address. This property is required when `isOAuth` is `true`. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_swimlane.yaml new file mode 100644 index 00000000000000..905112276acbe2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_swimlane.yaml @@ -0,0 +1,103 @@ +title: Connector request properties for a Swimlane connector +required: + - apiUrl + - appId + - connectorType +description: Defines properties for connectors when type is `.swimlane`. +type: object +properties: + apiUrl: + description: The Swimlane instance URL. + type: string + appId: + description: The Swimlane application ID. + type: string + connectorType: + description: The type of connector. Valid values are `all`, `alerts`, and `cases`. + type: string + enum: + - all + - alerts + - cases + mappings: + title: Connector mappings properties for a Swimlane connector + description: The field mapping. + type: object + properties: + alertIdConfig: + title: Alert identifier mapping + description: Mapping for the alert ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + caseIdConfig: + title: Case identifier mapping + description: Mapping for the case ID. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + caseNameConfig: + title: Case name mapping + description: Mapping for the case name. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + commentsConfig: + title: Case comment mapping + description: Mapping for the case comments. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + descriptionConfig: + title: Case description mapping + description: Mapping for the case description. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + ruleNameConfig: + title: Rule name mapping + description: Mapping for the name of the alert's rule. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' + severityConfig: + title: Severity mapping + description: Mapping for the severity. + type: object + required: + - fieldType + - id + - key + - name + properties: + $ref: 'mapping_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml new file mode 100644 index 00000000000000..336a312d9ac8e6 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a Tines connector +description: Defines properties for connectors when type is `.tines`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml new file mode 100644 index 00000000000000..6fffd356527af6 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a Webhook connector +description: Defines properties for connectors when type is `.webhook`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml new file mode 100644 index 00000000000000..6625eb09b4d35d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml @@ -0,0 +1,5 @@ +title: Connector request properties for a xMatters connector +description: Defines properties for connectors when type is `.xmatters`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml new file mode 100644 index 00000000000000..b73584568df6b2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml @@ -0,0 +1,22 @@ +title: Connector response properties +description: The properties vary depending on the connector type. +oneOf: + - $ref: 'connector_response_properties_cases_webhook.yaml' + - $ref: 'connector_response_properties_email.yaml' + - $ref: 'connector_response_properties_index.yaml' + - $ref: 'connector_response_properties_jira.yaml' + - $ref: 'connector_response_properties_opsgenie.yaml' + - $ref: 'connector_response_properties_pagerduty.yaml' + - $ref: 'connector_response_properties_resilient.yaml' + - $ref: 'connector_response_properties_serverlog.yaml' + - $ref: 'connector_response_properties_servicenow.yaml' + - $ref: 'connector_response_properties_servicenow_itom.yaml' + - $ref: 'connector_response_properties_servicenow_sir.yaml' + - $ref: 'connector_response_properties_slack.yaml' + - $ref: 'connector_response_properties_swimlane.yaml' + - $ref: 'connector_response_properties_teams.yaml' + - $ref: 'connector_response_properties_tines.yaml' + - $ref: 'connector_response_properties_webhook.yaml' + - $ref: 'connector_response_properties_xmatters.yaml' +discriminator: + propertyName: connector_type_id diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_cases_webhook.yaml new file mode 100644 index 00000000000000..88611b62b2c99b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_cases_webhook.yaml @@ -0,0 +1,29 @@ +title: Connector request properties for a Webhook - Case Management connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_cases_webhook.yaml' + connector_type_id: + description: The type of connector. + type: string + enum: + - .cases-webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_email.yaml new file mode 100644 index 00000000000000..62dac0309889ec --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_email.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an email connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_email.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_index.yaml new file mode 100644 index 00000000000000..d78d609a09b9db --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_index.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an index connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_index.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_jira.yaml new file mode 100644 index 00000000000000..5ff5807e200a8a --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_jira.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Jira connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_jira.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_opsgenie.yaml new file mode 100644 index 00000000000000..850454db1a3ad1 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_opsgenie.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an Opsgenie connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_opsgenie.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_pagerduty.yaml new file mode 100644 index 00000000000000..137108efd3e14f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_pagerduty.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a PagerDuty connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_pagerduty.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_resilient.yaml new file mode 100644 index 00000000000000..9250c4157c6601 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_resilient.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a IBM Resilient connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_resilient.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .resilient + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml new file mode 100644 index 00000000000000..999a8f375d1179 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml @@ -0,0 +1,30 @@ +title: Connector response properties for a server log connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + type: object + nullable: true + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow.yaml new file mode 100644 index 00000000000000..a5f9d1afa0077b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a ServiceNow ITSM connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_itom.yaml new file mode 100644 index 00000000000000..812d367cfb17cb --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_itom.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a ServiceNow ITOM connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_servicenow_itom.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_sir.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_sir.yaml new file mode 100644 index 00000000000000..ff99f5682f129c --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_servicenow_sir.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a ServiceNow SecOps connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_slack.yaml new file mode 100644 index 00000000000000..d0254e05183166 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_slack.yaml @@ -0,0 +1,26 @@ +title: Connector response properties for a Slack connector +type: object +required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_swimlane.yaml new file mode 100644 index 00000000000000..421abcf666038a --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_swimlane.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Swimlane connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_swimlane.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_teams.yaml new file mode 100644 index 00000000000000..bafc86f2b2977e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_teams.yaml @@ -0,0 +1,26 @@ +title: Connector response properties for a Microsoft Teams connector +type: object +required: + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_tines.yaml new file mode 100644 index 00000000000000..f89f85a30cd4f2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_tines.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Tines connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_tines.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_webhook.yaml new file mode 100644 index 00000000000000..011c39abd7ae03 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_webhook.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for a Webhook connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_webhook.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_xmatters.yaml new file mode 100644 index 00000000000000..6476adb1ab9373 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_xmatters.yaml @@ -0,0 +1,29 @@ +title: Connector response properties for an xMatters connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_xmatters.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml index 1923096b858c7f..fed928120b3957 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml @@ -1,3 +1,4 @@ +title: Connector types type: string description: The type of connector. For example, `.email`, `.index`, `.jira`, `.opsgenie`, or `.server-log`. enum: diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml new file mode 100644 index 00000000000000..bcbe840c03513c --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml @@ -0,0 +1,24 @@ +title: Create Webhook - Case Managment connector request +description: > + The Webhook - Case Management connector uses axios to send POST, PUT, and GET + requests to a case management RESTful API web service. +type: object +required: + - config + - connector_type_id + - name +properties: + config: + $ref: 'config_properties_cases_webhook.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .cases-webhook + example: .cases-webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_cases_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml new file mode 100644 index 00000000000000..89f0b79c4e74be --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml @@ -0,0 +1,27 @@ +title: Create email connector request +description: > + The email connector uses the SMTP protocol to send mail messages, using an + integration of Nodemailer. An exception is Microsoft Exchange, which uses + HTTP protocol for sending emails, Send mail. Email message text is sent as + both plain text and html text. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_email.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .email + example: .email + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_email.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml new file mode 100644 index 00000000000000..26d6e118c1fe8d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml @@ -0,0 +1,20 @@ +title: Create index connector request +description: The index connector indexes a document into Elasticsearch. +type: object +required: + - config + - connector_type_id + - name +properties: + config: + $ref: 'config_properties_index.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .index + example: .index + name: + type: string + description: The display name for the connector. + example: my-connector \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml new file mode 100644 index 00000000000000..5b6077e875b24c --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml @@ -0,0 +1,23 @@ +title: Create Jira connector request +description: The Jira connector uses the REST API v2 to create Jira issues. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_jira.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .jira + example: .jira + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_jira.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml new file mode 100644 index 00000000000000..6de1296dac43cd --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml @@ -0,0 +1,23 @@ +title: Create Opsgenie connector request +description: The Opsgenie connector uses the Opsgenie alert API. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_opsgenie.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .opsgenie + example: .opsgenie + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_opsgenie.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml new file mode 100644 index 00000000000000..498488299afd37 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml @@ -0,0 +1,25 @@ +title: Create PagerDuty connector request +description: > + The PagerDuty connector uses the v2 Events API to trigger, acknowledge, and + resolve PagerDuty alerts. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_pagerduty.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .pagerduty + example: .pagerduty + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_pagerduty.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml new file mode 100644 index 00000000000000..c3f766625b7da0 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml @@ -0,0 +1,23 @@ +title: Create IBM Resilient connector request +description: The IBM Resilient connector uses the RESILIENT REST v2 to create IBM Resilient incidents. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_resilient.yaml' + connector_type_id: + description: The type of connector. + type: string + example: .resilient + enum: + - .resilient + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_resilient.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml new file mode 100644 index 00000000000000..eac0a0d65b69f3 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml @@ -0,0 +1,17 @@ +title: Create server log connector request +description: This connector writes an entry to the Kibana server log. +type: object +required: + - connector_type_id + - name +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .server-log + example: .server-log + name: + type: string + description: The display name for the connector. + example: my-connector \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml new file mode 100644 index 00000000000000..e03303dcada4fb --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml @@ -0,0 +1,25 @@ +title: Create ServiceNow ITSM connector request +description: > + The ServiceNow ITSM connector uses the import set API to create ServiceNow incidents. + You can use the connector for rule actions and cases. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow + example: .servicenow + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml new file mode 100644 index 00000000000000..70a4c05c96522e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml @@ -0,0 +1,25 @@ +title: Create ServiceNow ITOM connector request +description: > + The ServiceNow ITOM connector uses the event API to create ServiceNow events. + You can use the connector for rule actions. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow_itom.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-itom + example: .servicenow-itom + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml new file mode 100644 index 00000000000000..4d247c456f3e62 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml @@ -0,0 +1,25 @@ +title: Create ServiceNow SecOps connector request +description: > + The ServiceNow SecOps connector uses the import set API to create ServiceNow security incidents. + You can use the connector for rule actions and cases. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .servicenow-sir + example: .servicenow-sir + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack.yaml new file mode 100644 index 00000000000000..0634d48b543a1e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack.yaml @@ -0,0 +1,20 @@ +title: Create Slack connector request +description: The Slack connector uses Slack Incoming Webhooks. +type: object +required: + - connector_type_id + - name + - secrets +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .slack + example: .slack + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_slack.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml new file mode 100644 index 00000000000000..3de4f5ecbcceff --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml @@ -0,0 +1,23 @@ +title: Create Swimlane connector request +description: The Swimlane connector uses the Swimlane REST API to create Swimlane records. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_swimlane.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .swimlane + example: .swimlane + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml new file mode 100644 index 00000000000000..5e0d449bf5546c --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml @@ -0,0 +1,20 @@ +title: Create Microsoft Teams connector request +description: The Microsoft Teams connector uses Incoming Webhooks. +type: object +required: + - connector_type_id + - name + - secrets +properties: + connector_type_id: + type: string + description: The type of connector. + enum: + - .teams + example: .teams + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_teams.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml new file mode 100644 index 00000000000000..224c3e03c43632 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml @@ -0,0 +1,24 @@ +title: Create Tines connector request +description: > + The Tines connector uses Tines Webhook actions to send events via POST request. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_tines.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .tines + example: .tines + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_tines.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml new file mode 100644 index 00000000000000..e0ead115d48dc6 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml @@ -0,0 +1,24 @@ +title: Create Webhook connector request +description: > + The Webhook connector uses axios to send a POST or PUT request to a web service. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_webhook.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .webhook + example: .webhook + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml new file mode 100644 index 00000000000000..13213d39561b28 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml @@ -0,0 +1,25 @@ +title: Create xMatters connector request +description: > + The xMatters connector uses the xMatters Workflow for Elastic to send + actionable alerts to on-call xMatters resources. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_xmatters.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .xmatters + example: .xmatters + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_xmatters.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/mapping_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/mapping_properties_swimlane.yaml new file mode 100644 index 00000000000000..9adacdd102d580 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/mapping_properties_swimlane.yaml @@ -0,0 +1,13 @@ +fieldType: + type: string + description: The type of field in Swimlane. +id: + type: string + description: The identifier for the field in Swimlane. +key: + type: string + description: The key for the field in Swimlane. +name: + type: string + description: The name of the field in Swimlane. + \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_cases_webhook.yaml new file mode 100644 index 00000000000000..571a88975a0e8b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_cases_webhook.yaml @@ -0,0 +1,9 @@ +title: Connector secrets properties for Webhook - Case Management connector +type: object +properties: + password: + type: string + description: The password for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. + user: + type: string + description: The username for HTTP basic authentication. If `hasAuth` is set to `true`, this property is required. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_email.yaml new file mode 100644 index 00000000000000..04a3526b72ce3f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_email.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for an email connector +description: Defines secrets for connectors when type is `.email`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_jira.yaml new file mode 100644 index 00000000000000..dba25d0646ae8e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_jira.yaml @@ -0,0 +1,13 @@ +title: Connector secrets properties for a Jira connector +required: + - apiToken + - email +description: Defines secrets for connectors when type is `.jira`. +type: object +properties: + apiToken: + description: The Jira API authentication token for HTTP basic authentication. + type: string + email: + description: The account email for HTTP Basic authentication. + type: string diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_opsgenie.yaml new file mode 100644 index 00000000000000..fc827886e3136a --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_opsgenie.yaml @@ -0,0 +1,9 @@ +title: Connector secrets properties for an Opsgenie connector +required: + - apiKey +description: Defines secrets for connectors when type is `.opsgenie`. +type: object +properties: + apiKey: + description: The Opsgenie API authentication key for HTTP Basic authentication. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_pagerduty.yaml new file mode 100644 index 00000000000000..14d0c6fbefd694 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_pagerduty.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a PagerDuty connector +description: Defines secrets for connectors when type is `.pagerduty`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_resilient.yaml new file mode 100644 index 00000000000000..c4500a208ee94f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_resilient.yaml @@ -0,0 +1,13 @@ +title: Connector secrets properties for IBM Resilient connector +required: + - apiKeyId + - apiKeySecret +description: Defines secrets for connectors when type is `.resilient`. +type: object +properties: + apiKeyId: + type: string + description: The authentication key ID for HTTP Basic authentication. + apiKeySecret: + type: string + description: The authentication key secret for HTTP Basic authentication. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_servicenow.yaml new file mode 100644 index 00000000000000..ed70fa840ecc0c --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_servicenow.yaml @@ -0,0 +1,19 @@ +title: Connector secrets properties for ServiceNow ITOM, ServiceNow ITSM, and ServiceNow SecOps connectors +description: Defines secrets for connectors when type is `.servicenow`, `.servicenow-sir`, or `.servicenow-itom`. +type: object +properties: + clientSecret: + type: string + description: The client secret assigned to your OAuth application. This property is required when `isOAuth` is `true`. + password: + type: string + description: The password for HTTP basic authentication. This property is required when `isOAuth` is `false`. + privateKey: + type: string + description: The RSA private key that you created for use in ServiceNow. This property is required when `isOAuth` is `true`. + privateKeyPassword: + type: string + description: The password for the RSA private key. This property is required when `isOAuth` is `true` and you set a password on your private key. + username: + type: string + description: The username for HTTP basic authentication. This property is required when `isOAuth` is `false`. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_slack.yaml new file mode 100644 index 00000000000000..4a681e8a195f3a --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_slack.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Slack connector +description: Defines secrets for connectors when type is `.slack`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_swimlane.yaml new file mode 100644 index 00000000000000..e9cf5679b0c453 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_swimlane.yaml @@ -0,0 +1,7 @@ +title: Connector secrets properties for a Swimlane connector +description: Defines secrets for connectors when type is `.swimlane`. +type: object +properties: + apiToken: + description: Swimlane API authentication token. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_teams.yaml new file mode 100644 index 00000000000000..f5e3aa51c75282 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_teams.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Microsoft Teams connector +description: Defines secrets for connectors when type is `.teams`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml new file mode 100644 index 00000000000000..2373f14beae508 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Tines connector +description: Defines secrets for connectors when type is `.tines`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_webhook.yaml new file mode 100644 index 00000000000000..5a465932fb8988 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_webhook.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for a Webhook connector +description: Defines secrets for connectors when type is `.webhook`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_xmatters.yaml new file mode 100644 index 00000000000000..67071884663dd2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_xmatters.yaml @@ -0,0 +1,5 @@ +title: Connector secrets properties for an xMatters connector +description: Defines secrets for connectors when type is `.xmatters`. +type: object +additionalProperties: true +# TO-DO: Add the properties for this connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml new file mode 100644 index 00000000000000..66250b31a94eb6 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml @@ -0,0 +1,14 @@ +title: Update Webhook - Case Managment connector request +type: object +required: + - config + - name +properties: + config: + $ref: 'config_properties_cases_webhook.yaml' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_cases_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_email.yaml new file mode 100644 index 00000000000000..b52ba071bef537 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_email.yaml @@ -0,0 +1,13 @@ +title: Update email connector request +type: object +required: + - config + - name +properties: + config: + $ref: 'config_properties_email.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_email.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_index.yaml new file mode 100644 index 00000000000000..3fe293832a39de --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_index.yaml @@ -0,0 +1,11 @@ +title: Update index connector request +type: object +required: + - config + - name +properties: + config: + $ref: 'config_properties_index.yaml' + name: + type: string + description: The display name for the connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_jira.yaml new file mode 100644 index 00000000000000..009442e87182f1 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_jira.yaml @@ -0,0 +1,14 @@ +title: Update Jira connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_jira.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_jira.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_opsgenie.yaml new file mode 100644 index 00000000000000..ee3c5112427151 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_opsgenie.yaml @@ -0,0 +1,14 @@ +title: Update Opsgenie connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_opsgenie.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_opsgenie.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_pagerduty.yaml new file mode 100644 index 00000000000000..8906c84d3d6049 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_pagerduty.yaml @@ -0,0 +1,14 @@ +title: Update PagerDuty connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_pagerduty.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_pagerduty.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_resilient.yaml new file mode 100644 index 00000000000000..4e3957af5fa784 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_resilient.yaml @@ -0,0 +1,14 @@ +title: Update IBM Resilient connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_resilient.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_resilient.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_serverlog.yaml new file mode 100644 index 00000000000000..eec0e738ca726e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_serverlog.yaml @@ -0,0 +1,8 @@ +title: Update server log connector request +type: object +required: + - name +properties: + name: + type: string + description: The display name for the connector. \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow.yaml new file mode 100644 index 00000000000000..a2fd56c21558e7 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow.yaml @@ -0,0 +1,14 @@ +title: Update ServiceNow ITSM connector or ServiceNow SecOps request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow_itom.yaml new file mode 100644 index 00000000000000..81b3220bbbeb37 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_servicenow_itom.yaml @@ -0,0 +1,14 @@ +title: Create ServiceNow ITOM connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_servicenow_itom.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_slack.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_slack.yaml new file mode 100644 index 00000000000000..6e1bf95b3944a2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_slack.yaml @@ -0,0 +1,11 @@ +title: Update Slack connector request +type: object +required: + - name + - secrets +properties: + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_slack.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml new file mode 100644 index 00000000000000..81321351b74ec2 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml @@ -0,0 +1,15 @@ +title: Update Swimlane connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_swimlane.yaml' + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_teams.yaml new file mode 100644 index 00000000000000..37a1741474ea54 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_teams.yaml @@ -0,0 +1,11 @@ +title: Update Microsoft Teams connector request +type: object +required: + - name + - secrets +properties: + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_teams.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_tines.yaml new file mode 100644 index 00000000000000..8572f474d8bd6d --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_tines.yaml @@ -0,0 +1,14 @@ +title: Update Tines connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_tines.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_tines.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_webhook.yaml new file mode 100644 index 00000000000000..6023a6795ae803 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_webhook.yaml @@ -0,0 +1,14 @@ +title: Update Webhook connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_webhook.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_xmatters.yaml new file mode 100644 index 00000000000000..de3e962bc7543e --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_xmatters.yaml @@ -0,0 +1,14 @@ +title: Update xMatters connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_xmatters.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_xmatters.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/entrypoint.yaml b/x-pack/plugins/actions/docs/openapi/entrypoint.yaml index c85da6d4d51ae3..98a50c7304d587 100644 --- a/x-pack/plugins/actions/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/actions/docs/openapi/entrypoint.yaml @@ -15,8 +15,8 @@ servers: - url: 'http://localhost:5601' description: local paths: -# '/s/{spaceId}/api/actions/connector': -# $ref: 'paths/s@{spaceid}@api@actions@connector.yaml' + '/s/{spaceId}/api/actions/connector': + $ref: 'paths/s@{spaceid}@api@actions@connector.yaml' '/s/{spaceId}/api/actions/connector/{connectorId}': $ref: 'paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml' '/s/{spaceId}/api/actions/connectors': diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml new file mode 100644 index 00000000000000..110f35c650e91f --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml @@ -0,0 +1,69 @@ +post: + summary: Creates a connector. + operationId: createConnector + description: > + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml + - $ref: '../components/parameters/space_id.yaml' + requestBody: + required: true + content: + application/json: + schema: + title: Create connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '../components/schemas/create_connector_request_cases_webhook.yaml' + - $ref: '../components/schemas/create_connector_request_email.yaml' + - $ref: '../components/schemas/create_connector_request_index.yaml' + - $ref: '../components/schemas/create_connector_request_jira.yaml' + - $ref: '../components/schemas/create_connector_request_opsgenie.yaml' + - $ref: '../components/schemas/create_connector_request_pagerduty.yaml' + - $ref: '../components/schemas/create_connector_request_resilient.yaml' + - $ref: '../components/schemas/create_connector_request_serverlog.yaml' + - $ref: '../components/schemas/create_connector_request_servicenow.yaml' + - $ref: '../components/schemas/create_connector_request_servicenow_itom.yaml' + - $ref: '../components/schemas/create_connector_request_servicenow_sir.yaml' + - $ref: '../components/schemas/create_connector_request_slack.yaml' + - $ref: '../components/schemas/create_connector_request_swimlane.yaml' + - $ref: '../components/schemas/create_connector_request_teams.yaml' + - $ref: '../components/schemas/create_connector_request_tines.yaml' + - $ref: '../components/schemas/create_connector_request_webhook.yaml' + - $ref: '../components/schemas/create_connector_request_xmatters.yaml' + discriminator: + propertyName: connector_type_id + examples: + createIndexConnectorRequest: + $ref: '../components/examples/create_index_connector_request.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '../components/schemas/connector_response_properties.yaml' + examples: + createIndexConnectorResponse: + $ref: '../components/examples/create_index_connector_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + servers: + - url: https://localhost:5601 +servers: + - url: https://localhost:5601 diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml index 53df4bcdf78ce3..c1cb7df5aa0f1b 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml @@ -11,41 +11,44 @@ get: responses: '200': description: Indicates a successful call. + content: + application/json: + schema: + $ref: '../components/schemas/connector_response_properties.yaml' + examples: + getConnectorResponse: + $ref: '../components/examples/get_connector_response.yaml' + '401': + description: Authorization information is missing or invalid. content: application/json: schema: type: object - required: - - connector_type_id - - id - - is_deprecated - - is_preconfigured - - name properties: - config: - type: object - description: The configuration for the connector. Configuration properties vary depending on the connector type. - additionalProperties: true - nullable: true - connector_type_id: - $ref: '../components/schemas/connector_types.yaml' - id: + error: type: string - description: The identifier for the connector. - example: b0766e10-d190-11ec-b04c-776c77d14fca - is_deprecated: - $ref: '../components/schemas/is_deprecated.yaml' - is_missing_secrets: - $ref: '../components/schemas/is_missing_secrets.yaml' - is_preconfigured: - $ref: '../components/schemas/is_preconfigured.yaml' - name: + example: Unauthorized + message: type: string - description: The display name for the connector. - example: my-connector - examples: - getConnectorResponse: - $ref: '../components/examples/get_connector_response.yaml' + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 @@ -64,6 +67,132 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 + servers: + - url: https://localhost:5601 + +put: + summary: Updates the attributes for a connector. + operationId: updateConnector + description: > + You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. + tags: + - connectors + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml + - $ref: '../components/parameters/connector_id.yaml' + - $ref: '../components/parameters/space_id.yaml' + requestBody: + required: true + content: + application/json: + schema: + title: Update connector request body properties + description: The properties vary depending on the connector type. + oneOf: + - $ref: '../components/schemas/update_connector_request_cases_webhook.yaml' +# - $ref: '../components/schemas/update_connector_request_email.yaml' + - $ref: '../components/schemas/update_connector_request_index.yaml' + - $ref: '../components/schemas/update_connector_request_jira.yaml' + - $ref: '../components/schemas/update_connector_request_opsgenie.yaml' +# - $ref: '../components/schemas/update_connector_request_pagerduty.yaml' + - $ref: '../components/schemas/update_connector_request_resilient.yaml' + - $ref: '../components/schemas/update_connector_request_serverlog.yaml' + - $ref: '../components/schemas/update_connector_request_servicenow.yaml' + - $ref: '../components/schemas/update_connector_request_servicenow_itom.yaml' +# - $ref: '../components/schemas/update_connector_request_slack.yaml' + - $ref: '../components/schemas/update_connector_request_swimlane.yaml' +# - $ref: '../components/schemas/update_connector_request_teams.yaml' +# - $ref: '../components/schemas/update_connector_request_tines.yaml' +# - $ref: '../components/schemas/update_connector_request_webhook.yaml' +# - $ref: '../components/schemas/update_connector_request_xmatters.yaml' + examples: + updateIndexConnectorRequest: + $ref: '../components/examples/update_index_connector_request.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '../components/schemas/connector_response_properties.yaml' + '400': + description: Indicates a bad request. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Bad Request + message: + type: string + example: "error validating action type config: [index]: expected value of type [string] but got [undefined]" + statusCode: + type: integer + example: 400 + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + '404': + description: Object is not found. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Not Found + message: + type: string + example: "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml index 5dcd403aea99c0..001da54c13c14a 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml @@ -18,6 +18,8 @@ get: content: application/json: schema: + title: Get connector types response body properties + description: The properties vary for each connector type. type: array items: type: object @@ -56,6 +58,21 @@ get: examples: getConnectorTypesResponse: $ref: '../components/examples/get_connector_types_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml index 36bd852c12f6f4..2a0a075703f8a8 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connectors.yaml @@ -15,6 +15,8 @@ get: schema: type: array items: + title: Get connectors response body properties + description: The properties vary for each connector type. type: object required: - connector_type_id @@ -53,6 +55,21 @@ get: examples: getConnectorsResponse: $ref: '../components/examples/get_connectors_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts b/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts index 20896e2691f102..223c8c28b55bc6 100644 --- a/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts +++ b/x-pack/plugins/actions/server/lib/request_oauth_client_credentials_token.test.ts @@ -74,6 +74,7 @@ describe('requestOAuthClientCredentialsToken', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts b/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts index 318775762bbbd5..af65bcf67d3dbb 100644 --- a/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts +++ b/x-pack/plugins/actions/server/lib/request_oauth_jwt_token.test.ts @@ -75,6 +75,7 @@ describe('requestOAuthJWTToken', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts b/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts index cc9ea6a74517ac..9843783aadf8de 100644 --- a/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts +++ b/x-pack/plugins/actions/server/lib/request_oauth_token.test.ts @@ -82,6 +82,7 @@ describe('requestOAuthToken', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/alerting/common/index.ts b/x-pack/plugins/alerting/common/index.ts index 795a05dcb802c2..9a977213d44465 100644 --- a/x-pack/plugins/alerting/common/index.ts +++ b/x-pack/plugins/alerting/common/index.ts @@ -11,6 +11,7 @@ import { AlertsHealth } from './rule'; export * from './rule'; +export * from './rules_settings'; export * from './rule_type'; export * from './rule_task_instance'; export * from './rule_navigation'; diff --git a/x-pack/plugins/alerting/common/rules_settings.ts b/x-pack/plugins/alerting/common/rules_settings.ts new file mode 100644 index 00000000000000..755becc8a9822d --- /dev/null +++ b/x-pack/plugins/alerting/common/rules_settings.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export interface RulesSettingsModificationMetadata { + createdBy: string | null; + updatedBy: string | null; + createdAt: string; + updatedAt: string; +} + +export interface RulesSettingsFlappingProperties { + enabled: boolean; + lookBackWindow: number; + statusChangeThreshold: number; +} + +export type RulesSettingsFlapping = RulesSettingsFlappingProperties & + RulesSettingsModificationMetadata; + +export interface RulesSettings { + flapping: RulesSettingsFlapping; +} + +export const MIN_LOOK_BACK_WINDOW = 2; +export const MAX_LOOK_BACK_WINDOW = 20; +export const MIN_STATUS_CHANGE_THRESHOLD = 2; +export const MAX_STATUS_CHANGE_THRESHOLD = 20; + +export const RULES_SETTINGS_FEATURE_ID = 'rulesSettings'; +export const ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID = 'allFlappingSettings'; +export const READ_FLAPPING_SETTINGS_SUB_FEATURE_ID = 'readFlappingSettings'; + +export const API_PRIVILEGES = { + READ_FLAPPING_SETTINGS: 'read-flapping-settings', + WRITE_FLAPPING_SETTINGS: 'write-flapping-settings', +}; + +export const RULES_SETTINGS_SAVED_OBJECT_TYPE = 'rules-settings'; +export const RULES_SETTINGS_SAVED_OBJECT_ID = 'rules-settings'; + +export const DEFAULT_LOOK_BACK_WINDOW = 20; +export const DEFAULT_STATUS_CHANGE_THRESHOLD = 4; + +export const DEFAULT_FLAPPING_SETTINGS = { + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 4, +}; diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.json b/x-pack/plugins/alerting/docs/openapi/bundled.json index 8adf80f41a8361..53b0ad2e75a732 100644 --- a/x-pack/plugins/alerting/docs/openapi/bundled.json +++ b/x-pack/plugins/alerting/docs/openapi/bundled.json @@ -27,7 +27,7 @@ "paths": { "/s/{spaceId}/api/alerting/rule/{ruleId}": { "get": { - "summary": "Retrieve a rule by its identifier.", + "summary": "Retrieves a rule by its identifier.", "operationId": "getRule", "description": "You must have `read` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rules you're seeking. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. To get rules associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role.\n", "tags": [ @@ -50,14 +50,39 @@ "$ref": "#/components/schemas/rule_response_properties" }, "examples": { - "updateRuleResponse": { + "getRuleResponse": { "$ref": "#/components/examples/get_rule_response" } } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } - } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] }, "delete": { "summary": "Deletes a rule.", @@ -80,6 +105,26 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } }, "servers": [ @@ -136,6 +181,26 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } }, "servers": [ @@ -152,7 +217,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_disable": { "post": { - "summary": "Disable a rule.", + "summary": "Disables a rule.", "operationId": "disableRule", "description": "You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features.\n", "tags": [ @@ -172,6 +237,26 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/404_response" + } + } + } } }, "servers": [ @@ -188,7 +273,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_enable": { "post": { - "summary": "Enable a rule.", + "summary": "Enables a rule.", "operationId": "enableRule", "description": "This API supports token-based authentication only. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features.\n", "tags": [ @@ -208,6 +293,26 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + }, + "404": { + "description": "Object is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -380,6 +485,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -394,9 +509,471 @@ } ] }, + "/s/{spaceId}/api/alerting/_health": { + "get": { + "summary": "Retrieves the health status of the alerting framework.", + "operationId": "getAlertingHealth", + "description": "You must have `read` privileges for the **Management > Stack Rules** feature or for at least one of the **Analytics > Discover**, **Analytics > Machine Learning**, **Observability**, or **Security** features.\n", + "tags": [ + "alerting" + ], + "parameters": [ + { + "$ref": "#/components/parameters/space_id" + } + ], + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "alerting_framework_heath": { + "type": "object", + "description": "This property has a typo. Use `alerting_framework_health` instead.", + "deprecated": true, + "properties": { + "_deprecated": { + "type": "string", + "example": "This state property has a typo, use \"alerting_framework_health\" instead." + }, + "decryption_health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "execution_health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "read_health": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + } + } + }, + "alerting_framework_health": { + "type": "object", + "description": "Three substates identify the health of the alerting framework: `decryption_health`, `execution_health`, and `read_health`.\n", + "properties": { + "decryption_health": { + "type": "object", + "description": "The timestamp and status of the rule decryption.", + "properties": { + "status": { + "type": "string", + "example": "ok", + "enum": [ + "error", + "ok", + "warn" + ] + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "execution_health": { + "type": "object", + "description": "The timestamp and status of the rule run.", + "properties": { + "status": { + "type": "string", + "example": "ok", + "enum": [ + "error", + "ok", + "warn" + ] + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + }, + "read_health": { + "type": "object", + "description": "The timestamp and status of the rule reading events.", + "properties": { + "status": { + "type": "string", + "example": "ok", + "enum": [ + "error", + "ok", + "warn" + ] + }, + "timestamp": { + "type": "string", + "format": "date-time", + "example": "2023-01-13T01:28:00.280Z" + } + } + } + } + }, + "has_permanent_encryption_key": { + "type": "boolean", + "description": "If `false`, the encrypted saved object plugin does not have a permanent encryption key.", + "example": true + }, + "is_sufficiently_secure": { + "type": "boolean", + "description": "If `false`, security is enabled but TLS is not.", + "example": true + } + } + }, + "examples": { + "getAlertingHealthResponse": { + "$ref": "#/components/examples/get_health_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, + "/s/{spaceId}/api/alerting/rule_types": { + "get": { + "summary": "Retrieves a list of rule types.", + "operationId": "getRuleTypes", + "description": "If you have `read` privileges for one or more Kibana features, the API response contains information about the appropriate rule types. For example, there are rule types associated with the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, and **Security** features. To get rule types associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role.\n", + "tags": [ + "alerting" + ], + "parameters": [ + { + "$ref": "#/components/parameters/space_id" + } + ], + "responses": { + "200": { + "description": "Indicates a successful call.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "action_groups": { + "description": "An explicit list of groups for which the rule type can schedule actions, each with the action group's unique ID and human readable name. Rule actions validation uses this configuration to ensure that groups are valid.\n", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + }, + "action_variables": { + "description": "A list of action variables that the rule type makes available via context and state in action parameter templates, and a short human readable description. When you create a rule in Kibana, it uses this information to prompt you for these variables in action parameter editors.\n", + "type": "object", + "properties": { + "context": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "useWithTripleBracesInTemplates": { + "type": "boolean" + } + } + } + }, + "params": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + }, + "state": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + } + } + }, + "authorized_consumers": { + "description": "The list of the plugins IDs that have access to the rule type.", + "type": "object", + "properties": { + "alerts": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "apm": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "discover": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "infrastructure": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "logs": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "ml": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "monitoring": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "siem": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "stackAlerts": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + }, + "uptime": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "read": { + "type": "boolean" + } + } + } + } + }, + "default_action_group_id": { + "description": "The default identifier for the rule type group.", + "type": "string" + }, + "does_set_recovery_context": { + "description": "Indicates whether the rule passes context variables to its recovery action.", + "type": "boolean" + }, + "enabled_in_license": { + "description": "Indicates whether the rule type is enabled or disabled based on the subscription.", + "type": "boolean" + }, + "id": { + "description": "The unique identifier for the rule type.", + "type": "string" + }, + "is_exportable": { + "description": "Indicates whether the rule type is exportable in **Stack Management > Saved Objects**.", + "type": "boolean" + }, + "minimum_license_required": { + "description": "The subscriptions required to use the rule type.", + "type": "string", + "example": "basic" + }, + "name": { + "description": "The descriptive name of the rule type.", + "type": "string" + }, + "producer": { + "description": "An identifier for the application that produces this rule type.", + "type": "string", + "example": "stackAlerts" + }, + "recovery_action_group": { + "description": "An action group to use when an alert goes from an active state to an inactive one.", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "rule_task_timeout": { + "type": "string", + "example": "5m" + } + } + } + }, + "examples": { + "getRuleTypesResponse": { + "$ref": "#/components/examples/get_rule_types_response" + } + } + } + } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } + } + } + }, + "servers": [ + { + "url": "https://localhost:5601" + } + ] + }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all": { "post": { - "summary": "Mute all alerts.", + "summary": "Mutes all alerts.", "operationId": "muteAllAlerts", "description": "This API snoozes the notifications for the rule indefinitely. The rule checks continue to occur but alerts will not trigger any actions. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature.\n", "tags": [ @@ -416,6 +993,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -432,7 +1019,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all": { "post": { - "summary": "Unmute all alerts.", + "summary": "Unmutes all alerts.", "operationId": "unmuteAllAlerts", "description": "If the rule has its notifications snoozed indefinitely, this API cancels the snooze. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature.\n", "tags": [ @@ -452,6 +1039,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -468,7 +1065,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute": { "post": { - "summary": "Mute an alert.", + "summary": "Mutes an alert.", "operationId": "muteAlert", "description": "You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. \n", "tags": [ @@ -491,6 +1088,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -507,7 +1114,7 @@ }, "/s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute": { "post": { - "summary": "Unmute an alert.", + "summary": "Unmutes an alert.", "operationId": "unmuteAlert", "description": "You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. \n", "tags": [ @@ -530,6 +1137,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/401_response" + } + } + } } }, "servers": [ @@ -838,6 +1455,52 @@ } } }, + "401_response": { + "type": "object", + "title": "Unsuccessful rule API response", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized", + "enum": [ + "Unauthorized" + ] + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401, + "enum": [ + 401 + ] + } + } + }, + "404_response": { + "type": "object", + "properties": { + "error": { + "type": "string", + "example": "Not Found", + "enum": [ + "Not Found" + ] + }, + "message": { + "type": "string", + "example": "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" + }, + "statusCode": { + "type": "integer", + "example": 404, + "enum": [ + 404 + ] + } + } + }, "update_rule_request": { "title": "Update rule request", "description": "The update rule API request body varies depending on the type of rule and actions.", @@ -1115,6 +1778,174 @@ } ] } + }, + "get_health_response": { + "summary": "Retrieve information about the health of the alerting framework.", + "value": { + "is_sufficiently_secure": true, + "has_permanent_encryption_key": true, + "alerting_framework_health": { + "decryption_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "execution_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "read_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + } + }, + "alerting_framework_heath": { + "_deprecated": "This state property has a typo, use \"alerting_framework_health\" instead.", + "decryption_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "execution_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + }, + "read_health": { + "status": "ok", + "timestamp": "2023-01-13T01:28:00.280Z" + } + } + } + }, + "get_rule_types_response": { + "summary": "Retrieve rule types associated with Kibana machine learning features", + "value": [ + { + "id": "xpack.ml.anomaly_detection_alert", + "action_groups": [ + { + "id": "anomaly_score_match", + "name": "Anomaly score matched the condition" + }, + { + "id": "recovered", + "name": "Recovered" + } + ], + "action_variables": { + "context": [ + { + "name": "timestamp", + "description": "The bucket timestamp of the anomaly" + }, + { + "name": "timestampIso8601", + "description": "The bucket time of the anomaly in ISO8601 format" + }, + { + "name": "jobIds", + "description": "List of job IDs that triggered the alert" + }, + { + "name": "message", + "description": "Alert info message" + }, + { + "name": "isInterim", + "description": "Indicate if top hits contain interim results" + }, + { + "name": "score", + "description": "Anomaly score at the time of the notification action" + }, + { + "name": "topRecords", + "description": "Top records" + }, + { + "name": "topInfluencers", + "description": "Top influencers" + }, + { + "name": "anomalyExplorerUrl", + "description": "URL to open in the Anomaly Explorer", + "useWithTripleBracesInTemplates": true + } + ], + "params": [], + "state": [] + }, + "authorized_consumers": { + "alerts": { + "all": true, + "read": true + }, + "ml": { + "all": true, + "read": true + } + }, + "default_action_group_id": "anomaly_score_match", + "does_set_recovery_context": true, + "enabled_in_license": true, + "is_exportable": true, + "minimum_license_required": "platinum", + "name": "Anomaly detection alert", + "producer": "ml", + "recovery_action_group": { + "id": "recovered", + "name": "Recovered" + }, + "rule_task_timeout": "5m" + }, + { + "id": "xpack.ml.anomaly_detection_jobs_health", + "action_groups": [ + { + "id": "anomaly_detection_realtime_issue", + "name": "Issue detected" + }, + { + "id": "recovered", + "name": "Recovered" + } + ], + "action_variables": { + "context": [ + { + "name": "results", + "description": "Results of the rule execution" + }, + { + "name": "message", + "description": "Alert info message" + } + ], + "params": [], + "state": [] + }, + "authorized_consumers": { + "alerts": { + "all": true, + "read": true + }, + "ml": { + "all": true, + "read": true + } + }, + "default_action_group_id": "anomaly_detection_realtime_issue", + "does_set_recovery_context": true, + "enabled_in_license": true, + "is_exportable": true, + "minimum_license_required": "platinum", + "name": "Anomaly detection jobs health", + "producer": "ml", + "recovery_action_group": { + "id": "recovered", + "name": "Recovered" + }, + "rule_task_timeout": "5m" + } + ] } } }, diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.yaml b/x-pack/plugins/alerting/docs/openapi/bundled.yaml index 029c6293557ce3..95c0f0c266f1f7 100644 --- a/x-pack/plugins/alerting/docs/openapi/bundled.yaml +++ b/x-pack/plugins/alerting/docs/openapi/bundled.yaml @@ -17,7 +17,7 @@ servers: paths: /s/{spaceId}/api/alerting/rule/{ruleId}: get: - summary: Retrieve a rule by its identifier. + summary: Retrieves a rule by its identifier. operationId: getRule description: | You must have `read` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rules you're seeking. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, or **Security** features. To get rules associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role. @@ -34,8 +34,22 @@ paths: schema: $ref: '#/components/schemas/rule_response_properties' examples: - updateRuleResponse: + getRuleResponse: $ref: '#/components/examples/get_rule_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' + servers: + - url: https://localhost:5601 delete: summary: Deletes a rule. operationId: deleteRule @@ -50,6 +64,18 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' servers: - url: https://localhost:5601 put: @@ -82,13 +108,25 @@ paths: examples: updateRuleResponse: $ref: '#/components/examples/update_rule_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_disable: post: - summary: Disable a rule. + summary: Disables a rule. operationId: disableRule description: | You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. @@ -101,13 +139,25 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_enable: post: - summary: Enable a rule. + summary: Enables a rule. operationId: enableRule description: | This API supports token-based authentication only. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. @@ -120,6 +170,18 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: @@ -229,13 +291,331 @@ paths: examples: findRulesResponse: $ref: '#/components/examples/find_rules_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 + /s/{spaceId}/api/alerting/_health: + get: + summary: Retrieves the health status of the alerting framework. + operationId: getAlertingHealth + description: | + You must have `read` privileges for the **Management > Stack Rules** feature or for at least one of the **Analytics > Discover**, **Analytics > Machine Learning**, **Observability**, or **Security** features. + tags: + - alerting + parameters: + - $ref: '#/components/parameters/space_id' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: object + properties: + alerting_framework_heath: + type: object + description: This property has a typo. Use `alerting_framework_health` instead. + deprecated: true + properties: + _deprecated: + type: string + example: This state property has a typo, use "alerting_framework_health" instead. + decryption_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + execution_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + read_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + alerting_framework_health: + type: object + description: | + Three substates identify the health of the alerting framework: `decryption_health`, `execution_health`, and `read_health`. + properties: + decryption_health: + type: object + description: The timestamp and status of the rule decryption. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + execution_health: + type: object + description: The timestamp and status of the rule run. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + read_health: + type: object + description: The timestamp and status of the rule reading events. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: '2023-01-13T01:28:00.280Z' + has_permanent_encryption_key: + type: boolean + description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. + example: true + is_sufficiently_secure: + type: boolean + description: If `false`, security is enabled but TLS is not. + example: true + examples: + getAlertingHealthResponse: + $ref: '#/components/examples/get_health_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + servers: + - url: https://localhost:5601 + /s/{spaceId}/api/alerting/rule_types: + get: + summary: Retrieves a list of rule types. + operationId: getRuleTypes + description: | + If you have `read` privileges for one or more Kibana features, the API response contains information about the appropriate rule types. For example, there are rule types associated with the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability** features, and **Security** features. To get rule types associated with the **Stack Monitoring** feature, use the `monitoring_user` built-in role. + tags: + - alerting + parameters: + - $ref: '#/components/parameters/space_id' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: array + items: + type: object + properties: + action_groups: + description: | + An explicit list of groups for which the rule type can schedule actions, each with the action group's unique ID and human readable name. Rule actions validation uses this configuration to ensure that groups are valid. + type: array + items: + type: object + properties: + id: + type: string + name: + type: string + action_variables: + description: | + A list of action variables that the rule type makes available via context and state in action parameter templates, and a short human readable description. When you create a rule in Kibana, it uses this information to prompt you for these variables in action parameter editors. + type: object + properties: + context: + type: array + items: + type: object + properties: + name: + type: string + description: + type: string + useWithTripleBracesInTemplates: + type: boolean + params: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + state: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + authorized_consumers: + description: The list of the plugins IDs that have access to the rule type. + type: object + properties: + alerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + apm: + type: object + properties: + all: + type: boolean + read: + type: boolean + discover: + type: object + properties: + all: + type: boolean + read: + type: boolean + infrastructure: + type: object + properties: + all: + type: boolean + read: + type: boolean + logs: + type: object + properties: + all: + type: boolean + read: + type: boolean + ml: + type: object + properties: + all: + type: boolean + read: + type: boolean + monitoring: + type: object + properties: + all: + type: boolean + read: + type: boolean + siem: + type: object + properties: + all: + type: boolean + read: + type: boolean + stackAlerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + uptime: + type: object + properties: + all: + type: boolean + read: + type: boolean + default_action_group_id: + description: The default identifier for the rule type group. + type: string + does_set_recovery_context: + description: Indicates whether the rule passes context variables to its recovery action. + type: boolean + enabled_in_license: + description: Indicates whether the rule type is enabled or disabled based on the subscription. + type: boolean + id: + description: The unique identifier for the rule type. + type: string + is_exportable: + description: Indicates whether the rule type is exportable in **Stack Management > Saved Objects**. + type: boolean + minimum_license_required: + description: The subscriptions required to use the rule type. + type: string + example: basic + name: + description: The descriptive name of the rule type. + type: string + producer: + description: An identifier for the application that produces this rule type. + type: string + example: stackAlerts + recovery_action_group: + description: An action group to use when an alert goes from an active state to an inactive one. + type: object + properties: + id: + type: string + name: + type: string + rule_task_timeout: + type: string + example: 5m + examples: + getRuleTypesResponse: + $ref: '#/components/examples/get_rule_types_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + servers: + - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all: post: - summary: Mute all alerts. + summary: Mutes all alerts. operationId: muteAllAlerts description: | This API snoozes the notifications for the rule indefinitely. The rule checks continue to occur but alerts will not trigger any actions. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -248,13 +628,19 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all: post: - summary: Unmute all alerts. + summary: Unmutes all alerts. operationId: unmuteAllAlerts description: | If the rule has its notifications snoozed indefinitely, this API cancels the snooze. You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -267,13 +653,19 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_mute: post: - summary: Mute an alert. + summary: Mutes an alert. operationId: muteAlert description: | You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -287,13 +679,19 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: - url: https://localhost:5601 /s/{spaceId}/api/alerting/rule/{ruleId}/alert/{alertId}/_unmute: post: - summary: Unmute an alert. + summary: Unmutes an alert. operationId: unmuteAlert description: | You must have `all` privileges for the appropriate Kibana features, depending on the `consumer` and `rule_type_id` of the rule. For example, the **Management > Stack Rules** feature, **Analytics > Discover** and **Machine Learning** features, **Observability**, and **Security** features. If the rule has actions, you must also have `read` privileges for the **Management > Actions and Connectors** feature. @@ -307,6 +705,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' servers: - url: https://localhost:5601 servers: @@ -539,6 +943,38 @@ components: description: The identifier for the user that updated this rule most recently. nullable: true example: elastic + 401_response: + type: object + title: Unsuccessful rule API response + properties: + error: + type: string + example: Unauthorized + enum: + - Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + enum: + - 401 + 404_response: + type: object + properties: + error: + type: string + example: Not Found + enum: + - Not Found + message: + type: string + example: Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found + statusCode: + type: integer + example: 404 + enum: + - 404 update_rule_request: title: Update rule request description: The update rule API request body varies depending on the type of rule and actions. @@ -770,6 +1206,114 @@ components: warning: null outcome: succeeded next_run: '2022-12-06T01:45:23.912Z' + get_health_response: + summary: Retrieve information about the health of the alerting framework. + value: + is_sufficiently_secure: true + has_permanent_encryption_key: true + alerting_framework_health: + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + alerting_framework_heath: + _deprecated: This state property has a typo, use "alerting_framework_health" instead. + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + get_rule_types_response: + summary: Retrieve rule types associated with Kibana machine learning features + value: + - id: xpack.ml.anomaly_detection_alert + action_groups: + - id: anomaly_score_match + name: Anomaly score matched the condition + - id: recovered + name: Recovered + action_variables: + context: + - name: timestamp + description: The bucket timestamp of the anomaly + - name: timestampIso8601 + description: The bucket time of the anomaly in ISO8601 format + - name: jobIds + description: List of job IDs that triggered the alert + - name: message + description: Alert info message + - name: isInterim + description: Indicate if top hits contain interim results + - name: score + description: Anomaly score at the time of the notification action + - name: topRecords + description: Top records + - name: topInfluencers + description: Top influencers + - name: anomalyExplorerUrl + description: URL to open in the Anomaly Explorer + useWithTripleBracesInTemplates: true + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_score_match + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection alert + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m + - id: xpack.ml.anomaly_detection_jobs_health + action_groups: + - id: anomaly_detection_realtime_issue + name: Issue detected + - id: recovered + name: Recovered + action_variables: + context: + - name: results + description: Results of the rule execution + - name: message + description: Alert info message + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_detection_realtime_issue + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection jobs health + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m security: - basicAuth: [] - apiKeyAuth: [] diff --git a/x-pack/plugins/alerting/docs/openapi/components/examples/get_health_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/examples/get_health_response.yaml new file mode 100644 index 00000000000000..fcd334cc677cfc --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/examples/get_health_response.yaml @@ -0,0 +1,25 @@ +summary: Retrieve information about the health of the alerting framework. +value: + is_sufficiently_secure: true + has_permanent_encryption_key: true + alerting_framework_health: + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + alerting_framework_heath: + _deprecated: "This state property has a typo, use \"alerting_framework_health\" instead." + decryption_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + execution_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' + read_health: + status: ok + timestamp: '2023-01-13T01:28:00.280Z' \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/examples/get_rule_types_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/examples/get_rule_types_response.yaml new file mode 100644 index 00000000000000..8299f7357a2173 --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/examples/get_rule_types_response.yaml @@ -0,0 +1,81 @@ +summary: Retrieve rule types associated with Kibana machine learning features +value: + - id: xpack.ml.anomaly_detection_alert + action_groups: + - id: anomaly_score_match + name: Anomaly score matched the condition + - id: recovered + name: Recovered + action_variables: + context: + - name: timestamp + description: The bucket timestamp of the anomaly + - name: timestampIso8601 + description: The bucket time of the anomaly in ISO8601 format + - name: jobIds + description: List of job IDs that triggered the alert + - name: message + description: Alert info message + - name: isInterim + description: Indicate if top hits contain interim results + - name: score + description: Anomaly score at the time of the notification action + - name: topRecords + description: Top records + - name: topInfluencers + description: Top influencers + - name: anomalyExplorerUrl + description: URL to open in the Anomaly Explorer + useWithTripleBracesInTemplates: true + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_score_match + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection alert + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m + - id: xpack.ml.anomaly_detection_jobs_health + action_groups: + - id: anomaly_detection_realtime_issue + name: Issue detected + - id: recovered + name: Recovered + action_variables: + context: + - name: results + description: Results of the rule execution + - name: message + description: Alert info message + params: [] + state: [] + authorized_consumers: + alerts: + all: true + read: true + ml: + all: true + read: true + default_action_group_id: anomaly_detection_realtime_issue + does_set_recovery_context: true + enabled_in_license: true + is_exportable: true + minimum_license_required: platinum + name: Anomaly detection jobs health + producer: ml + recovery_action_group: + id: recovered + name: Recovered + rule_task_timeout: 5m diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml new file mode 100644 index 00000000000000..c6044998f86499 --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml @@ -0,0 +1,15 @@ +type: object +title: Unsuccessful rule API response +properties: + error: + type: string + example: Unauthorized + enum: + - Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 + enum: + - 401 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml new file mode 100644 index 00000000000000..1b8a118703ecbc --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml @@ -0,0 +1,15 @@ +type: object +properties: + error: + type: string + example: Not Found + enum: + - Not Found + message: + type: string + example: "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" + statusCode: + type: integer + example: 404 + enum: + - 404 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml b/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml index b26443cfc8dcee..3b141954b30da8 100644 --- a/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml @@ -23,10 +23,10 @@ paths: $ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml' '/s/{spaceId}/api/alerting/rules/_find': $ref: 'paths/s@{spaceid}@api@alerting@rules@_find.yaml' -# '/s/{spaceId}/api/alerting/_health': -# $ref: paths/s@{spaceid}@api@alerting@_health.yaml -# '/s/{spaceId}/api/alerting/rule_types': -# $ref: 'paths/s@{spaceid}@api@alerting@rule_types.yaml' + '/s/{spaceId}/api/alerting/_health': + $ref: paths/s@{spaceid}@api@alerting@_health.yaml + '/s/{spaceId}/api/alerting/rule_types': + $ref: 'paths/s@{spaceid}@api@alerting@rule_types.yaml' '/s/{spaceId}/api/alerting/rule/{ruleId}/_mute_all': $ref: 'paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml' '/s/{spaceId}/api/alerting/rule/{ruleId}/_unmute_all': diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml new file mode 100644 index 00000000000000..6934bddfa9580f --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml @@ -0,0 +1,126 @@ +get: + summary: Retrieves the health status of the alerting framework. + operationId: getAlertingHealth + description: > + You must have `read` privileges for the **Management > Stack Rules** feature + or for at least one of the **Analytics > Discover**, + **Analytics > Machine Learning**, **Observability**, or **Security** features. + tags: + - alerting + parameters: + - $ref: '../components/parameters/space_id.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: object + properties: + alerting_framework_heath: + type: object + description: This property has a typo. Use `alerting_framework_health` instead. + deprecated: true + properties: + _deprecated: + type: string + example: "This state property has a typo, use \"alerting_framework_health\" instead." + decryption_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + execution_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + read_health: + type: object + properties: + status: + type: string + example: ok + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + alerting_framework_health: + type: object + description: > + Three substates identify the health of the alerting framework: `decryption_health`, `execution_health`, and `read_health`. + properties: + decryption_health: + type: object + description: The timestamp and status of the rule decryption. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + execution_health: + type: object + description: The timestamp and status of the rule run. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + read_health: + type: object + description: The timestamp and status of the rule reading events. + properties: + status: + type: string + example: ok + enum: + - error + - ok + - warn + timestamp: + type: string + format: date-time + example: "2023-01-13T01:28:00.280Z" + has_permanent_encryption_key: + type: boolean + description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. + example: true + is_sufficiently_secure: + type: boolean + description: If `false`, security is enabled but TLS is not. + example: true + examples: + getAlertingHealthResponse: + $ref: '../components/examples/get_health_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' +servers: + - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml index cb6a4a34525d96..91ef40aa0c2e91 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml @@ -1,5 +1,5 @@ get: - summary: Retrieve a rule by its identifier. + summary: Retrieves a rule by its identifier. operationId: getRule description: > You must have `read` privileges for the appropriate Kibana features, @@ -21,8 +21,22 @@ get: schema: $ref: '../components/schemas/rule_response_properties.yaml' examples: - updateRuleResponse: + getRuleResponse: $ref: '../components/examples/get_rule_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' + servers: + - url: https://localhost:5601 delete: summary: Deletes a rule. @@ -42,6 +56,18 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' servers: - url: https://localhost:5601 @@ -88,6 +114,18 @@ put: examples: updateRuleResponse: $ref: '../components/examples/update_rule_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml index 8c8a60ae2ce2ef..d0d5321a484206 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_disable.yaml @@ -1,5 +1,5 @@ post: - summary: Disable a rule. + summary: Disables a rule. operationId: disableRule description: > You must have `all` privileges for the appropriate Kibana features, @@ -15,6 +15,18 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/404_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml index ee4ef54fc43f63..cb7991c2d9185c 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_enable.yaml @@ -1,5 +1,5 @@ post: - summary: Enable a rule. + summary: Enables a rule. operationId: enableRule description: > This API supports token-based authentication only. @@ -16,6 +16,18 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' + '404': + description: Object is not found. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml index a816ed0b0b7ef0..00250d5a754a40 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_mute_all.yaml @@ -1,5 +1,5 @@ post: - summary: Mute all alerts. + summary: Mutes all alerts. operationId: muteAllAlerts description: > This API snoozes the notifications for the rule indefinitely. The rule @@ -19,6 +19,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml index 38e8f0807c9988..b0a887e7b427e0 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@_unmute_all.yaml @@ -1,5 +1,5 @@ post: - summary: Unmute all alerts. + summary: Unmutes all alerts. operationId: unmuteAllAlerts description: > If the rule has its notifications snoozed indefinitely, this API cancels the snooze. @@ -18,6 +18,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml index d120c06e7a6c4c..2356bf4a603944 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_mute.yaml @@ -1,5 +1,5 @@ post: - summary: Mute an alert. + summary: Mutes an alert. operationId: muteAlert description: > You must have `all` privileges for the appropriate Kibana features, @@ -18,6 +18,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml index bbc92453e236b8..c06eccb531b469 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}@alert@{alertid}@_unmute.yaml @@ -1,5 +1,5 @@ post: - summary: Unmute an alert. + summary: Unmutes an alert. operationId: unmuteAlert description: > You must have `all` privileges for the appropriate Kibana features, @@ -18,6 +18,12 @@ post: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml new file mode 100644 index 00000000000000..8b7019ee54539c --- /dev/null +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml @@ -0,0 +1,198 @@ +get: + summary: Retrieves a list of rule types. + operationId: getRuleTypes + description: > + If you have `read` privileges for one or more Kibana features, the API + response contains information about the appropriate rule types. For example, + there are rule types associated with the **Management > Stack Rules** feature, + **Analytics > Discover** and **Machine Learning** features, **Observability** + features, and **Security** features. To get rule types associated with the + **Stack Monitoring** feature, use the `monitoring_user` built-in role. + tags: + - alerting + parameters: + - $ref: '../components/parameters/space_id.yaml' + responses: + '200': + description: Indicates a successful call. + content: + application/json: + schema: + type: array + items: + type: object + properties: + action_groups: + description: > + An explicit list of groups for which the rule type can + schedule actions, each with the action group's unique ID and + human readable name. Rule actions validation uses this + configuration to ensure that groups are valid. + type: array + items: + type: object + properties: + id: + type: string + name: + type: string + action_variables: + description: > + A list of action variables that the rule type makes available + via context and state in action parameter templates, and a + short human readable description. When you create a rule in + Kibana, it uses this information to prompt you for these + variables in action parameter editors. + type: object + properties: + context: + type: array + items: + type: object + properties: + name: + type: string + description: + type: string + useWithTripleBracesInTemplates: + type: boolean + params: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + state: + type: array + items: + type: object + properties: + description: + type: string + name: + type: string + authorized_consumers: + description: The list of the plugins IDs that have access to the rule type. + type: object + properties: + alerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + apm: + type: object + properties: + all: + type: boolean + read: + type: boolean + discover: + type: object + properties: + all: + type: boolean + read: + type: boolean + infrastructure: + type: object + properties: + all: + type: boolean + read: + type: boolean + logs: + type: object + properties: + all: + type: boolean + read: + type: boolean + ml: + type: object + properties: + all: + type: boolean + read: + type: boolean + monitoring: + type: object + properties: + all: + type: boolean + read: + type: boolean + siem: + type: object + properties: + all: + type: boolean + read: + type: boolean + stackAlerts: + type: object + properties: + all: + type: boolean + read: + type: boolean + uptime: + type: object + properties: + all: + type: boolean + read: + type: boolean + default_action_group_id: + description: The default identifier for the rule type group. + type: string + does_set_recovery_context: + description: Indicates whether the rule passes context variables to its recovery action. + type: boolean + enabled_in_license: + description: Indicates whether the rule type is enabled or disabled based on the subscription. + type: boolean + id: + description: The unique identifier for the rule type. + type: string + is_exportable: + description: Indicates whether the rule type is exportable in **Stack Management > Saved Objects**. + type: boolean + minimum_license_required: + description: The subscriptions required to use the rule type. + type: string + example: basic + name: + description: The descriptive name of the rule type. + type: string + producer: + description: An identifier for the application that produces this rule type. + type: string + example: stackAlerts + recovery_action_group: + description: An action group to use when an alert goes from an active state to an inactive one. + type: object + properties: + id: + type: string + name: + type: string + rule_task_timeout: + type: string + example: 5m + examples: + getRuleTypesResponse: + $ref: '../components/examples/get_rule_types_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' +servers: + - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml index 42c4b817f79683..2f84059aa392d5 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml @@ -113,6 +113,12 @@ get: examples: findRulesResponse: $ref: '../components/examples/find_rules_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/401_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/alerting/server/alert/create_alert_factory.ts b/x-pack/plugins/alerting/server/alert/create_alert_factory.ts index c7fea46e37e4b2..ff8aacd52f5feb 100644 --- a/x-pack/plugins/alerting/server/alert/create_alert_factory.ts +++ b/x-pack/plugins/alerting/server/alert/create_alert_factory.ts @@ -129,7 +129,12 @@ export function createAlertFactory< return []; } - const { currentRecoveredAlerts } = processAlerts({ + const { currentRecoveredAlerts } = processAlerts< + State, + Context, + ActionGroupIds, + ActionGroupIds + >({ alerts, existingAlerts: originalAlerts, previouslyRecoveredAlerts: {}, diff --git a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts index 95f99a763ad7b0..9a8cd78f7fd8f0 100644 --- a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts @@ -17,7 +17,12 @@ import { AlertingEventLogger } from '../lib/alerting_event_logger/alerting_event import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; import { UntypedNormalizedRuleType } from '../rule_type_registry'; import { logAlerts } from '../task_runner/log_alerts'; -import { AlertInstanceContext, AlertInstanceState, RawAlertInstance } from '../types'; +import { + AlertInstanceContext, + AlertInstanceState, + RawAlertInstance, + WithoutReservedActionGroups, +} from '../types'; interface ConstructorOpts { logger: Logger; @@ -28,19 +33,24 @@ interface ConstructorOpts { export class LegacyAlertsClient< State extends AlertInstanceState, Context extends AlertInstanceContext, - ActionGroupIds extends string + ActionGroupIds extends string, + RecoveryActionGroupId extends string > { private activeAlertsFromPreviousExecution: Record>; private recoveredAlertsFromPreviousExecution: Record>; private alerts: Record>; private processedAlerts: { - new: Record>; - active: Record>; - recovered: Record>; - recoveredCurrent: Record>; + new: Record>; + active: Record>; + recovered: Record>; + recoveredCurrent: Record>; }; - private alertFactory?: AlertFactory; + private alertFactory?: AlertFactory< + State, + Context, + WithoutReservedActionGroups + >; constructor(private readonly options: ConstructorOpts) { this.alerts = {}; this.activeAlertsFromPreviousExecution = {}; @@ -77,7 +87,11 @@ export class LegacyAlertsClient< this.alerts = cloneDeep(this.activeAlertsFromPreviousExecution); - this.alertFactory = createAlertFactory({ + this.alertFactory = createAlertFactory< + State, + Context, + WithoutReservedActionGroups + >({ alerts: this.alerts, logger: this.options.logger, maxAlerts: this.options.maxAlerts, @@ -101,7 +115,7 @@ export class LegacyAlertsClient< activeAlerts: processedAlertsActive, currentRecoveredAlerts: processedAlertsRecoveredCurrent, recoveredAlerts: processedAlertsRecovered, - } = processAlerts({ + } = processAlerts({ alerts: this.alerts, existingAlerts: this.activeAlertsFromPreviousExecution, previouslyRecoveredAlerts: this.recoveredAlertsFromPreviousExecution, @@ -110,7 +124,10 @@ export class LegacyAlertsClient< setFlapping: true, }); - setFlapping(processedAlertsActive, processedAlertsRecovered); + setFlapping( + processedAlertsActive, + processedAlertsRecovered + ); this.processedAlerts.new = processedAlertsNew; this.processedAlerts.active = processedAlertsActive; @@ -139,7 +156,7 @@ export class LegacyAlertsClient< } public getAlertsToSerialize() { - return determineAlertsToReturn( + return determineAlertsToReturn( this.processedAlerts.active, this.processedAlerts.recovered ); diff --git a/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts b/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts index ff9b5ff0b63539..5916bf91efcc04 100644 --- a/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts +++ b/x-pack/plugins/alerting/server/lib/determine_alerts_to_return.ts @@ -12,10 +12,12 @@ import { AlertInstanceState, AlertInstanceContext, RawAlertInstance } from '../t // determines which alerts to return in the state export function determineAlertsToReturn< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >( - activeAlerts: Record> = {}, - recoveredAlerts: Record> = {} + activeAlerts: Record> = {}, + recoveredAlerts: Record> = {} ): { alertsToReturn: Record; recoveredAlertsToReturn: Record; diff --git a/x-pack/plugins/alerting/server/lib/process_alerts.ts b/x-pack/plugins/alerting/server/lib/process_alerts.ts index 83d375e9b8ac23..40c86dc461ab03 100644 --- a/x-pack/plugins/alerting/server/lib/process_alerts.ts +++ b/x-pack/plugins/alerting/server/lib/process_alerts.ts @@ -25,18 +25,22 @@ interface ProcessAlertsOpts< } interface ProcessAlertsResult< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string > { - newAlerts: Record>; - activeAlerts: Record>; + newAlerts: Record>; + activeAlerts: Record>; // recovered alerts in the current rule run that were previously active - currentRecoveredAlerts: Record>; - recoveredAlerts: Record>; + currentRecoveredAlerts: Record>; + recoveredAlerts: Record>; } export function processAlerts< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >({ alerts, existingAlerts, @@ -44,7 +48,12 @@ export function processAlerts< hasReachedAlertLimit, alertLimit, setFlapping, -}: ProcessAlertsOpts): ProcessAlertsResult { +}: ProcessAlertsOpts): ProcessAlertsResult< + State, + Context, + ActionGroupIds, + RecoveryActionGroupId +> { return hasReachedAlertLimit ? processAlertsLimitReached( alerts, @@ -58,21 +67,23 @@ export function processAlerts< function processAlertsHelper< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >( alerts: Record>, existingAlerts: Record>, previouslyRecoveredAlerts: Record>, setFlapping: boolean -): ProcessAlertsResult { +): ProcessAlertsResult { const existingAlertIds = new Set(Object.keys(existingAlerts)); const previouslyRecoveredAlertsIds = new Set(Object.keys(previouslyRecoveredAlerts)); const currentTime = new Date().toISOString(); - const newAlerts: Record> = {}; - const activeAlerts: Record> = {}; - const currentRecoveredAlerts: Record> = {}; - const recoveredAlerts: Record> = {}; + const newAlerts: Record> = {}; + const activeAlerts: Record> = {}; + const currentRecoveredAlerts: Record> = {}; + const recoveredAlerts: Record> = {}; for (const id in alerts) { if (alerts.hasOwnProperty(id)) { @@ -147,14 +158,16 @@ function processAlertsHelper< function processAlertsLimitReached< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string >( alerts: Record>, existingAlerts: Record>, previouslyRecoveredAlerts: Record>, alertLimit: number, setFlapping: boolean -): ProcessAlertsResult { +): ProcessAlertsResult { const existingAlertIds = new Set(Object.keys(existingAlerts)); const previouslyRecoveredAlertsIds = new Set(Object.keys(previouslyRecoveredAlerts)); @@ -164,10 +177,12 @@ function processAlertsLimitReached< // - add any new alerts, up to the max allowed const currentTime = new Date().toISOString(); - const newAlerts: Record> = {}; + const newAlerts: Record> = {}; // all existing alerts stay active - const activeAlerts: Record> = cloneDeep(existingAlerts); + const activeAlerts: Record> = cloneDeep( + existingAlerts + ); // update duration for existing alerts for (const id in activeAlerts) { @@ -231,8 +246,10 @@ function processAlertsLimitReached< export function updateAlertFlappingHistory< State extends AlertInstanceState, - Context extends AlertInstanceContext ->(alert: Alert, state: boolean) { + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>(alert: Alert, state: boolean) { const updatedFlappingHistory = updateFlappingHistory(alert.getFlappingHistory() || [], state); alert.setFlappingHistory(updatedFlappingHistory); } diff --git a/x-pack/plugins/alerting/server/lib/set_flapping.test.ts b/x-pack/plugins/alerting/server/lib/set_flapping.test.ts index 93b1cafaca76a6..9900d3391861bd 100644 --- a/x-pack/plugins/alerting/server/lib/set_flapping.test.ts +++ b/x-pack/plugins/alerting/server/lib/set_flapping.test.ts @@ -7,7 +7,7 @@ import { pick } from 'lodash'; import { Alert } from '../alert'; -import { AlertInstanceState, AlertInstanceContext } from '../../common'; +import { AlertInstanceState, AlertInstanceContext, DefaultActionGroupId } from '../../common'; import { setFlapping, isAlertFlapping } from './set_flapping'; describe('setFlapping', () => { @@ -85,25 +85,34 @@ describe('setFlapping', () => { describe('not currently flapping', () => { test('returns true if the flap count exceeds the threshold', () => { const flappingHistory = [true, true, true, true].concat(new Array(16).fill(false)); - const alert = new Alert('1', { - meta: { flappingHistory }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test("returns false the flap count doesn't exceed the threshold", () => { const flappingHistory = [true, true].concat(new Array(20).fill(false)); - const alert = new Alert('1', { - meta: { flappingHistory }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory }, + } + ); expect(isAlertFlapping(alert)).toEqual(false); }); test('returns true if not at capacity and the flap count exceeds the threshold', () => { const flappingHistory = new Array(5).fill(true); - const alert = new Alert('1', { - meta: { flappingHistory }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); }); @@ -111,33 +120,45 @@ describe('setFlapping', () => { describe('currently flapping', () => { test('returns true if at capacity and the flap count exceeds the threshold', () => { const flappingHistory = new Array(16).fill(false).concat([true, true, true, true]); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test("returns true if not at capacity and the flap count doesn't exceed the threshold", () => { const flappingHistory = new Array(16).fill(false); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test('returns true if not at capacity and the flap count exceeds the threshold', () => { const flappingHistory = new Array(10).fill(false).concat([true, true, true, true]); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(true); }); test("returns false if at capacity and the flap count doesn't exceed the threshold", () => { const flappingHistory = new Array(20).fill(false); - const alert = new Alert('1', { - meta: { flappingHistory, flapping: true }, - }); + const alert = new Alert( + '1', + { + meta: { flappingHistory, flapping: true }, + } + ); expect(isAlertFlapping(alert)).toEqual(false); }); }); diff --git a/x-pack/plugins/alerting/server/lib/set_flapping.ts b/x-pack/plugins/alerting/server/lib/set_flapping.ts index 81e7d0143af6cb..2e941cf06e07c7 100644 --- a/x-pack/plugins/alerting/server/lib/set_flapping.ts +++ b/x-pack/plugins/alerting/server/lib/set_flapping.ts @@ -10,9 +10,14 @@ import { Alert } from '../alert'; import { AlertInstanceState, AlertInstanceContext } from '../types'; import { isFlapping } from './flapping_utils'; -export function setFlapping( - activeAlerts: Record> = {}, - recoveredAlerts: Record> = {} +export function setFlapping< + State extends AlertInstanceState, + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupIds extends string +>( + activeAlerts: Record> = {}, + recoveredAlerts: Record> = {} ) { for (const id of keys(activeAlerts)) { const alert = activeAlerts[id]; @@ -29,8 +34,10 @@ export function setFlapping(alert: Alert): boolean { + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>(alert: Alert): boolean { const flappingHistory: boolean[] = alert.getFlappingHistory() || []; const isCurrentlyFlapping = alert.getFlapping(); return isFlapping(flappingHistory, isCurrentlyFlapping); diff --git a/x-pack/plugins/alerting/server/plugin.test.ts b/x-pack/plugins/alerting/server/plugin.test.ts index 2c057cc4cfc434..7b85bc898fee03 100644 --- a/x-pack/plugins/alerting/server/plugin.test.ts +++ b/x-pack/plugins/alerting/server/plugin.test.ts @@ -78,6 +78,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }; let plugin: AlertingPlugin; @@ -221,6 +222,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }); const startContract = plugin.start(coreMock.createStart(), { @@ -267,6 +269,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }); const startContract = plugin.start(coreMock.createStart(), { @@ -324,6 +327,7 @@ describe('Alerting Plugin', () => { statusService: statusServiceMock.createSetupContract(), monitoringCollection: monitoringCollectionMock.createSetup(), data: dataPluginMock.createSetupContract() as unknown as DataPluginSetup, + features: featuresPluginMock.createSetup(), }); const startContract = plugin.start(coreMock.createStart(), { diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 13f39504d27815..86d8a7411c16d2 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -47,13 +47,17 @@ import { IEventLogService, IEventLogClientService, } from '@kbn/event-log-plugin/server'; -import { PluginStartContract as FeaturesPluginStart } from '@kbn/features-plugin/server'; +import { + PluginStartContract as FeaturesPluginStart, + PluginSetupContract as FeaturesPluginSetup, +} from '@kbn/features-plugin/server'; import { PluginStart as DataPluginStart } from '@kbn/data-plugin/server'; import { MonitoringCollectionSetup } from '@kbn/monitoring-collection-plugin/server'; import { SharePluginStart } from '@kbn/share-plugin/server'; import { RuleTypeRegistry } from './rule_type_registry'; import { TaskRunnerFactory } from './task_runner'; import { RulesClientFactory } from './rules_client_factory'; +import { RulesSettingsClientFactory } from './rules_settings_client_factory'; import { ILicenseState, LicenseState } from './lib/license_state'; import { AlertingRequestHandlerContext, ALERTS_FEATURE_ID } from './types'; import { defineRoutes } from './routes'; @@ -82,6 +86,7 @@ import { getSecurityHealth, SecurityHealth } from './lib/get_security_health'; import { registerNodeCollector, registerClusterCollector, InMemoryMetrics } from './monitoring'; import { getRuleTaskTimeout } from './lib/get_rule_task_timeout'; import { getActionsConfigMap } from './lib/get_actions_config_map'; +import { rulesSettingsFeature } from './rules_settings_feature'; export const EVENT_LOG_PROVIDER = 'alerting'; export const EVENT_LOG_ACTIONS = { @@ -146,6 +151,7 @@ export interface AlertingPluginsSetup { statusService: StatusServiceSetup; monitoringCollection: MonitoringCollectionSetup; data: DataPluginSetup; + features: FeaturesPluginSetup; } export interface AlertingPluginsStart { @@ -172,6 +178,7 @@ export class AlertingPlugin { private security?: SecurityPluginSetup; private readonly rulesClientFactory: RulesClientFactory; private readonly alertingAuthorizationClientFactory: AlertingAuthorizationClientFactory; + private readonly rulesSettingsClientFactory: RulesSettingsClientFactory; private readonly telemetryLogger: Logger; private readonly kibanaVersion: PluginInitializerContext['env']['packageInfo']['version']; private eventLogService?: IEventLogService; @@ -186,6 +193,7 @@ export class AlertingPlugin { this.taskRunnerFactory = new TaskRunnerFactory(); this.rulesClientFactory = new RulesClientFactory(); this.alertingAuthorizationClientFactory = new AlertingAuthorizationClientFactory(); + this.rulesSettingsClientFactory = new RulesSettingsClientFactory(); this.telemetryLogger = initializerContext.logger.get('usage'); this.kibanaVersion = initializerContext.env.packageInfo.version; this.inMemoryMetrics = new InMemoryMetrics(initializerContext.logger.get('in_memory_metrics')); @@ -210,6 +218,8 @@ export class AlertingPlugin { }; }); + plugins.features.registerKibanaFeature(rulesSettingsFeature); + this.isESOCanEncrypt = plugins.encryptedSavedObjects.canEncrypt; if (!this.isESOCanEncrypt) { @@ -368,6 +378,7 @@ export class AlertingPlugin { ruleTypeRegistry, rulesClientFactory, alertingAuthorizationClientFactory, + rulesSettingsClientFactory, security, licenseState, } = this; @@ -416,6 +427,12 @@ export class AlertingPlugin { minimumScheduleInterval: this.config.rules.minimumScheduleInterval, }); + rulesSettingsClientFactory.initialize({ + logger: this.logger, + savedObjectsService: core.savedObjects, + securityPluginStart: plugins.security, + }); + const getRulesClientWithRequest = (request: KibanaRequest) => { if (isESOCanEncrypt !== true) { throw new Error( @@ -483,13 +500,16 @@ export class AlertingPlugin { private createRouteHandlerContext = ( core: CoreSetup ): IContextProvider => { - const { ruleTypeRegistry, rulesClientFactory } = this; + const { ruleTypeRegistry, rulesClientFactory, rulesSettingsClientFactory } = this; return async function alertsRouteHandlerContext(context, request) { const [{ savedObjects }] = await core.getStartServices(); return { getRulesClient: () => { return rulesClientFactory!.create(request, savedObjects); }, + getRulesSettingsClient: () => { + return rulesSettingsClientFactory.createWithAuthorization(request); + }, listTypes: ruleTypeRegistry!.list.bind(ruleTypeRegistry!), getFrameworkHealth: async () => await getHealth(savedObjects.createInternalRepository(['alert'])), diff --git a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts index b5fbaa3d0cf863..0df0f371f62b6d 100644 --- a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts +++ b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts @@ -10,17 +10,20 @@ import { identity } from 'lodash'; import type { MethodKeysOf } from '@kbn/utility-types'; import { httpServerMock } from '@kbn/core/server/mocks'; import { rulesClientMock, RulesClientMock } from '../rules_client.mock'; +import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; import { AlertsHealth, RuleType } from '../../common'; import type { AlertingRequestHandlerContext } from '../types'; export function mockHandlerArguments( { rulesClient = rulesClientMock.create(), + rulesSettingsClient = rulesSettingsClientMock.create(), listTypes: listTypesRes = [], getFrameworkHealth, areApiKeysEnabled, }: { rulesClient?: RulesClientMock; + rulesSettingsClient?: RulesSettingsClientMock; listTypes?: RuleType[]; getFrameworkHealth?: jest.MockInstance, []> & (() => Promise); @@ -41,6 +44,9 @@ export function mockHandlerArguments( getRulesClient() { return rulesClient || rulesClientMock.create(); }, + getRulesSettingsClient() { + return rulesSettingsClient || rulesSettingsClientMock.create(); + }, getFrameworkHealth, areApiKeysEnabled: areApiKeysEnabled ? areApiKeysEnabled : () => Promise.resolve(true), }, diff --git a/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts b/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts new file mode 100644 index 00000000000000..156ab604fb9050 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { httpServiceMock } from '@kbn/core/server/mocks'; +import { licenseStateMock } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; +import { getFlappingSettingsRoute } from './get_flapping_settings'; + +let rulesSettingsClient: RulesSettingsClientMock; + +jest.mock('../lib/license_api_access', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); + rulesSettingsClient = rulesSettingsClientMock.create(); +}); + +describe('getFlappingSettingsRoute', () => { + test('gets flapping settings', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + getFlappingSettingsRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config).toMatchInlineSnapshot(` + Object { + "options": Object { + "tags": Array [ + "access:read-flapping-settings", + ], + }, + "path": "/internal/alerting/rules/settings/_flapping", + "validate": false, + } + `); + + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValue({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }); + + const [context, req, res] = mockHandlerArguments({ rulesSettingsClient }, {}, ['ok']); + + await handler(context, req, res); + + expect(rulesSettingsClient.flapping().get).toHaveBeenCalledTimes(1); + expect(res.ok).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/get_flapping_settings.ts b/x-pack/plugins/alerting/server/routes/get_flapping_settings.ts new file mode 100644 index 00000000000000..6ae039032994d9 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get_flapping_settings.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IRouter } from '@kbn/core/server'; +import { ILicenseState } from '../lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; +import { verifyAccessAndContext } from './lib'; +import { API_PRIVILEGES } from '../../common'; + +export const getFlappingSettingsRoute = ( + router: IRouter, + licenseState: ILicenseState +) => { + router.get( + { + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping`, + validate: false, + options: { + tags: [`access:${API_PRIVILEGES.READ_FLAPPING_SETTINGS}`], + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(); + const flappingSettings = await rulesSettingsClient.flapping().get(); + return res.ok({ body: flappingSettings }); + }) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index c4c62a92cbedeb..32deff30edd7cf 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -42,6 +42,8 @@ import { bulkDeleteRulesRoute } from './bulk_delete_rules'; import { bulkEnableRulesRoute } from './bulk_enable_rules'; import { bulkDisableRulesRoute } from './bulk_disable_rules'; import { cloneRuleRoute } from './clone_rule'; +import { getFlappingSettingsRoute } from './get_flapping_settings'; +import { updateFlappingSettingsRoute } from './update_flapping_settings'; export interface RouteOptions { router: IRouter; @@ -87,4 +89,6 @@ export function defineRoutes(opts: RouteOptions) { unsnoozeRuleRoute(router, licenseState); runSoonRoute(router, licenseState); cloneRuleRoute(router, licenseState); + getFlappingSettingsRoute(router, licenseState); + updateFlappingSettingsRoute(router, licenseState); } diff --git a/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts b/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts new file mode 100644 index 00000000000000..28914e71e7dd3e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { httpServiceMock } from '@kbn/core/server/mocks'; +import { licenseStateMock } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; +import { updateFlappingSettingsRoute } from './update_flapping_settings'; + +let rulesSettingsClient: RulesSettingsClientMock; + +jest.mock('../lib/license_api_access', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); + rulesSettingsClient = rulesSettingsClientMock.create(); +}); + +describe('updateFlappingSettingsRoute', () => { + test('updates flapping settings', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + updateFlappingSettingsRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/internal/alerting/rules/settings/_flapping"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:write-flapping-settings", + ], + } + `); + + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValue({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }); + + const updateResult = { + enabled: false, + lookBackWindow: 6, + statusChangeThreshold: 5, + }; + + const [context, req, res] = mockHandlerArguments( + { rulesSettingsClient }, + { + body: updateResult, + }, + ['ok'] + ); + + await handler(context, req, res); + + expect(rulesSettingsClient.flapping().update).toHaveBeenCalledTimes(1); + expect((rulesSettingsClient.flapping().update as jest.Mock).mock.calls[0]) + .toMatchInlineSnapshot(` + Array [ + Object { + "enabled": false, + "lookBackWindow": 6, + "statusChangeThreshold": 5, + }, + ] + `); + expect(res.ok).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/update_flapping_settings.ts b/x-pack/plugins/alerting/server/routes/update_flapping_settings.ts new file mode 100644 index 00000000000000..ede33a7d36a95d --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update_flapping_settings.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IRouter } from '@kbn/core/server'; +import { schema } from '@kbn/config-schema'; +import { ILicenseState } from '../lib'; +import { verifyAccessAndContext } from './lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; +import { API_PRIVILEGES } from '../../common'; + +const bodySchema = schema.object({ + enabled: schema.boolean(), + lookBackWindow: schema.number(), + statusChangeThreshold: schema.number(), +}); + +export const updateFlappingSettingsRoute = ( + router: IRouter, + licenseState: ILicenseState +) => { + router.post( + { + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping`, + validate: { + body: bodySchema, + }, + options: { + tags: [`access:${API_PRIVILEGES.WRITE_FLAPPING_SETTINGS}`], + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(); + + const updatedFlappingSettings = await rulesSettingsClient.flapping().update(req.body); + + return res.ok({ + body: updatedFlappingSettings, + }); + }) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/rules_settings_client.mock.ts b/x-pack/plugins/alerting/server/rules_settings_client.mock.ts new file mode 100644 index 00000000000000..2c321e54ebf71d --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client.mock.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RulesSettingsClientApi, RulesSettingsFlappingClientApi } from './types'; + +export type RulesSettingsClientMock = jest.Mocked; +export type RulesSettingsFlappingClientMock = jest.Mocked; + +// Warning: Becareful when resetting all mocks in tests as it would clear +// the mock return value on the flapping +const createRulesSettingsClientMock = () => { + const flappingMocked: RulesSettingsFlappingClientMock = { + get: jest.fn(), + update: jest.fn(), + }; + const mocked: RulesSettingsClientMock = { + get: jest.fn(), + create: jest.fn(), + flapping: jest.fn().mockReturnValue(flappingMocked), + }; + return mocked; +}; + +export const rulesSettingsClientMock: { + create: () => RulesSettingsClientMock; +} = { + create: createRulesSettingsClientMock, +}; diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts new file mode 100644 index 00000000000000..ca69100fcfaedb --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts @@ -0,0 +1,185 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + RulesSettingsFlappingClient, + RulesSettingsFlappingClientConstructorOptions, +} from './rules_settings_flapping_client'; +import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { + RULES_SETTINGS_FEATURE_ID, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + DEFAULT_FLAPPING_SETTINGS, + RulesSettings, +} from '../../../common'; + +const mockDateString = '2019-02-12T21:01:22.479Z'; + +const savedObjectsClient = savedObjectsClientMock.create(); + +const getMockRulesSettings = (): RulesSettings => { + return { + flapping: { + enabled: DEFAULT_FLAPPING_SETTINGS.enabled, + lookBackWindow: DEFAULT_FLAPPING_SETTINGS.lookBackWindow, + statusChangeThreshold: DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + }; +}; + +const rulesSettingsFlappingClientParams: jest.Mocked = + { + logger: loggingSystemMock.create().get(), + getOrCreate: jest.fn().mockReturnValue({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: getMockRulesSettings(), + references: [], + version: '123', + }), + getModificationMetadata: jest.fn(), + savedObjectsClient, + }; + +describe('RulesSettingsFlappingClient', () => { + beforeAll(() => { + jest.useFakeTimers(); + jest.setSystemTime(new Date(mockDateString)); + }); + + afterAll(() => { + jest.clearAllMocks(); + jest.useRealTimers(); + }); + + test('can get flapping settings', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + const result = await client.get(); + + expect(result).toEqual( + expect.objectContaining({ + enabled: DEFAULT_FLAPPING_SETTINGS.enabled, + lookBackWindow: DEFAULT_FLAPPING_SETTINGS.lookBackWindow, + statusChangeThreshold: DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }) + ); + }); + + test('can update flapping settings', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + + const mockResolve = { + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: getMockRulesSettings(), + references: [], + version: '123', + }; + + savedObjectsClient.update.mockResolvedValueOnce({ + ...mockResolve, + attributes: { + flapping: { + ...mockResolve.attributes.flapping, + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + }, + }, + }); + + const result = await client.update({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + }); + + expect(savedObjectsClient.update).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + { + flapping: expect.objectContaining({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { version: '123' } + ); + + expect(result).toEqual( + expect.objectContaining({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }) + ); + }); + + test('throws if savedObjectsClient failed to update', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + savedObjectsClient.update.mockRejectedValueOnce(new Error('failed!!')); + + await expect( + client.update({ + enabled: false, + lookBackWindow: 19, + statusChangeThreshold: 3, + }) + ).rejects.toThrowError( + 'savedObjectsClient errored trying to update flapping settings: failed!!' + ); + }); + + test('throws if new flapping setting fails verification', async () => { + const client = new RulesSettingsFlappingClient(rulesSettingsFlappingClientParams); + await expect( + client.update({ + enabled: true, + lookBackWindow: 200, + statusChangeThreshold: 500, + }) + ).rejects.toThrowError('Invalid lookBackWindow value, must be between 2 and 20, but got: 200.'); + + await expect( + client.update({ + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 500, + }) + ).rejects.toThrowError( + 'Invalid statusChangeThreshold value, must be between 2 and 20, but got: 500.' + ); + + await expect( + client.update({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 20, + }) + ).rejects.toThrowError( + 'Invalid values,lookBackWindow (10) must be equal to or greater than statusChangeThreshold (20).' + ); + }); +}); diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts new file mode 100644 index 00000000000000..65db68aaba5255 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import Boom from '@hapi/boom'; +import { Logger, SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; +import { + RulesSettings, + RulesSettingsFlapping, + RulesSettingsFlappingProperties, + RulesSettingsModificationMetadata, + MIN_LOOK_BACK_WINDOW, + MAX_LOOK_BACK_WINDOW, + MIN_STATUS_CHANGE_THRESHOLD, + MAX_STATUS_CHANGE_THRESHOLD, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, +} from '../../../common'; + +const verifyFlappingSettings = (flappingSettings: RulesSettingsFlappingProperties) => { + const { lookBackWindow, statusChangeThreshold } = flappingSettings; + + if (lookBackWindow < MIN_LOOK_BACK_WINDOW || lookBackWindow > MAX_LOOK_BACK_WINDOW) { + throw Boom.badRequest( + `Invalid lookBackWindow value, must be between ${MIN_LOOK_BACK_WINDOW} and ${MAX_LOOK_BACK_WINDOW}, but got: ${lookBackWindow}.` + ); + } + + if ( + statusChangeThreshold < MIN_STATUS_CHANGE_THRESHOLD || + statusChangeThreshold > MAX_STATUS_CHANGE_THRESHOLD + ) { + throw Boom.badRequest( + `Invalid statusChangeThreshold value, must be between ${MIN_STATUS_CHANGE_THRESHOLD} and ${MAX_STATUS_CHANGE_THRESHOLD}, but got: ${statusChangeThreshold}.` + ); + } + + if (lookBackWindow < statusChangeThreshold) { + throw Boom.badRequest( + `Invalid values,lookBackWindow (${lookBackWindow}) must be equal to or greater than statusChangeThreshold (${statusChangeThreshold}).` + ); + } +}; + +export interface RulesSettingsFlappingClientConstructorOptions { + readonly logger: Logger; + readonly savedObjectsClient: SavedObjectsClientContract; + readonly getOrCreate: () => Promise>; + readonly getModificationMetadata: () => Promise; +} + +export class RulesSettingsFlappingClient { + private readonly logger: Logger; + private readonly savedObjectsClient: SavedObjectsClientContract; + private readonly getOrCreate: () => Promise>; + private readonly getModificationMetadata: () => Promise; + + constructor(options: RulesSettingsFlappingClientConstructorOptions) { + this.logger = options.logger; + this.savedObjectsClient = options.savedObjectsClient; + this.getOrCreate = options.getOrCreate; + this.getModificationMetadata = options.getModificationMetadata; + } + + public async get(): Promise { + const rulesSettings = await this.getOrCreate(); + return rulesSettings.attributes.flapping; + } + + public async update(newFlappingProperties: RulesSettingsFlappingProperties) { + try { + verifyFlappingSettings(newFlappingProperties); + } catch (e) { + this.logger.error( + `Failed to verify new flapping settings properties when updating. Error: ${e}` + ); + throw e; + } + + const { attributes, version } = await this.getOrCreate(); + const modificationMetadata = await this.getModificationMetadata(); + + try { + const result = await this.savedObjectsClient.update( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + { + ...attributes, + flapping: { + ...attributes.flapping, + ...newFlappingProperties, + ...modificationMetadata, + }, + }, + { + version, + } + ); + return result.attributes.flapping; + } catch (e) { + const errorMessage = 'savedObjectsClient errored trying to update flapping settings'; + this.logger.error(`${errorMessage}: ${e}`); + throw Boom.boomify(e, { message: errorMessage }); + } + } +} diff --git a/x-pack/plugins/alerting/server/rules_settings_client/index.ts b/x-pack/plugins/alerting/server/rules_settings_client/index.ts new file mode 100644 index 00000000000000..efbb3f0b3ccfe9 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './rules_settings_client'; +export * from './flapping/rules_settings_flapping_client'; diff --git a/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts new file mode 100644 index 00000000000000..a40c491b9117ec --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts @@ -0,0 +1,285 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + RulesSettingsClient, + RulesSettingsClientConstructorOptions, +} from './rules_settings_client'; +import { RulesSettingsFlappingClient } from './flapping/rules_settings_flapping_client'; +import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { SavedObjectsErrorHelpers } from '@kbn/core/server'; +import { + RULES_SETTINGS_FEATURE_ID, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + DEFAULT_FLAPPING_SETTINGS, + RulesSettings, +} from '../../common'; + +const mockDateString = '2019-02-12T21:01:22.479Z'; + +const savedObjectsClient = savedObjectsClientMock.create(); + +const rulesSettingsClientParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + getUserName: jest.fn(), + savedObjectsClient, +}; + +const getMockRulesSettings = (): RulesSettings => { + return { + flapping: { + enabled: DEFAULT_FLAPPING_SETTINGS.enabled, + lookBackWindow: DEFAULT_FLAPPING_SETTINGS.lookBackWindow, + statusChangeThreshold: DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + }; +}; + +describe('RulesSettingsClient', () => { + beforeAll(() => { + jest.useFakeTimers(); + jest.setSystemTime(new Date(mockDateString)); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + beforeEach(() => { + jest.resetAllMocks(); + rulesSettingsClientParams.getUserName.mockResolvedValue('test name'); + }); + + test('can initialize correctly', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + expect(client.flapping()).toEqual(expect.any(RulesSettingsFlappingClient)); + }); + + test('can create a new rules settings saved object', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.create.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + + const result = await client.create(); + + expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); + expect(savedObjectsClient.create).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: expect.objectContaining({ + enabled: mockAttributes.flapping.enabled, + lookBackWindow: mockAttributes.flapping.lookBackWindow, + statusChangeThreshold: mockAttributes.flapping.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + expect(result.attributes).toEqual(mockAttributes); + }); + + test('can get existing rules settings saved object', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.get.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + const result = await client.get(); + expect(result.attributes).toEqual(mockAttributes); + }); + + test('throws if there is no existing saved object to get', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + + savedObjectsClient.get.mockRejectedValueOnce( + SavedObjectsErrorHelpers.createGenericNotFoundError( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ) + ); + await expect(client.get()).rejects.toThrowError(); + }); + + test('can persist flapping settings when saved object does not exist', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + savedObjectsClient.get.mockRejectedValueOnce( + SavedObjectsErrorHelpers.createGenericNotFoundError( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ) + ); + + savedObjectsClient.create.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + + const result = await client.flapping().get(); + + expect(savedObjectsClient.get).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + + expect(savedObjectsClient.create).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: expect.objectContaining({ + enabled: mockAttributes.flapping.enabled, + lookBackWindow: mockAttributes.flapping.lookBackWindow, + statusChangeThreshold: mockAttributes.flapping.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + expect(result).toEqual(mockAttributes.flapping); + }); + + test('can persist flapping settings when saved object already exists', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.get.mockResolvedValueOnce({ + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + }); + + const result = await client.flapping().get(); + + expect(savedObjectsClient.get).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + expect(savedObjectsClient.create).not.toHaveBeenCalled(); + expect(result).toEqual(mockAttributes.flapping); + }); + + test('can update flapping settings when saved object does not exist', async () => { + const client = new RulesSettingsClient(rulesSettingsClientParams); + const mockAttributes = getMockRulesSettings(); + + savedObjectsClient.get.mockRejectedValueOnce( + SavedObjectsErrorHelpers.createGenericNotFoundError( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ) + ); + + const mockResolve = { + id: RULES_SETTINGS_FEATURE_ID, + type: RULES_SETTINGS_SAVED_OBJECT_TYPE, + attributes: mockAttributes, + references: [], + version: '123', + }; + + savedObjectsClient.create.mockResolvedValueOnce(mockResolve); + savedObjectsClient.update.mockResolvedValueOnce({ + ...mockResolve, + attributes: { + flapping: { + ...mockResolve.attributes.flapping, + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + }, + }, + }); + + // Try to update with new values + const result = await client.flapping().update({ + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + }); + + // Tried to get first, but no results + expect(savedObjectsClient.get).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + + // So create a new entry + expect(savedObjectsClient.create).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: expect.objectContaining({ + enabled: mockAttributes.flapping.enabled, + lookBackWindow: mockAttributes.flapping.lookBackWindow, + statusChangeThreshold: mockAttributes.flapping.statusChangeThreshold, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + + // Try to update with version + expect(savedObjectsClient.update).toHaveBeenCalledWith( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, + { + flapping: expect.objectContaining({ + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + createdBy: 'test name', + updatedBy: 'test name', + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + }, + { version: '123' } + ); + + expect(result).toEqual( + expect.objectContaining({ + enabled: false, + lookBackWindow: 5, + statusChangeThreshold: 5, + }) + ); + }); +}); diff --git a/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts new file mode 100644 index 00000000000000..1a99ab56442462 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + Logger, + SavedObjectsClientContract, + SavedObject, + SavedObjectsErrorHelpers, +} from '@kbn/core/server'; +import { RulesSettingsFlappingClient } from './flapping/rules_settings_flapping_client'; +import { + RulesSettings, + DEFAULT_FLAPPING_SETTINGS, + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID, +} from '../../common'; + +export interface RulesSettingsClientConstructorOptions { + readonly logger: Logger; + readonly savedObjectsClient: SavedObjectsClientContract; + readonly getUserName: () => Promise; +} + +export class RulesSettingsClient { + private readonly logger: Logger; + private readonly savedObjectsClient: SavedObjectsClientContract; + private readonly getUserName: () => Promise; + private readonly _flapping: RulesSettingsFlappingClient; + + constructor(options: RulesSettingsClientConstructorOptions) { + this.logger = options.logger; + this.savedObjectsClient = options.savedObjectsClient; + this.getUserName = options.getUserName; + + this._flapping = new RulesSettingsFlappingClient({ + logger: this.logger, + savedObjectsClient: this.savedObjectsClient, + getOrCreate: this.getOrCreate.bind(this), + getModificationMetadata: this.getModificationMetadata.bind(this), + }); + } + + private async getModificationMetadata() { + const createTime = Date.now(); + const userName = await this.getUserName(); + + return { + createdBy: userName, + updatedBy: userName, + createdAt: new Date(createTime).toISOString(), + updatedAt: new Date(createTime).toISOString(), + }; + } + + public async get(): Promise> { + try { + return await this.savedObjectsClient.get( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + RULES_SETTINGS_SAVED_OBJECT_ID + ); + } catch (e) { + this.logger.error(`Failed to get rules setting for current space. Error: ${e}`); + throw e; + } + } + + public async create(): Promise> { + const modificationMetadata = await this.getModificationMetadata(); + + try { + return await this.savedObjectsClient.create( + RULES_SETTINGS_SAVED_OBJECT_TYPE, + { + flapping: { + ...DEFAULT_FLAPPING_SETTINGS, + ...modificationMetadata, + }, + }, + { + id: RULES_SETTINGS_SAVED_OBJECT_ID, + overwrite: true, + } + ); + } catch (e) { + this.logger.error(`Failed to create rules setting for current space. Error: ${e}`); + throw e; + } + } + + /** + * Helper function to ensure that a rules-settings saved object always exists. + * Enabled the creation of the saved object is done lazily during retrieval. + */ + private async getOrCreate(): Promise> { + try { + return await this.get(); + } catch (e) { + if (SavedObjectsErrorHelpers.isNotFoundError(e)) { + this.logger.info('Creating new default rules settings for current space.'); + return await this.create(); + } + this.logger.error(`Failed to persist rules setting for current space. Error: ${e}`); + throw e; + } + } + + public flapping(): RulesSettingsFlappingClient { + return this._flapping; + } +} diff --git a/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts b/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts new file mode 100644 index 00000000000000..176082ee023362 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts @@ -0,0 +1,161 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Request } from '@hapi/hapi'; +import { CoreKibanaRequest } from '@kbn/core/server'; +import { + RulesSettingsClientFactory, + RulesSettingsClientFactoryOpts, +} from './rules_settings_client_factory'; +import { + savedObjectsClientMock, + savedObjectsServiceMock, + loggingSystemMock, +} from '@kbn/core/server/mocks'; +import { AuthenticatedUser } from '@kbn/security-plugin/common/model'; +import { securityMock } from '@kbn/security-plugin/server/mocks'; +import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../common'; + +jest.mock('./rules_settings_client'); + +const savedObjectsClient = savedObjectsClientMock.create(); +const savedObjectsService = savedObjectsServiceMock.createInternalStartContract(); + +const securityPluginStart = securityMock.createStart(); + +const rulesSettingsClientFactoryParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + savedObjectsService, +}; + +const fakeRequest = { + app: {}, + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, + getSavedObjectsClient: () => savedObjectsClient, +} as unknown as Request; + +beforeEach(() => { + jest.resetAllMocks(); +}); + +test('creates a rules settings client with proper constructor arguments when security is enabled', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize({ + securityPluginStart, + ...rulesSettingsClientFactoryParams, + }); + const request = CoreKibanaRequest.from(fakeRequest); + + savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); + + factory.createWithAuthorization(request); + + expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }); + + const { RulesSettingsClient } = jest.requireMock('./rules_settings_client'); + + expect(RulesSettingsClient).toHaveBeenCalledWith({ + logger: rulesSettingsClientFactoryParams.logger, + savedObjectsClient, + getUserName: expect.any(Function), + }); +}); + +test('creates a rules settings client with proper constructor arguments', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize(rulesSettingsClientFactoryParams); + const request = CoreKibanaRequest.from(fakeRequest); + + savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); + + factory.createWithAuthorization(request); + + expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }); + + const { RulesSettingsClient } = jest.requireMock('./rules_settings_client'); + + expect(RulesSettingsClient).toHaveBeenCalledWith({ + logger: rulesSettingsClientFactoryParams.logger, + savedObjectsClient, + getUserName: expect.any(Function), + }); +}); + +test('creates an unauthorized rules settings client', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize({ + securityPluginStart, + ...rulesSettingsClientFactoryParams, + }); + const request = CoreKibanaRequest.from(fakeRequest); + + savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); + + factory.create(request); + + expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { + excludedExtensions: [SECURITY_EXTENSION_ID], + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }); + + const { RulesSettingsClient } = jest.requireMock('./rules_settings_client'); + + expect(RulesSettingsClient).toHaveBeenCalledWith({ + logger: rulesSettingsClientFactoryParams.logger, + savedObjectsClient, + getUserName: expect.any(Function), + }); +}); + +test('getUserName() returns null when security is disabled', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize(rulesSettingsClientFactoryParams); + const request = CoreKibanaRequest.from(fakeRequest); + + factory.createWithAuthorization(request); + const constructorCall = + jest.requireMock('./rules_settings_client').RulesSettingsClient.mock.calls[0][0]; + + const userNameResult = await constructorCall.getUserName(); + expect(userNameResult).toEqual(null); +}); + +test('getUserName() returns a name when security is enabled', async () => { + const factory = new RulesSettingsClientFactory(); + factory.initialize({ + securityPluginStart, + ...rulesSettingsClientFactoryParams, + }); + const request = CoreKibanaRequest.from(fakeRequest); + + factory.createWithAuthorization(request); + + const constructorCall = + jest.requireMock('./rules_settings_client').RulesSettingsClient.mock.calls[0][0]; + + securityPluginStart.authc.getCurrentUser.mockReturnValueOnce({ + username: 'testname', + } as unknown as AuthenticatedUser); + const userNameResult = await constructorCall.getUserName(); + expect(userNameResult).toEqual('testname'); +}); diff --git a/x-pack/plugins/alerting/server/rules_settings_client_factory.ts b/x-pack/plugins/alerting/server/rules_settings_client_factory.ts new file mode 100644 index 00000000000000..619e498c6b9881 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_client_factory.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + KibanaRequest, + Logger, + SavedObjectsServiceStart, + SECURITY_EXTENSION_ID, +} from '@kbn/core/server'; +import { SecurityPluginStart } from '@kbn/security-plugin/server'; +import { RulesSettingsClient } from './rules_settings_client'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../common'; + +export interface RulesSettingsClientFactoryOpts { + logger: Logger; + savedObjectsService: SavedObjectsServiceStart; + securityPluginStart?: SecurityPluginStart; +} + +export class RulesSettingsClientFactory { + private isInitialized = false; + private logger!: Logger; + private savedObjectsService!: SavedObjectsServiceStart; + private securityPluginStart?: SecurityPluginStart; + + public initialize(options: RulesSettingsClientFactoryOpts) { + if (this.isInitialized) { + throw new Error('RulesSettingsClientFactory already initialized'); + } + this.isInitialized = true; + this.logger = options.logger; + this.savedObjectsService = options.savedObjectsService; + this.securityPluginStart = options.securityPluginStart; + } + + private createRulesSettingsClient(request: KibanaRequest, withAuth: boolean) { + const { securityPluginStart } = this; + const savedObjectsClient = this.savedObjectsService.getScopedClient(request, { + includedHiddenTypes: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + ...(withAuth ? {} : { excludedExtensions: [SECURITY_EXTENSION_ID] }), + }); + + return new RulesSettingsClient({ + logger: this.logger, + savedObjectsClient, + async getUserName() { + if (!securityPluginStart || !request) { + return null; + } + const user = securityPluginStart.authc.getCurrentUser(request); + return user ? user.username : null; + }, + }); + } + + public createWithAuthorization(request: KibanaRequest) { + return this.createRulesSettingsClient(request, true); + } + + public create(request: KibanaRequest) { + return this.createRulesSettingsClient(request, false); + } +} diff --git a/x-pack/plugins/alerting/server/rules_settings_feature.ts b/x-pack/plugins/alerting/server/rules_settings_feature.ts new file mode 100644 index 00000000000000..c207d337a2b204 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings_feature.ts @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { KibanaFeatureConfig } from '@kbn/features-plugin/common'; +import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; +import { + RULES_SETTINGS_FEATURE_ID, + READ_FLAPPING_SETTINGS_SUB_FEATURE_ID, + ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID, + API_PRIVILEGES, + RULES_SETTINGS_SAVED_OBJECT_TYPE, +} from '../common'; + +export const rulesSettingsFeature: KibanaFeatureConfig = { + id: RULES_SETTINGS_FEATURE_ID, + name: i18n.translate('xpack.alerting.feature.rulesSettingsFeatureName', { + defaultMessage: 'Rules Settings', + }), + category: DEFAULT_APP_CATEGORIES.management, + app: [], + management: { + insightsAndAlerting: ['triggersActions'], + }, + privileges: { + all: { + app: [], + api: [], + management: { + insightsAndAlerting: ['triggersActions'], + }, + savedObject: { + all: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + read: [], + }, + ui: ['show', 'save'], + }, + read: { + app: [], + api: [], + management: { + insightsAndAlerting: ['triggersActions'], + }, + savedObject: { + all: [], + read: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }, + ui: ['show'], + }, + }, + subFeatures: [ + { + name: i18n.translate('xpack.alerting.feature.flappingSettingsSubFeatureName', { + defaultMessage: 'Flapping Detection', + }), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [API_PRIVILEGES.READ_FLAPPING_SETTINGS, API_PRIVILEGES.WRITE_FLAPPING_SETTINGS], + name: 'All', + id: ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID, + includeIn: 'all', + savedObject: { + all: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + read: [], + }, + ui: ['writeFlappingSettingsUI', 'readFlappingSettingsUI'], + }, + { + api: [API_PRIVILEGES.READ_FLAPPING_SETTINGS], + name: 'Read', + id: READ_FLAPPING_SETTINGS_SUB_FEATURE_ID, + includeIn: 'read', + savedObject: { + all: [], + read: [RULES_SETTINGS_SAVED_OBJECT_TYPE], + }, + ui: ['readFlappingSettingsUI'], + }, + ], + }, + ], + }, + ], +}; diff --git a/x-pack/plugins/alerting/server/saved_objects/index.ts b/x-pack/plugins/alerting/server/saved_objects/index.ts index d8d53f4978d55a..cd69efaf3e875f 100644 --- a/x-pack/plugins/alerting/server/saved_objects/index.ts +++ b/x-pack/plugins/alerting/server/saved_objects/index.ts @@ -14,6 +14,7 @@ import type { import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import { MigrateFunctionsObject } from '@kbn/kibana-utils-plugin/common'; import { alertMappings } from './mappings'; +import { rulesSettingsMappings } from './rules_settings_mappings'; import { getMigrations } from './migrations'; import { transformRulesForExport } from './transform_rule_for_export'; import { RawRule } from '../types'; @@ -21,6 +22,7 @@ import { getImportWarnings } from './get_import_warnings'; import { isRuleExportable } from './is_rule_exportable'; import { RuleTypeRegistry } from '../rule_type_registry'; export { partiallyUpdateAlert } from './partially_update_alert'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../../common'; // Use caution when removing items from this array! Any field which has // ever existed in the rule SO must be included in this array to prevent @@ -114,6 +116,13 @@ export function setupSavedObjects( }, }); + savedObjects.registerType({ + name: RULES_SETTINGS_SAVED_OBJECT_TYPE, + hidden: true, + namespaceType: 'single', + mappings: rulesSettingsMappings, + }); + // Encrypted attributes encryptedSavedObjects.registerType({ type: 'alert', diff --git a/x-pack/plugins/alerting/server/saved_objects/rules_settings_mappings.ts b/x-pack/plugins/alerting/server/saved_objects/rules_settings_mappings.ts new file mode 100644 index 00000000000000..d20567edc28328 --- /dev/null +++ b/x-pack/plugins/alerting/server/saved_objects/rules_settings_mappings.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SavedObjectsTypeMappingDefinition } from '@kbn/core/server'; + +export const rulesSettingsMappings: SavedObjectsTypeMappingDefinition = { + properties: { + flapping: { + properties: { + enabled: { + type: 'boolean', + index: false, + }, + lookBackWindow: { + type: 'long', + index: false, + }, + statusChangeThreshold: { + type: 'long', + index: false, + }, + createdBy: { + type: 'keyword', + index: false, + }, + updatedBy: { + type: 'keyword', + index: false, + }, + createdAt: { + type: 'date', + index: false, + }, + updatedAt: { + type: 'date', + index: false, + }, + }, + }, + }, +}; diff --git a/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts b/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts index b903e638e06aab..163cadf1d084bd 100644 --- a/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/log_alerts.test.ts @@ -9,6 +9,7 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { Alert } from '../alert'; import { alertingEventLoggerMock } from '../lib/alerting_event_logger/alerting_event_logger.mock'; import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; +import { DefaultActionGroupId } from '../types'; import { logAlerts } from './log_alerts'; const logger: ReturnType = loggingSystemMock.createLogger(); @@ -28,8 +29,8 @@ describe('logAlerts', () => { alertingEventLogger, newAlerts: {}, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), }, recoveredAlerts: {}, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, @@ -51,11 +52,11 @@ describe('logAlerts', () => { alertingEventLogger, newAlerts: {}, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), }, recoveredAlerts: { - '8': new Alert<{}, {}>('8'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, @@ -75,8 +76,8 @@ describe('logAlerts', () => { }); test('should correctly debug log recovered alerts if canSetRecoveryContext is true', () => { - const recoveredAlert1 = new Alert<{ value: string }, {}>('8'); - const recoveredAlert2 = new Alert<{ value: string }, {}>('9'); + const recoveredAlert1 = new Alert<{ value: string }, {}, DefaultActionGroupId>('8'); + const recoveredAlert2 = new Alert<{ value: string }, {}, DefaultActionGroupId>('9'); const recoveredAlerts = { '8': recoveredAlert1, '9': recoveredAlert2, @@ -127,18 +128,18 @@ describe('logAlerts', () => { logger, alertingEventLogger, newAlerts: { - '4': new Alert<{}, {}>('4'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), - '4': new Alert<{}, {}>('4'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, recoveredAlerts: { - '7': new Alert<{}, {}>('7'), - '8': new Alert<{}, {}>('8'), - '9': new Alert<{}, {}>('9'), - '10': new Alert<{}, {}>('10'), + '7': new Alert<{}, {}, DefaultActionGroupId>('7'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8'), + '9': new Alert<{}, {}, DefaultActionGroupId>('9'), + '10': new Alert<{}, {}, DefaultActionGroupId>('10'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, @@ -215,18 +216,18 @@ describe('logAlerts', () => { logger, alertingEventLogger, newAlerts: { - '4': new Alert<{}, {}>('4'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, activeAlerts: { - '1': new Alert<{}, {}>('1'), - '2': new Alert<{}, {}>('2'), - '4': new Alert<{}, {}>('4'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1'), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, recoveredAlerts: { - '7': new Alert<{}, {}>('7'), - '8': new Alert<{}, {}>('8'), - '9': new Alert<{}, {}>('9'), - '10': new Alert<{}, {}>('10'), + '7': new Alert<{}, {}, DefaultActionGroupId>('7'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8'), + '9': new Alert<{}, {}, DefaultActionGroupId>('9'), + '10': new Alert<{}, {}, DefaultActionGroupId>('10'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, @@ -246,18 +247,18 @@ describe('logAlerts', () => { logger, alertingEventLogger, newAlerts: { - '4': new Alert<{}, {}>('4'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, activeAlerts: { - '1': new Alert<{}, {}>('1', { meta: { flapping: true } }), - '2': new Alert<{}, {}>('2'), - '4': new Alert<{}, {}>('4'), + '1': new Alert<{}, {}, DefaultActionGroupId>('1', { meta: { flapping: true } }), + '2': new Alert<{}, {}, DefaultActionGroupId>('2'), + '4': new Alert<{}, {}, DefaultActionGroupId>('4'), }, recoveredAlerts: { - '7': new Alert<{}, {}>('7'), - '8': new Alert<{}, {}>('8', { meta: { flapping: true } }), - '9': new Alert<{}, {}>('9'), - '10': new Alert<{}, {}>('10'), + '7': new Alert<{}, {}, DefaultActionGroupId>('7'), + '8': new Alert<{}, {}, DefaultActionGroupId>('8', { meta: { flapping: true } }), + '9': new Alert<{}, {}, DefaultActionGroupId>('9'), + '10': new Alert<{}, {}, DefaultActionGroupId>('10'), }, ruleLogPrefix: `test-rule-type-id:123: 'test rule'`, ruleRunMetricsStore, diff --git a/x-pack/plugins/alerting/server/task_runner/log_alerts.ts b/x-pack/plugins/alerting/server/task_runner/log_alerts.ts index 4b673b44864dd5..7f8f5d93a5d9fd 100644 --- a/x-pack/plugins/alerting/server/task_runner/log_alerts.ts +++ b/x-pack/plugins/alerting/server/task_runner/log_alerts.ts @@ -15,20 +15,27 @@ import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; export interface LogAlertsParams< State extends AlertInstanceState, - Context extends AlertInstanceContext + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string > { logger: Logger; alertingEventLogger: AlertingEventLogger; - newAlerts: Record>; - activeAlerts: Record>; - recoveredAlerts: Record>; + newAlerts: Record>; + activeAlerts: Record>; + recoveredAlerts: Record>; ruleLogPrefix: string; ruleRunMetricsStore: RuleRunMetricsStore; canSetRecoveryContext: boolean; shouldPersistAlerts: boolean; } -export function logAlerts({ +export function logAlerts< + State extends AlertInstanceState, + Context extends AlertInstanceContext, + ActionGroupIds extends string, + RecoveryActionGroupId extends string +>({ logger, alertingEventLogger, newAlerts, @@ -38,7 +45,7 @@ export function logAlerts) { +}: LogAlertsParams) { const newAlertIds = Object.keys(newAlerts); const activeAlertIds = Object.keys(activeAlerts); const recoveredAlertIds = Object.keys(recoveredAlerts); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 27977dd3bf6f5f..e88922f51ddb13 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -44,7 +44,6 @@ import { RuleTypeParams, RuleTypeState, parseDuration, - WithoutReservedActionGroups, } from '../../common'; import { NormalizedRuleType, UntypedNormalizedRuleType } from '../rule_type_registry'; import { getEsErrorMessage } from '../lib/errors'; @@ -114,7 +113,8 @@ export class TaskRunner< private legacyAlertsClient: LegacyAlertsClient< State, Context, - WithoutReservedActionGroups + ActionGroupIds, + RecoveryActionGroupId >; constructor( diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index c0399779a62df6..f2a368c062d051 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -25,6 +25,7 @@ import { SharePluginStart } from '@kbn/share-plugin/server'; import { RuleTypeRegistry as OrigruleTypeRegistry } from './rule_type_registry'; import { PluginSetupContract, PluginStartContract } from './plugin'; import { RulesClient } from './rules_client'; +import { RulesSettingsClient, RulesSettingsFlappingClient } from './rules_settings_client'; export * from '../common'; import { Rule, @@ -57,6 +58,7 @@ export type { RuleTypeParams }; */ export interface AlertingApiRequestHandlerContext { getRulesClient: () => RulesClient; + getRulesSettingsClient: () => RulesSettingsClient; listTypes: RuleTypeRegistry['list']; getFrameworkHealth: () => Promise; areApiKeysEnabled: () => Promise; @@ -320,6 +322,9 @@ export type RuleTypeRegistry = PublicMethodsOf; export type RulesClientApi = PublicMethodsOf; +export type RulesSettingsClientApi = PublicMethodsOf; +export type RulesSettingsFlappingClientApi = PublicMethodsOf; + export interface PublicMetricsSetters { setLastRunMetricsTotalSearchDurationMs: (totalSearchDurationMs: number) => void; setLastRunMetricsTotalIndexingDurationMs: (totalIndexingDurationMs: number) => void; diff --git a/x-pack/plugins/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap b/x-pack/plugins/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap index 224b0b3b78ab36..10c8daa6e85653 100644 --- a/x-pack/plugins/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap +++ b/x-pack/plugins/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap @@ -49,7 +49,7 @@ exports[`Error CONTAINER_IMAGE 1`] = `undefined`; exports[`Error DESTINATION_ADDRESS 1`] = `undefined`; -exports[`Error DEVICE_MODEL_NAME 1`] = `undefined`; +exports[`Error DEVICE_MODEL_IDENTIFIER 1`] = `undefined`; exports[`Error ERROR_CULPRIT 1`] = `"handleOopsie"`; @@ -212,6 +212,8 @@ exports[`Error SERVICE_RUNTIME_NAME 1`] = `undefined`; exports[`Error SERVICE_RUNTIME_VERSION 1`] = `undefined`; +exports[`Error SERVICE_TARGET_TYPE 1`] = `undefined`; + exports[`Error SERVICE_VERSION 1`] = `undefined`; exports[`Error SESSION_ID 1`] = `undefined`; @@ -337,7 +339,7 @@ exports[`Span CONTAINER_IMAGE 1`] = `undefined`; exports[`Span DESTINATION_ADDRESS 1`] = `undefined`; -exports[`Span DEVICE_MODEL_NAME 1`] = `undefined`; +exports[`Span DEVICE_MODEL_IDENTIFIER 1`] = `undefined`; exports[`Span ERROR_CULPRIT 1`] = `undefined`; @@ -483,6 +485,8 @@ exports[`Span SERVICE_RUNTIME_NAME 1`] = `undefined`; exports[`Span SERVICE_RUNTIME_VERSION 1`] = `undefined`; +exports[`Span SERVICE_TARGET_TYPE 1`] = `undefined`; + exports[`Span SERVICE_VERSION 1`] = `undefined`; exports[`Span SESSION_ID 1`] = `undefined`; @@ -612,7 +616,7 @@ exports[`Transaction CONTAINER_IMAGE 1`] = `undefined`; exports[`Transaction DESTINATION_ADDRESS 1`] = `undefined`; -exports[`Transaction DEVICE_MODEL_NAME 1`] = `undefined`; +exports[`Transaction DEVICE_MODEL_IDENTIFIER 1`] = `undefined`; exports[`Transaction ERROR_CULPRIT 1`] = `undefined`; @@ -772,6 +776,8 @@ exports[`Transaction SERVICE_RUNTIME_NAME 1`] = `undefined`; exports[`Transaction SERVICE_RUNTIME_VERSION 1`] = `undefined`; +exports[`Transaction SERVICE_TARGET_TYPE 1`] = `undefined`; + exports[`Transaction SERVICE_VERSION 1`] = `undefined`; exports[`Transaction SESSION_ID 1`] = `undefined`; diff --git a/x-pack/plugins/apm/common/es_fields/apm.ts b/x-pack/plugins/apm/common/es_fields/apm.ts index 3bf8c1919946fd..c20b70e0add769 100644 --- a/x-pack/plugins/apm/common/es_fields/apm.ts +++ b/x-pack/plugins/apm/common/es_fields/apm.ts @@ -32,6 +32,7 @@ export const SERVICE_RUNTIME_NAME = 'service.runtime.name'; export const SERVICE_RUNTIME_VERSION = 'service.runtime.version'; export const SERVICE_NODE_NAME = 'service.node.name'; export const SERVICE_VERSION = 'service.version'; +export const SERVICE_TARGET_TYPE = 'service.target.type'; export const URL_FULL = 'url.full'; export const HTTP_REQUEST_METHOD = 'http.request.method'; @@ -158,7 +159,7 @@ export const INDEX = '_index'; // Mobile export const NETWORK_CONNECTION_TYPE = 'network.connection.type'; -export const DEVICE_MODEL_NAME = 'device.model.name'; +export const DEVICE_MODEL_IDENTIFIER = 'device.model.identifier'; export const SESSION_ID = 'session.id'; export const APP_LAUNCH_TIME = 'application.launch.time'; export const EVENT_NAME = 'event.name'; diff --git a/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.test.ts b/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.test.ts index b6ad94d3cc0bb3..cacc544a3afe81 100644 --- a/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.test.ts +++ b/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.test.ts @@ -15,7 +15,7 @@ describe('getKueryWithMobileFilters', () => { appVersion: '', netConnectionType: undefined, }); - expect(result).toBe('device.model.name: foo'); + expect(result).toBe('device.model.identifier: foo'); }); it('should return only kuery when mobile filters are missing ', () => { @@ -38,7 +38,7 @@ describe('getKueryWithMobileFilters', () => { kuery: '', }); expect(result).toBe( - 'device.model.name: foo and host.os.version: bar and service.version: 1.0 and network.connection.type: fooBar' + 'device.model.identifier: foo and host.os.version: bar and service.version: 1.0 and network.connection.type: fooBar' ); }); @@ -52,7 +52,7 @@ describe('getKueryWithMobileFilters', () => { }); expect(result).toBe( - 'foo.bar.test: test and device.model.name: foo and host.os.version: bar and service.version: 1.0 and network.connection.type: fooBar' + 'foo.bar.test: test and device.model.identifier: foo and host.os.version: bar and service.version: 1.0 and network.connection.type: fooBar' ); }); @@ -66,7 +66,7 @@ describe('getKueryWithMobileFilters', () => { }); expect(result).toBe( - 'foo.bar.test: test and device.model.name: foo\\>. and host.os.version: bar\\*\\* and service.version: 1.0\\(\\)\\: and network.connection.type: fooBar\\)45' + 'foo.bar.test: test and device.model.identifier: foo\\>. and host.os.version: bar\\*\\* and service.version: 1.0\\(\\)\\: and network.connection.type: fooBar\\)45' ); }); }); diff --git a/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.ts b/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.ts index 6244b5a72f1f42..19970a0b24b933 100644 --- a/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.ts +++ b/x-pack/plugins/apm/common/utils/get_kuery_with_mobile_filters.ts @@ -7,7 +7,7 @@ import { HOST_OS_VERSION, - DEVICE_MODEL_NAME, + DEVICE_MODEL_IDENTIFIER, NETWORK_CONNECTION_TYPE, SERVICE_VERSION, } from '../es_fields/apm'; @@ -28,7 +28,7 @@ export function getKueryWithMobileFilters({ }) { const kueryWithFilters = [ kuery, - ...fieldValuePairToKql(DEVICE_MODEL_NAME, device), + ...fieldValuePairToKql(DEVICE_MODEL_IDENTIFIER, device), ...fieldValuePairToKql(HOST_OS_VERSION, osVersion), ...fieldValuePairToKql(SERVICE_VERSION, appVersion), ...fieldValuePairToKql(NETWORK_CONNECTION_TYPE, netConnectionType), diff --git a/x-pack/plugins/apm/public/components/app/mobile/charts/http_requests_chart.tsx b/x-pack/plugins/apm/public/components/app/mobile/charts/http_requests_chart.tsx new file mode 100644 index 00000000000000..0b530a6cc4e2c6 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/mobile/charts/http_requests_chart.tsx @@ -0,0 +1,146 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { + EuiPanel, + EuiTitle, + EuiIconTip, + EuiFlexItem, + EuiFlexGroup, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { useFetcher } from '../../../../hooks/use_fetcher'; +import { TimeseriesChartWithContext } from '../../../shared/charts/timeseries_chart_with_context'; +import { getComparisonChartTheme } from '../../../shared/time_comparison/get_comparison_chart_theme'; +import { + getTimeSeriesColor, + ChartType, +} from '../../../shared/charts/helper/get_timeseries_color'; +import { usePreviousPeriodLabel } from '../../../../hooks/use_previous_period_text'; + +const INITIAL_STATE = { + currentPeriod: [], + previousPeriod: [], +}; + +export function HttpRequestsChart({ + kuery, + serviceName, + start, + end, + transactionName, + environment, + offset, + comparisonEnabled, +}: { + kuery: string; + serviceName: string; + start: string; + end: string; + transactionType?: string; + transactionName?: string; + environment: string; + offset?: string; + comparisonEnabled: boolean; +}) { + const comparisonChartTheme = getComparisonChartTheme(); + const { currentPeriodColor, previousPeriodColor } = getTimeSeriesColor( + ChartType.HTTP_REQUESTS + ); + + const previousPeriodLabel = usePreviousPeriodLabel(); + + const { data = INITIAL_STATE, status } = useFetcher( + (callApmApi) => { + return callApmApi( + 'GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests', + { + params: { + path: { + serviceName, + }, + query: { + environment, + kuery, + start, + end, + transactionName, + offset: comparisonEnabled ? offset : undefined, + }, + }, + } + ); + }, + [ + environment, + kuery, + serviceName, + start, + end, + transactionName, + offset, + comparisonEnabled, + ] + ); + + const timeseries = [ + { + data: data.currentPeriod, + type: 'linemark', + color: currentPeriodColor, + title: i18n.translate('xpack.apm.transactions.httpRequestsTitle', { + defaultMessage: 'HTTP Requests', + }), + }, + ...(comparisonEnabled + ? [ + { + data: data.previousPeriod, + type: 'area', + color: previousPeriodColor, + title: previousPeriodLabel, + }, + ] + : []), + ]; + return ( + + + + +

    + {i18n.translate('xpack.apm.transactions.httpRequestsTitle', { + defaultMessage: 'HTTP Requests', + })} +

    +
    +
    + + + + +
    + + `${y}`} + /> +
    + ); +} diff --git a/x-pack/plugins/apm/public/components/app/mobile/charts/sessions_chart.tsx b/x-pack/plugins/apm/public/components/app/mobile/charts/sessions_chart.tsx new file mode 100644 index 00000000000000..8c0b806cce6be4 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/mobile/charts/sessions_chart.tsx @@ -0,0 +1,152 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiPanel, + EuiTitle, + EuiIconTip, + EuiFlexItem, + EuiFlexGroup, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { useFetcher } from '../../../../hooks/use_fetcher'; +import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; +import { TimeseriesChartWithContext } from '../../../shared/charts/timeseries_chart_with_context'; +import { getComparisonChartTheme } from '../../../shared/time_comparison/get_comparison_chart_theme'; +import { + getTimeSeriesColor, + ChartType, +} from '../../../shared/charts/helper/get_timeseries_color'; +import { usePreviousPeriodLabel } from '../../../../hooks/use_previous_period_text'; + +const INITIAL_STATE = { + currentPeriod: [], + previousPeriod: [], +}; + +type SessionsChart = + APIReturnType<'GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions'>; + +export function SessionsChart({ + kuery, + serviceName, + start, + end, + transactionType, + transactionName, + environment, + offset, + comparisonEnabled, +}: { + kuery: string; + serviceName: string; + start: string; + end: string; + transactionType?: string; + transactionName?: string; + environment: string; + offset?: string; + comparisonEnabled: boolean; +}) { + const comparisonChartTheme = getComparisonChartTheme(); + const { currentPeriodColor, previousPeriodColor } = getTimeSeriesColor( + ChartType.SESSIONS + ); + + const { data = INITIAL_STATE, status } = useFetcher( + (callApmApi) => { + return callApmApi( + 'GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions', + { + params: { + path: { + serviceName, + }, + query: { + environment, + kuery, + start, + end, + transactionType, + transactionName, + offset: comparisonEnabled ? offset : undefined, + }, + }, + } + ); + }, + [ + environment, + kuery, + serviceName, + start, + end, + transactionType, + transactionName, + offset, + comparisonEnabled, + ] + ); + const previousPeriodLabel = usePreviousPeriodLabel(); + + const timeseries = [ + { + data: data.currentPeriod, + type: 'linemark', + color: currentPeriodColor, + title: i18n.translate('xpack.apm.transactions.sessionsChartTitle', { + defaultMessage: 'Sessions', + }), + }, + ...(comparisonEnabled + ? [ + { + data: data.previousPeriod, + type: 'area', + color: previousPeriodColor, + title: previousPeriodLabel, + }, + ] + : []), + ]; + return ( + + + + +

    + {i18n.translate('xpack.apm.transactions.sessionsChartTitle', { + defaultMessage: 'Sessions', + })} +

    +
    +
    + + + + +
    + + `${y}`} + /> +
    + ); +} diff --git a/x-pack/plugins/apm/public/components/app/mobile/service_overview/index.tsx b/x-pack/plugins/apm/public/components/app/mobile/service_overview/index.tsx index c8ac865fc3a401..847df33534455c 100644 --- a/x-pack/plugins/apm/public/components/app/mobile/service_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/mobile/service_overview/index.tsx @@ -29,7 +29,7 @@ import { useApmRouter } from '../../../../hooks/use_apm_router'; import { ServiceOverviewThroughputChart } from '../../service_overview/service_overview_throughput_chart'; import { TransactionsTable } from '../../../shared/transactions_table'; import { - DEVICE_MODEL_NAME, + DEVICE_MODEL_IDENTIFIER, HOST_OS_VERSION, NETWORK_CONNECTION_TYPE, SERVICE_VERSION, @@ -191,7 +191,7 @@ export function MobileServiceOverview() { defaultMessage: 'Devices', } )} - metric={DEVICE_MODEL_NAME} + metric={DEVICE_MODEL_IDENTIFIER} start={start} end={end} kuery={kueryWithMobileFilters} diff --git a/x-pack/plugins/apm/public/components/app/mobile/service_overview/most_used_chart/index.tsx b/x-pack/plugins/apm/public/components/app/mobile/service_overview/most_used_chart/index.tsx index 101ae1592e5f16..53f9d41cd15b12 100644 --- a/x-pack/plugins/apm/public/components/app/mobile/service_overview/most_used_chart/index.tsx +++ b/x-pack/plugins/apm/public/components/app/mobile/service_overview/most_used_chart/index.tsx @@ -13,14 +13,14 @@ import { useKibana } from '@kbn/kibana-react-plugin/public'; import { ApmPluginStartDeps } from '../../../../../plugin'; import { getLensAttributes } from './get_lens_attributes'; import { - DEVICE_MODEL_NAME, + DEVICE_MODEL_IDENTIFIER, HOST_OS_VERSION, NETWORK_CONNECTION_TYPE, SERVICE_VERSION, } from '../../../../../../common/es_fields/apm'; export type MostUsedMetricTypes = - | typeof DEVICE_MODEL_NAME + | typeof DEVICE_MODEL_IDENTIFIER | typeof SERVICE_VERSION | typeof HOST_OS_VERSION | typeof NETWORK_CONNECTION_TYPE; diff --git a/x-pack/plugins/apm/public/components/app/mobile/transaction_overview/index.tsx b/x-pack/plugins/apm/public/components/app/mobile/transaction_overview/index.tsx index e3610662646685..3194a21c5d14ad 100644 --- a/x-pack/plugins/apm/public/components/app/mobile/transaction_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/mobile/transaction_overview/index.tsx @@ -18,13 +18,14 @@ import { useApmServiceContext } from '../../../../context/apm_service/use_apm_se import { useApmParams } from '../../../../hooks/use_apm_params'; import { useTimeRange } from '../../../../hooks/use_time_range'; import { AggregatedTransactionsBadge } from '../../../shared/aggregated_transactions_badge'; -import { MobileTransactionCharts } from '../../../shared/charts/transaction_charts/mobile_transaction_charts'; import { TransactionsTable } from '../../../shared/transactions_table'; import { replace } from '../../../shared/links/url_helpers'; import { getKueryWithMobileFilters } from '../../../../../common/utils/get_kuery_with_mobile_filters'; +import { MobileTransactionCharts } from './transaction_charts'; export function MobileTransactionOverview() { const { + path: { serviceName }, query: { environment, rangeFrom, @@ -35,10 +36,12 @@ export function MobileTransactionOverview() { appVersion, netConnectionType, kuery, + offset, + comparisonEnabled, }, } = useApmParams('/mobile-services/{serviceName}/transactions'); - const kueryWithFilters = getKueryWithMobileFilters({ + const kueryWithMobileFilters = getKueryWithMobileFilters({ device, osVersion, appVersion, @@ -73,10 +76,14 @@ export function MobileTransactionOverview() { )} @@ -85,7 +92,7 @@ export function MobileTransactionOverview() { numberOfTransactionsPerPage={25} showAggregationAccurateCallout environment={environment} - kuery={kueryWithFilters} + kuery={kueryWithMobileFilters} start={start} end={end} saveTableOptionsToUrl diff --git a/x-pack/plugins/apm/public/components/app/mobile/transaction_overview/transaction_charts.tsx b/x-pack/plugins/apm/public/components/app/mobile/transaction_overview/transaction_charts.tsx new file mode 100644 index 00000000000000..a80f0ebfbced35 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/mobile/transaction_overview/transaction_charts.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGrid, EuiFlexItem, EuiPanel, EuiSpacer } from '@elastic/eui'; +import React from 'react'; +import { AnnotationsContextProvider } from '../../../../context/annotations/annotations_context'; +import { ChartPointerEventContextProvider } from '../../../../context/chart_pointer_event/chart_pointer_event_context'; +import { ServiceOverviewThroughputChart } from '../../service_overview/service_overview_throughput_chart'; +import { SessionsChart } from '../charts/sessions_chart'; +import { HttpRequestsChart } from '../charts/http_requests_chart'; +import { LatencyChart } from '../../../shared/charts/latency_chart'; +import { FailedTransactionRateChart } from '../../../shared/charts/failed_transaction_rate_chart'; + +export function MobileTransactionCharts({ + serviceName, + kuery, + environment, + start, + end, + transactionType, + offset, + comparisonEnabled, +}: { + serviceName: string; + kuery: string; + environment: string; + start: string; + end: string; + transactionType?: string; + offset?: string; + comparisonEnabled: boolean; +}) { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx b/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx index a2a4b756d4c5b1..e250f1e09276b5 100644 --- a/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx +++ b/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx @@ -11,7 +11,6 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { apmLabsButton, - apmProgressiveLoading, apmServiceGroupMaxNumberOfServices, defaultApmServiceEnvironment, enableComparisonByDefault, @@ -28,7 +27,6 @@ import { BottomBarActions } from '../bottom_bar_actions'; const apmSettingsKeys = [ enableComparisonByDefault, defaultApmServiceEnvironment, - apmProgressiveLoading, apmServiceGroupMaxNumberOfServices, enableInspectEsQueries, apmLabsButton, diff --git a/x-pack/plugins/apm/public/components/shared/charts/helper/get_timeseries_color.ts b/x-pack/plugins/apm/public/components/shared/charts/helper/get_timeseries_color.ts index ba5ff5fec0801b..0ab27b607f099b 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/helper/get_timeseries_color.ts +++ b/x-pack/plugins/apm/public/components/shared/charts/helper/get_timeseries_color.ts @@ -15,6 +15,8 @@ export enum ChartType { FAILED_TRANSACTION_RATE, CPU_USAGE, MEMORY_USAGE, + SESSIONS, + HTTP_REQUESTS, ERROR_OCCURRENCES, } @@ -52,6 +54,14 @@ const timeSeriesColorMap: Record< currentPeriodColor: palette[8], previousPeriodColor: palette[18], }, + [ChartType.SESSIONS]: { + currentPeriodColor: palette[3], + previousPeriodColor: palette[13], + }, + [ChartType.HTTP_REQUESTS]: { + currentPeriodColor: palette[2], + previousPeriodColor: palette[12], + }, [ChartType.ERROR_OCCURRENCES]: { currentPeriodColor: palette[3], previousPeriodColor: palette[13], diff --git a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/mobile_transaction_charts.tsx b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/mobile_transaction_charts.tsx deleted file mode 100644 index 67d713eea2b0a4..00000000000000 --- a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/mobile_transaction_charts.tsx +++ /dev/null @@ -1,55 +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 { EuiFlexGrid, EuiFlexItem, EuiPanel } from '@elastic/eui'; -import React from 'react'; -import { AnnotationsContextProvider } from '../../../../context/annotations/annotations_context'; -import { ChartPointerEventContextProvider } from '../../../../context/chart_pointer_event/chart_pointer_event_context'; -import { ServiceOverviewThroughputChart } from '../../../app/service_overview/service_overview_throughput_chart'; -import { LatencyChart } from '../latency_chart'; -import { FailedTransactionRateChart } from '../failed_transaction_rate_chart'; - -export function MobileTransactionCharts({ - kuery, - environment, - start, - end, - transactionName, -}: { - kuery: string; - environment: string; - start: string; - end: string; - transactionName?: string; -}) { - return ( - - - - - - - - - - - - - - - - - - ); -} diff --git a/x-pack/plugins/apm/public/hooks/use_previous_period_text.ts b/x-pack/plugins/apm/public/hooks/use_previous_period_text.ts index 822fa8d6302301..544c3a6e28208e 100644 --- a/x-pack/plugins/apm/public/hooks/use_previous_period_text.ts +++ b/x-pack/plugins/apm/public/hooks/use_previous_period_text.ts @@ -22,7 +22,8 @@ export const usePreviousPeriodLabel = () => { } = useAnyOfApmParams( '/services', '/dependencies/*', - '/services/{serviceName}' + '/services/{serviceName}', + '/mobile-services/{serviceName}/*' ); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); diff --git a/x-pack/plugins/apm/server/routes/mobile/get_http_requests_chart.ts b/x-pack/plugins/apm/server/routes/mobile/get_http_requests_chart.ts new file mode 100644 index 00000000000000..e1e9ef59c94e83 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/mobile/get_http_requests_chart.ts @@ -0,0 +1,153 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '@kbn/observability-plugin/server'; +import { + SERVICE_NAME, + TRANSACTION_NAME, + SERVICE_TARGET_TYPE, +} from '../../../common/es_fields/apm'; +import { environmentQuery } from '../../../common/utils/environment_query'; +import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; +import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_previous_period_coordinate'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; +import { getBucketSize } from '../../lib/helpers/get_bucket_size'; +import { Coordinate } from '../../../typings/timeseries'; + +export interface HttpRequestsTimeseries { + currentPeriod: Coordinate[]; + previousPeriod: Coordinate[]; +} +interface Props { + apmEventClient: APMEventClient; + serviceName: string; + transactionName?: string; + environment: string; + start: number; + end: number; + kuery: string; + offset?: string; +} + +async function getHttpRequestsTimeseries({ + kuery, + apmEventClient, + serviceName, + transactionName, + environment, + start, + end, + offset, +}: Props) { + const { startWithOffset, endWithOffset } = getOffsetInMs({ + start, + end, + offset, + }); + + const { intervalString } = getBucketSize({ + start: startWithOffset, + end: endWithOffset, + minBucketSize: 60, + }); + + const response = await apmEventClient.search('get_http_requests_chart', { + apm: { events: [ProcessorEvent.metric] }, + body: { + track_total_hits: false, + size: 0, + query: { + bool: { + filter: [ + { exists: { field: SERVICE_TARGET_TYPE } }, + ...termQuery(SERVICE_NAME, serviceName), + ...termQuery(TRANSACTION_NAME, transactionName), + ...rangeQuery(startWithOffset, endWithOffset), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ], + }, + }, + aggs: { + timeseries: { + date_histogram: { + field: '@timestamp', + fixed_interval: intervalString, + min_doc_count: 0, + extended_bounds: { min: startWithOffset, max: endWithOffset }, + }, + aggs: { + requests: { + filter: { term: { [SERVICE_TARGET_TYPE]: 'http' } }, + }, + }, + }, + }, + }, + }); + + return ( + response?.aggregations?.timeseries.buckets.map((bucket) => { + return { + x: bucket.key, + y: bucket.doc_count ?? 0, + }; + }) ?? [] + ); +} + +export async function getHttpRequestsChart({ + kuery, + apmEventClient, + serviceName, + transactionName, + environment, + start, + end, + offset, +}: Props): Promise { + const options = { + serviceName, + transactionName, + apmEventClient, + kuery, + environment, + }; + + const currentPeriodPromise = getHttpRequestsTimeseries({ + ...options, + start, + end, + }); + + const previousPeriodPromise = offset + ? getHttpRequestsTimeseries({ + ...options, + start, + end, + offset, + }) + : []; + + const [currentPeriod, previousPeriod] = await Promise.all([ + currentPeriodPromise, + previousPeriodPromise, + ]); + + return { + currentPeriod, + previousPeriod: offsetPreviousPeriodCoordinates({ + currentPeriodTimeseries: currentPeriod, + previousPeriodTimeseries: previousPeriod, + }), + }; +} diff --git a/x-pack/plugins/apm/server/routes/mobile/get_mobile_filters.ts b/x-pack/plugins/apm/server/routes/mobile/get_mobile_filters.ts index 1b1553fa3be8c2..cc648513a896a6 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_mobile_filters.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_mobile_filters.ts @@ -12,7 +12,7 @@ import { } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { - DEVICE_MODEL_NAME, + DEVICE_MODEL_IDENTIFIER, HOST_OS_VERSION, NETWORK_CONNECTION_TYPE, SERVICE_NAME, @@ -76,7 +76,7 @@ export async function getMobileFilters({ aggs: { devices: { terms: { - field: DEVICE_MODEL_NAME, + field: DEVICE_MODEL_IDENTIFIER, size: 10, }, }, diff --git a/x-pack/plugins/apm/server/routes/mobile/get_mobile_stats.ts b/x-pack/plugins/apm/server/routes/mobile/get_mobile_stats.ts index 1102c728ce8db8..e37f4ec9616c85 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_mobile_stats.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_mobile_stats.ts @@ -13,9 +13,8 @@ import { import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { SERVICE_NAME, - TRANSACTION_TYPE, SESSION_ID, - SPAN_SUBTYPE, + SERVICE_TARGET_TYPE, APP_LAUNCH_TIME, EVENT_NAME, } from '../../../common/es_fields/apm'; @@ -59,7 +58,7 @@ export async function getMobileStats({ cardinality: { field: SESSION_ID }, }, requests: { - filter: { term: { [SPAN_SUBTYPE]: 'http' } }, + filter: { term: { [SERVICE_TARGET_TYPE]: 'http' } }, }, maxLoadTime: { max: { field: APP_LAUNCH_TIME }, @@ -85,7 +84,6 @@ export async function getMobileStats({ bool: { filter: [ ...termQuery(SERVICE_NAME, serviceName), - ...termQuery(TRANSACTION_TYPE, transactionType), ...rangeQuery(start, end), ...environmentQuery(environment), ...kqlQuery(kuery), diff --git a/x-pack/plugins/apm/server/routes/mobile/get_sessions_chart.ts b/x-pack/plugins/apm/server/routes/mobile/get_sessions_chart.ts new file mode 100644 index 00000000000000..874743af633421 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/mobile/get_sessions_chart.ts @@ -0,0 +1,160 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '@kbn/observability-plugin/server'; +import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_previous_period_coordinate'; +import { + SERVICE_NAME, + SESSION_ID, + TRANSACTION_NAME, +} from '../../../common/es_fields/apm'; +import { environmentQuery } from '../../../common/utils/environment_query'; +import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; +import { getBucketSize } from '../../lib/helpers/get_bucket_size'; +import { Coordinate } from '../../../typings/timeseries'; + +export interface SessionsTimeseries { + currentPeriod: Coordinate[]; + previousPeriod: Coordinate[]; +} + +interface Props { + apmEventClient: APMEventClient; + serviceName: string; + transactionName?: string; + environment: string; + start: number; + end: number; + kuery: string; + offset?: string; +} + +async function getSessionTimeseries({ + apmEventClient, + serviceName, + transactionName, + environment, + start, + end, + kuery, + offset, +}: Props) { + const { startWithOffset, endWithOffset } = getOffsetInMs({ + start, + end, + offset, + }); + + const { intervalString } = getBucketSize({ + start: startWithOffset, + end: endWithOffset, + minBucketSize: 60, + }); + + const response = await apmEventClient.search('get_sessions_chart', { + apm: { + events: [ + ProcessorEvent.transaction, + ProcessorEvent.error, + ProcessorEvent.span, + ], + }, + body: { + track_total_hits: false, + size: 0, + query: { + bool: { + filter: [ + { exists: { field: SESSION_ID } }, + ...termQuery(SERVICE_NAME, serviceName), + ...termQuery(TRANSACTION_NAME, transactionName), + ...rangeQuery(startWithOffset, endWithOffset), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ], + }, + }, + aggs: { + timeseries: { + date_histogram: { + field: '@timestamp', + fixed_interval: intervalString, + min_doc_count: 0, + extended_bounds: { min: startWithOffset, max: endWithOffset }, + }, + aggs: { + sessions: { + cardinality: { field: SESSION_ID }, + }, + }, + }, + }, + }, + }); + + return ( + response?.aggregations?.timeseries.buckets.map((bucket) => { + return { + x: bucket.key, + y: bucket.doc_count ?? 0, + }; + }) ?? [] + ); +} + +export async function getSessionsChart({ + kuery, + apmEventClient, + serviceName, + transactionName, + environment, + start, + end, + offset, +}: Props): Promise { + const options = { + serviceName, + transactionName, + apmEventClient, + kuery, + environment, + }; + + const currentPeriodPromise = getSessionTimeseries({ + ...options, + start, + end, + }); + + const previousPeriodPromise = offset + ? getSessionTimeseries({ + ...options, + start, + end, + offset, + }) + : []; + + const [currentPeriod, previousPeriod] = await Promise.all([ + currentPeriodPromise, + previousPeriodPromise, + ]); + + return { + currentPeriod, + previousPeriod: offsetPreviousPeriodCoordinates({ + currentPeriodTimeseries: currentPeriod, + previousPeriodTimeseries: previousPeriod, + }), + }; +} diff --git a/x-pack/plugins/apm/server/routes/mobile/route.ts b/x-pack/plugins/apm/server/routes/mobile/route.ts index 966a12ab776ede..e18e7cae75c877 100644 --- a/x-pack/plugins/apm/server/routes/mobile/route.ts +++ b/x-pack/plugins/apm/server/routes/mobile/route.ts @@ -9,10 +9,16 @@ import * as t from 'io-ts'; import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; +import { offsetRt } from '../../../common/comparison_rt'; +import { + getHttpRequestsChart, + HttpRequestsTimeseries, +} from './get_http_requests_chart'; import { getMobileFilters } from './get_mobile_filters'; +import { getSessionsChart, SessionsTimeseries } from './get_sessions_chart'; import { getMobileStats, MobileStats } from './get_mobile_stats'; -const mobileFilters = createApmServerRoute({ +const mobileFiltersRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/services/{serviceName}/mobile/filters', params: t.type({ path: t.type({ @@ -51,7 +57,7 @@ const mobileFilters = createApmServerRoute({ }, }); -const mobileStats = createApmServerRoute({ +const mobileStatsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/mobile-services/{serviceName}/stats', params: t.type({ path: t.type({ @@ -71,12 +77,11 @@ const mobileStats = createApmServerRoute({ const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.path; - const { kuery, environment, start, end, transactionType } = params.query; + const { kuery, environment, start, end } = params.query; const stats = await getMobileStats({ kuery, environment, - transactionType, start, end, serviceName, @@ -87,7 +92,91 @@ const mobileStats = createApmServerRoute({ }, }); +const sessionsChartRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions', + params: t.type({ + path: t.type({ + serviceName: t.string, + }), + query: t.intersection([ + kueryRt, + rangeRt, + environmentRt, + offsetRt, + t.partial({ + transactionType: t.string, + transactionName: t.string, + }), + ]), + }), + options: { tags: ['access:apm'] }, + handler: async (resources): Promise => { + const apmEventClient = await getApmEventClient(resources); + const { params } = resources; + const { serviceName } = params.path; + const { kuery, environment, start, end, transactionName, offset } = + params.query; + + const { currentPeriod, previousPeriod } = await getSessionsChart({ + kuery, + environment, + transactionName, + start, + end, + serviceName, + apmEventClient, + offset, + }); + + return { currentPeriod, previousPeriod }; + }, +}); + +const httpRequestsChartRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests', + params: t.type({ + path: t.type({ + serviceName: t.string, + }), + query: t.intersection([ + kueryRt, + rangeRt, + environmentRt, + offsetRt, + t.partial({ + transactionType: t.string, + transactionName: t.string, + }), + ]), + }), + options: { tags: ['access:apm'] }, + handler: async (resources): Promise => { + const apmEventClient = await getApmEventClient(resources); + const { params } = resources; + const { serviceName } = params.path; + const { kuery, environment, start, end, transactionName, offset } = + params.query; + + const { currentPeriod, previousPeriod } = await getHttpRequestsChart({ + kuery, + environment, + transactionName, + start, + end, + serviceName, + apmEventClient, + offset, + }); + + return { currentPeriod, previousPeriod }; + }, +}); + export const mobileRouteRepository = { - ...mobileFilters, - ...mobileStats, + ...mobileFiltersRoute, + ...sessionsChartRoute, + ...httpRequestsChartRoute, + ...mobileStatsRoute, }; diff --git a/x-pack/plugins/cases/common/api/connectors/index.ts b/x-pack/plugins/cases/common/api/connectors/index.ts index 5f73f3ae493ac0..8aac471c634b86 100644 --- a/x-pack/plugins/cases/common/api/connectors/index.ts +++ b/x-pack/plugins/cases/common/api/connectors/index.ts @@ -116,6 +116,15 @@ export const CaseConnectorRt = rt.intersection([ CaseUserActionConnectorRt, ]); +export const GetCaseConnectorsResponseRt = rt.record( + rt.string, + rt.intersection([ + rt.type({ needsToBePushed: rt.boolean, hasBeenPushed: rt.boolean }), + rt.partial(rt.type({ latestPushDate: rt.string }).props), + CaseConnectorRt, + ]) +); + export type CaseUserActionConnector = rt.TypeOf; export type CaseConnector = rt.TypeOf; export type ConnectorTypeFields = rt.TypeOf; @@ -130,3 +139,5 @@ export type ConnectorServiceNowSIRTypeFields = rt.TypeOf; + +export type GetCaseConnectorsResponse = rt.TypeOf; diff --git a/x-pack/plugins/cases/common/constants.ts b/x-pack/plugins/cases/common/constants.ts index af50c851a1979e..1f8d6031a1c56f 100644 --- a/x-pack/plugins/cases/common/constants.ts +++ b/x-pack/plugins/cases/common/constants.ts @@ -89,6 +89,7 @@ export const INTERNAL_BULK_CREATE_ATTACHMENTS_URL = `${CASES_INTERNAL_URL}/{case_id}/attachments/_bulk_create` as const; export const INTERNAL_SUGGEST_USER_PROFILES_URL = `${CASES_INTERNAL_URL}/_suggest_user_profiles` as const; +export const INTERNAL_CONNECTORS_URL = `${CASES_INTERNAL_URL}/{case_id}/_connectors` as const; export const INTERNAL_BULK_GET_CASES_URL = `${CASES_INTERNAL_URL}/_bulk_get` as const; /** diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index 226d5578e8521e..3fad9872c07bf1 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -71,6 +71,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -107,6 +117,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -162,6 +182,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -419,6 +449,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -482,6 +522,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -649,6 +699,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -882,6 +942,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1104,6 +1174,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1184,6 +1264,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1253,6 +1343,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1310,6 +1410,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1373,6 +1483,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1428,6 +1548,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1477,6 +1607,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1540,6 +1680,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1569,6 +1719,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1625,6 +1785,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1659,6 +1829,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1698,6 +1878,16 @@ "responses": { "204": { "description": "Indicates a successful call." + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1746,6 +1936,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1807,6 +2007,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -1856,6 +2066,16 @@ } } } + }, + "401": { + "description": "Authorization information is missing or invalid.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/4xx_response" + } + } + } } }, "servers": [ @@ -3008,6 +3228,23 @@ } } }, + "4xx_response": { + "type": "object", + "title": "Unsuccessful cases API response", + "properties": { + "error": { + "type": "string", + "example": "Unauthorized" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "example": 401 + } + } + }, "update_case_request": { "title": "Update case request", "description": "The update case API request body varies depending on the type of connector.", diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index e01bf8c4fea106..129bf13a79b48c 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -45,6 +45,12 @@ paths: examples: createCaseResponse: $ref: '#/components/examples/create_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 delete: @@ -67,6 +73,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 patch: @@ -99,6 +111,12 @@ paths: examples: updateCaseResponse: $ref: '#/components/examples/update_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -257,6 +275,12 @@ paths: examples: findCaseResponse: $ref: '#/components/examples/find_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -293,6 +317,12 @@ paths: example: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 title: security_case + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -409,6 +439,12 @@ paths: version: type: string example: WzIwNzMsMV0= + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 post: @@ -573,6 +609,12 @@ paths: examples: setCaseConfigResponse: $ref: '#/components/examples/set_case_configuration_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -728,6 +770,12 @@ paths: version: type: string example: WzIwNzMsMV0= + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -777,6 +825,12 @@ paths: examples: findConnectorResponse: $ref: '#/components/examples/find_connector_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -820,6 +874,12 @@ paths: examples: getReportersResponse: $ref: '#/components/examples/get_reporters_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -853,6 +913,12 @@ paths: examples: getStatusResponse: $ref: '#/components/examples/get_status_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -888,6 +954,12 @@ paths: examples: getTagsResponse: $ref: '#/components/examples/get_tags_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -920,6 +992,12 @@ paths: examples: getCaseResponse: $ref: '#/components/examples/get_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -948,6 +1026,12 @@ paths: examples: getCaseAlertsResponse: $ref: '#/components/examples/get_case_alerts_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -983,6 +1067,12 @@ paths: examples: createCaseCommentResponse: $ref: '#/components/examples/add_comment_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 delete: @@ -999,6 +1089,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 patch: @@ -1031,6 +1127,12 @@ paths: examples: updateCaseCommentResponse: $ref: '#/components/examples/update_comment_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 get: @@ -1051,6 +1153,12 @@ paths: application/json: schema: $ref: '#/components/schemas/case_response_properties' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -1071,6 +1179,12 @@ paths: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 get: @@ -1096,6 +1210,12 @@ paths: examples: getCaseCommentResponse: $ref: '#/components/examples/get_comment_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -1129,6 +1249,12 @@ paths: examples: pushCaseResponse: $ref: '#/components/examples/push_case_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -1157,6 +1283,12 @@ paths: examples: getCaseActivityResponse: $ref: '#/components/examples/get_case_activity_response' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/4xx_response' servers: - url: https://localhost:5601 servers: @@ -2004,6 +2136,18 @@ components: version: type: string example: WzUzMiwxXQ== + 4xx_response: + type: object + title: Unsuccessful cases API response + properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 update_case_request: title: Update case request description: The update case API request body varies depending on the type of connector. diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml new file mode 100644 index 00000000000000..75d0ac39903bf0 --- /dev/null +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml @@ -0,0 +1,11 @@ +type: object +title: Unsuccessful cases API response +properties: + error: + type: string + example: Unauthorized + message: + type: string + statusCode: + type: integer + example: 401 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml index 98e36898e96859..ba4b852d964054 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml @@ -29,6 +29,12 @@ post: examples: createCaseResponse: $ref: '../components/examples/create_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -55,6 +61,12 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -90,6 +102,12 @@ patch: examples: updateCaseResponse: $ref: '../components/examples/update_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml index 65fbc2e1e2e404..e4eb42e73f0b2c 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml @@ -163,6 +163,12 @@ get: examples: findCaseResponse: $ref: '../components/examples/find_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml index f12e48f4bb6b93..940f343c893868 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml @@ -30,7 +30,13 @@ get: description: The case title. example: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 - title: security_case + title: security_case + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml index e95a6f5410149e..cc17f044d437cc 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml @@ -21,6 +21,12 @@ get: type: object properties: $ref: '../components/schemas/case_configure_response_properties.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -90,8 +96,13 @@ post: examples: setCaseConfigResponse: $ref: '../components/examples/set_case_configuration_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 - servers: - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml index d6328b4426f7bd..7cdd1bf63ae616 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml @@ -23,6 +23,12 @@ get: examples: findConnectorResponse: $ref: '../components/examples/find_connector_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml index c15c3ff5dc1d75..5f8dae09abf552 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml @@ -50,6 +50,12 @@ patch: type: object properties: $ref: '../components/schemas/case_configure_response_properties.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml index 171af68a417ba4..51e57615f12164 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml @@ -28,6 +28,12 @@ get: examples: getReportersResponse: $ref: '../components/examples/get_reporters_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml index c3f4875e07ffd3..a9db413e2eaef4 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml @@ -28,6 +28,12 @@ get: examples: getStatusResponse: $ref: '../components/examples/get_status_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml index a4ce739c52b047..5e70cff6640e15 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml @@ -30,7 +30,12 @@ get: examples: getTagsResponse: $ref: '../components/examples/get_tags_response.yaml' - + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml index d32d24b9fa01ba..aca09f4a74420b 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml @@ -27,6 +27,12 @@ get: examples: getCaseResponse: $ref: '../components/examples/get_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml index abf2f26ce357bc..aca587fe4886c7 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml @@ -23,6 +23,12 @@ get: examples: getCaseAlertsResponse: $ref: '../components/examples/get_case_alerts_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml index 25d119bd613c76..1b69926377ffbf 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml @@ -31,6 +31,12 @@ post: examples: createCaseCommentResponse: $ref: '../components/examples/add_comment_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -50,6 +56,12 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -86,6 +98,12 @@ patch: examples: updateCaseCommentResponse: $ref: '../components/examples/update_comment_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -109,9 +127,13 @@ get: application/json: schema: $ref: '../components/schemas/case_response_properties.yaml' - + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 - servers: - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml index f12e43158a99a9..e43a2b2d81d65b 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml @@ -15,6 +15,12 @@ delete: responses: '204': description: Indicates a successful call. + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 @@ -43,8 +49,13 @@ get: examples: getCaseCommentResponse: $ref: '../components/examples/get_comment_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 - servers: - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml index 7c4ba981edd07e..c378192592ce94 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml @@ -30,6 +30,12 @@ post: examples: pushCaseResponse: $ref: '../components/examples/push_case_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml index 43a6ec096dfaaf..a21988cd5434fd 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml @@ -23,6 +23,12 @@ get: examples: getCaseActivityResponse: $ref: '../components/examples/get_case_activity_response.yaml' + '401': + description: Authorization information is missing or invalid. + content: + application/json: + schema: + $ref: '../components/schemas/4xx_response.yaml' servers: - url: https://localhost:5601 servers: diff --git a/x-pack/plugins/cases/public/common/translations.ts b/x-pack/plugins/cases/public/common/translations.ts index b7ef1d80f3afae..fdccc41f8e1acd 100644 --- a/x-pack/plugins/cases/public/common/translations.ts +++ b/x-pack/plugins/cases/public/common/translations.ts @@ -21,6 +21,14 @@ export const DELETE_CASE = (quantity: number = 1) => defaultMessage: `Delete {quantity, plural, =1 {case} other {{quantity} cases}}`, }); +export const COPY_ID_ACTION_LABEL = i18n.translate('xpack.cases.caseView.copyID', { + defaultMessage: 'Copy Case ID', +}); + +export const COPY_ID_ACTION_SUCCESS = i18n.translate('xpack.cases.caseView.copyIDSuccess', { + defaultMessage: 'Copied Case ID to clipboard', +}); + export const NAME = i18n.translate('xpack.cases.caseView.name', { defaultMessage: 'Name', }); @@ -158,7 +166,7 @@ export const NO_TAGS = i18n.translate('xpack.cases.caseView.noTags', { }); export const TITLE_REQUIRED = i18n.translate('xpack.cases.createCase.titleFieldRequiredError', { - defaultMessage: 'A title is required.', + defaultMessage: 'A name is required.', }); export const CONFIGURE_CASES_PAGE_TITLE = i18n.translate('xpack.cases.configureCases.headerTitle', { diff --git a/x-pack/plugins/cases/public/components/actions/copy_id/use_copy_id_action.test.tsx b/x-pack/plugins/cases/public/components/actions/copy_id/use_copy_id_action.test.tsx new file mode 100644 index 00000000000000..7cc4f7677286bb --- /dev/null +++ b/x-pack/plugins/cases/public/components/actions/copy_id/use_copy_id_action.test.tsx @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { AppMockRenderer } from '../../../common/mock'; +import { createAppMockRenderer } from '../../../common/mock'; +import { renderHook } from '@testing-library/react-hooks'; +import { useCopyIDAction } from './use_copy_id_action'; + +import { basicCase } from '../../../containers/mock'; + +jest.mock('../../../containers/api'); + +describe('useCopyIDAction', () => { + let appMockRender: AppMockRenderer; + const onActionSuccess = jest.fn(); + const originalClipboard = global.window.navigator.clipboard; + + beforeEach(() => { + appMockRender = createAppMockRenderer(); + jest.clearAllMocks(); + Object.defineProperty(navigator, 'clipboard', { + value: { + writeText: jest.fn().mockImplementation(() => Promise.resolve()), + }, + writable: true, + }); + }); + + afterEach(() => { + Object.defineProperty(navigator, 'clipboard', { + value: originalClipboard, + }); + }); + + it('renders a copy ID action with one case', async () => { + const { result } = renderHook(() => useCopyIDAction({ onActionSuccess }), { + wrapper: appMockRender.AppWrapper, + }); + + expect(result.current.getAction(basicCase)).toMatchInlineSnapshot(` + Object { + "data-test-subj": "cases-action-copy-id", + "icon": , + "key": "cases-action-copy-id", + "name": + Copy Case ID + , + "onClick": [Function], + } + `); + }); + + it('copies the id of the selected case to the clipboard', async () => { + const { result, waitFor } = renderHook(() => useCopyIDAction({ onActionSuccess }), { + wrapper: appMockRender.AppWrapper, + }); + + const action = result.current.getAction(basicCase); + + action.onClick(); + + await waitFor(() => { + expect(onActionSuccess).toHaveBeenCalled(); + expect(navigator.clipboard.writeText).toHaveBeenCalledWith(basicCase.id); + }); + }); + + it('shows the success toaster correctly when copying the case id', async () => { + const { result, waitFor } = renderHook(() => useCopyIDAction({ onActionSuccess }), { + wrapper: appMockRender.AppWrapper, + }); + + const action = result.current.getAction(basicCase); + + action.onClick(); + + await waitFor(() => { + expect(onActionSuccess).toHaveBeenCalled(); + expect(appMockRender.coreStart.notifications.toasts.addSuccess).toHaveBeenCalledWith( + 'Copied Case ID to clipboard' + ); + }); + }); +}); diff --git a/x-pack/plugins/cases/public/components/actions/copy_id/use_copy_id_action.tsx b/x-pack/plugins/cases/public/components/actions/copy_id/use_copy_id_action.tsx new file mode 100644 index 00000000000000..be2166ba5b2504 --- /dev/null +++ b/x-pack/plugins/cases/public/components/actions/copy_id/use_copy_id_action.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiIcon, EuiTextColor } from '@elastic/eui'; +import * as i18n from '../../../common/translations'; +import { useCasesToast } from '../../../common/use_cases_toast'; + +import type { Case } from '../../../../common'; +import type { UseCopyIDActionProps } from '../types'; + +export const useCopyIDAction = ({ onActionSuccess }: UseCopyIDActionProps) => { + const { showSuccessToast } = useCasesToast(); + + const getAction = (selectedCase: Case) => { + return { + name: {i18n.COPY_ID_ACTION_LABEL}, + onClick: () => { + navigator.clipboard.writeText(selectedCase.id).then(() => { + onActionSuccess(); + showSuccessToast(i18n.COPY_ID_ACTION_SUCCESS); + }); + }, + 'data-test-subj': 'cases-action-copy-id', + icon: , + key: 'cases-action-copy-id', + }; + }; + + return { getAction }; +}; + +export type UseCopyIDAction = ReturnType; diff --git a/x-pack/plugins/cases/public/components/actions/types.ts b/x-pack/plugins/cases/public/components/actions/types.ts index a906a0ff382695..7d477a09eed522 100644 --- a/x-pack/plugins/cases/public/components/actions/types.ts +++ b/x-pack/plugins/cases/public/components/actions/types.ts @@ -13,6 +13,8 @@ export interface UseActionProps { isDisabled: boolean; } +export type UseCopyIDActionProps = Pick; + export interface ItemsSelectionState { selectedItems: string[]; unSelectedItems: string[]; diff --git a/x-pack/plugins/cases/public/components/all_cases/use_actions.test.tsx b/x-pack/plugins/cases/public/components/all_cases/use_actions.test.tsx index ac60ccbc6c0bfb..ab719466bbb251 100644 --- a/x-pack/plugins/cases/public/components/all_cases/use_actions.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/use_actions.test.tsx @@ -73,6 +73,7 @@ describe('useActions', () => { expect(res.getByText('Actions')).toBeInTheDocument(); expect(res.getByTestId(`case-action-status-panel-${basicCase.id}`)).toBeInTheDocument(); expect(res.getByTestId('cases-bulk-action-delete')).toBeInTheDocument(); + expect(res.getByTestId('cases-action-copy-id')).toBeInTheDocument(); }); }); @@ -143,6 +144,40 @@ describe('useActions', () => { }); }); + it('copies the case id to the clipboard', async () => { + const originalClipboard = global.window.navigator.clipboard; + + Object.defineProperty(navigator, 'clipboard', { + value: { + writeText: jest.fn().mockImplementation(() => Promise.resolve()), + }, + writable: true, + }); + + const { result } = renderHook(() => useActions({ disableActions: false }), { + wrapper: appMockRender.AppWrapper, + }); + + const comp = result.current.actions!.render(basicCase) as React.ReactElement; + const res = appMockRender.render(comp); + + userEvent.click(res.getByTestId(`case-action-popover-button-${basicCase.id}`)); + + await waitFor(() => { + expect(res.getByTestId('cases-action-copy-id')).toBeInTheDocument(); + }); + + userEvent.click(res.getByTestId('cases-action-copy-id'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(navigator.clipboard.writeText).toHaveBeenCalledWith(basicCase.id); + + Object.defineProperty(navigator, 'clipboard', { + value: originalClipboard, + }); + }); + describe('Modals', () => { it('delete a case', async () => { const deleteSpy = jest.spyOn(api, 'deleteCases'); @@ -304,6 +339,7 @@ describe('useActions', () => { expect(res.getByTestId(`case-action-severity-panel-${basicCase.id}`)).toBeInTheDocument(); expect(res.getByTestId('cases-bulk-action-delete')).toBeInTheDocument(); expect(res.getByTestId(`actions-separator-${basicCase.id}`)).toBeInTheDocument(); + expect(res.getByTestId('cases-action-copy-id')).toBeInTheDocument(); }); }); @@ -321,6 +357,7 @@ describe('useActions', () => { await waitFor(() => { expect(res.getByTestId(`case-action-status-panel-${basicCase.id}`)).toBeInTheDocument(); expect(res.getByTestId(`case-action-severity-panel-${basicCase.id}`)).toBeInTheDocument(); + expect(res.getByTestId('cases-action-copy-id')).toBeInTheDocument(); expect(res.queryByTestId('cases-bulk-action-delete')).toBeFalsy(); expect(res.queryByTestId(`actions-separator-${basicCase.id}`)).toBeFalsy(); }); @@ -340,6 +377,7 @@ describe('useActions', () => { await waitFor(() => { expect(res.queryByTestId(`case-action-status-panel-${basicCase.id}`)).toBeFalsy(); expect(res.queryByTestId(`case-action-severity-panel-${basicCase.id}`)).toBeFalsy(); + expect(res.getByTestId('cases-action-copy-id')).toBeInTheDocument(); expect(res.getByTestId('cases-bulk-action-delete')).toBeInTheDocument(); expect(res.queryByTestId(`actions-separator-${basicCase.id}`)).toBeFalsy(); }); diff --git a/x-pack/plugins/cases/public/components/all_cases/use_actions.tsx b/x-pack/plugins/cases/public/components/all_cases/use_actions.tsx index d793233f9cca64..a06235d144a50d 100644 --- a/x-pack/plugins/cases/public/components/all_cases/use_actions.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/use_actions.tsx @@ -27,6 +27,7 @@ import { useTagsAction } from '../actions/tags/use_tags_action'; import { EditTagsFlyout } from '../actions/tags/edit_tags_flyout'; import { useAssigneesAction } from '../actions/assignees/use_assignees_action'; import { EditAssigneesFlyout } from '../actions/assignees/edit_assignees_flyout'; +import { useCopyIDAction } from '../actions/copy_id/use_copy_id_action'; const ActionColumnComponent: React.FC<{ theCase: Case; disableActions: boolean }> = ({ theCase, @@ -43,6 +44,10 @@ const ActionColumnComponent: React.FC<{ theCase: Case; disableActions: boolean } onActionSuccess: refreshCases, }); + const copyIDAction = useCopyIDAction({ + onActionSuccess: closePopover, + }); + const statusAction = useStatusAction({ isDisabled: false, onAction: closePopover, @@ -126,6 +131,8 @@ const ActionColumnComponent: React.FC<{ theCase: Case; disableActions: boolean } mainPanelItems.push(assigneesAction.getAction([theCase])); } + mainPanelItems.push(copyIDAction.getAction(theCase)); + if (canDelete) { mainPanelItems.push(deleteAction.getAction([theCase])); } @@ -146,13 +153,14 @@ const ActionColumnComponent: React.FC<{ theCase: Case; disableActions: boolean } return panelsToBuild; }, [ + assigneesAction, canDelete, canUpdate, + copyIDAction, deleteAction, severityAction, statusAction, tagsAction, - assigneesAction, theCase, ]); diff --git a/x-pack/plugins/cases/public/components/case_action_bar/actions.test.tsx b/x-pack/plugins/cases/public/components/case_action_bar/actions.test.tsx index cf15d546415bef..16bef4b933d6ec 100644 --- a/x-pack/plugins/cases/public/components/case_action_bar/actions.test.tsx +++ b/x-pack/plugins/cases/public/components/case_action_bar/actions.test.tsx @@ -55,6 +55,32 @@ describe('CaseView actions', () => { expect(wrapper.find('[data-test-subj="confirm-delete-case-modal"]').exists()).toBeTruthy(); }); + it('clicking copyClipboard icon copies case id', () => { + const originalClipboard = global.window.navigator.clipboard; + + Object.defineProperty(navigator, 'clipboard', { + value: { + writeText: jest.fn().mockImplementation(() => Promise.resolve()), + }, + writable: true, + }); + + const wrapper = mount( + + + + ); + + wrapper.find('button[data-test-subj="property-actions-ellipses"]').first().simulate('click'); + wrapper.find('button[data-test-subj="property-actions-copyClipboard"]').simulate('click'); + + expect(navigator.clipboard.writeText).toHaveBeenCalledWith(basicCase.id); + + Object.defineProperty(navigator, 'clipboard', { + value: originalClipboard, + }); + }); + it('does not show trash icon when user does not have deletion privileges', () => { const wrapper = mount( @@ -63,7 +89,9 @@ describe('CaseView actions', () => { ); expect(wrapper.find('[data-test-subj="confirm-delete-case-modal"]').exists()).toBeFalsy(); - expect(wrapper.find('button[data-test-subj="property-actions-ellipses"]').exists()).toBeFalsy(); + wrapper.find('button[data-test-subj="property-actions-ellipses"]').first().simulate('click'); + expect(wrapper.find('[data-test-subj="property-actions-trash"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="property-actions-copyClipboard"]').exists()).toBeTruthy(); }); it('toggle delete modal and confirm', async () => { diff --git a/x-pack/plugins/cases/public/components/case_action_bar/actions.tsx b/x-pack/plugins/cases/public/components/case_action_bar/actions.tsx index 414ac6326ef5d5..bb6e323d433a0e 100644 --- a/x-pack/plugins/cases/public/components/case_action_bar/actions.tsx +++ b/x-pack/plugins/cases/public/components/case_action_bar/actions.tsx @@ -16,6 +16,7 @@ import type { Case } from '../../../common/ui/types'; import type { CaseService } from '../../containers/use_get_case_user_actions'; import { useAllCasesNavigation } from '../../common/navigation'; import { useCasesContext } from '../cases_context/use_cases_context'; +import { useCasesToast } from '../../common/use_cases_toast'; interface CaseViewActions { caseData: Case; @@ -26,6 +27,7 @@ const ActionsComponent: React.FC = ({ caseData, currentExternal const { mutate: deleteCases } = useDeleteCases(); const { navigateToAllCases } = useAllCasesNavigation(); const { permissions } = useCasesContext(); + const { showSuccessToast } = useCasesToast(); const [isModalVisible, setIsModalVisible] = useState(false); const openModal = useCallback(() => { @@ -38,11 +40,20 @@ const ActionsComponent: React.FC = ({ caseData, currentExternal const propertyActions = useMemo( () => [ + { + iconType: 'copyClipboard', + label: i18n.COPY_ID_ACTION_LABEL, + onClick: () => { + navigator.clipboard.writeText(caseData.id); + showSuccessToast(i18n.COPY_ID_ACTION_SUCCESS); + }, + }, ...(permissions.delete ? [ { iconType: 'trash', label: i18n.DELETE_CASE(), + color: 'danger' as const, onClick: openModal, }, ] @@ -57,7 +68,7 @@ const ActionsComponent: React.FC = ({ caseData, currentExternal ] : []), ], - [permissions.delete, openModal, currentExternalIncident] + [permissions.delete, openModal, currentExternalIncident, caseData.id, showSuccessToast] ); const onConfirmDeletion = useCallback(() => { diff --git a/x-pack/plugins/cases/public/components/case_action_bar/index.test.tsx b/x-pack/plugins/cases/public/components/case_action_bar/index.test.tsx index dc2cbccc229c25..e458961db3424f 100644 --- a/x-pack/plugins/cases/public/components/case_action_bar/index.test.tsx +++ b/x-pack/plugins/cases/public/components/case_action_bar/index.test.tsx @@ -233,8 +233,10 @@ describe('CaseActionBar', () => { ); - expect(queryByTestId('property-actions-ellipses')).not.toBeInTheDocument(); + userEvent.click(screen.getByTestId('property-actions-ellipses')); expect(queryByText('Delete case')).not.toBeInTheDocument(); + expect(queryByTestId('property-actions-trash')).not.toBeInTheDocument(); + expect(queryByTestId('property-actions-copyClipboard')).toBeInTheDocument(); }); it('should show the the delete item in the menu when the user does have delete privileges', () => { diff --git a/x-pack/plugins/cases/public/components/create/form_context.test.tsx b/x-pack/plugins/cases/public/components/create/form_context.test.tsx index 1f7551b466b8ad..37971667da37b1 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.test.tsx @@ -282,7 +282,7 @@ describe('Create case', () => { await waitFor(() => { expect( - screen.getByText('The length of the title is too long. The maximum length is 160.') + screen.getByText('The length of the name is too long. The maximum length is 160.') ).toBeInTheDocument(); }); diff --git a/x-pack/plugins/cases/public/components/create/schema.tsx b/x-pack/plugins/cases/public/components/create/schema.tsx index f80c4e52945bb9..10f414109852d7 100644 --- a/x-pack/plugins/cases/public/components/create/schema.tsx +++ b/x-pack/plugins/cases/public/components/create/schema.tsx @@ -58,7 +58,7 @@ export const schema: FormSchema = { { validator: maxLengthField({ length: MAX_TITLE_LENGTH, - message: i18n.MAX_LENGTH_ERROR('title', MAX_TITLE_LENGTH), + message: i18n.MAX_LENGTH_ERROR('name', MAX_TITLE_LENGTH), }), }, ], diff --git a/x-pack/plugins/cases/public/components/property_actions/index.tsx b/x-pack/plugins/cases/public/components/property_actions/index.tsx index 8f67611097a805..61f4c4b6f2cfe8 100644 --- a/x-pack/plugins/cases/public/components/property_actions/index.tsx +++ b/x-pack/plugins/cases/public/components/property_actions/index.tsx @@ -6,6 +6,7 @@ */ import React, { useCallback, useState } from 'react'; +import type { EuiButtonProps } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiPopover, EuiButtonIcon, EuiButtonEmpty } from '@elastic/eui'; import * as i18n from './translations'; @@ -15,15 +16,16 @@ export interface PropertyActionButtonProps { onClick: () => void; iconType: string; label: string; + color?: EuiButtonProps['color']; } const ComponentId = 'property-actions'; const PropertyActionButton = React.memo( - ({ disabled = false, onClick, iconType, label }) => ( + ({ disabled = false, onClick, iconType, label, color }) => ( (({ propertyActio disabled={action.disabled} iconType={action.iconType} label={action.label} + color={action.color} onClick={() => onClosePopover(action.onClick)} /> diff --git a/x-pack/plugins/cases/public/components/user_actions/property_actions/alert_property_actions.tsx b/x-pack/plugins/cases/public/components/user_actions/property_actions/alert_property_actions.tsx index 0acafdcfa8d609..9885de69bb5512 100644 --- a/x-pack/plugins/cases/public/components/user_actions/property_actions/alert_property_actions.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/property_actions/alert_property_actions.tsx @@ -32,6 +32,7 @@ const AlertPropertyActionsComponent: React.FC = ({ isLoading, totalAlerts ? [ { iconType: 'minusInCircle', + color: 'danger' as const, label: i18n.REMOVE_ALERTS(totalAlerts), onClick: onModalOpen, }, diff --git a/x-pack/plugins/cases/public/components/user_actions/property_actions/registered_attachments_property_actions.tsx b/x-pack/plugins/cases/public/components/user_actions/property_actions/registered_attachments_property_actions.tsx index 28d82525246f5e..8859d61c99ea5e 100644 --- a/x-pack/plugins/cases/public/components/user_actions/property_actions/registered_attachments_property_actions.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/property_actions/registered_attachments_property_actions.tsx @@ -34,6 +34,7 @@ const RegisteredAttachmentsPropertyActionsComponent: React.FC = ({ ? [ { iconType: 'trash', + color: 'danger' as const, label: i18n.DELETE_ATTACHMENT, onClick: onModalOpen, }, diff --git a/x-pack/plugins/cases/public/components/user_actions/property_actions/user_comment_property_actions.tsx b/x-pack/plugins/cases/public/components/user_actions/property_actions/user_comment_property_actions.tsx index 90d16dfc2bf610..a791ef534e5ddf 100644 --- a/x-pack/plugins/cases/public/components/user_actions/property_actions/user_comment_property_actions.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/property_actions/user_comment_property_actions.tsx @@ -54,21 +54,22 @@ const UserCommentPropertyActionsComponent: React.FC = ({ }, ] : []), - ...(showTrashIcon + ...(showQuoteIcon ? [ { - iconType: 'trash', - label: i18n.DELETE_COMMENT, - onClick: onModalOpen, + iconType: 'quote', + label: i18n.QUOTE, + onClick: onQuote, }, ] : []), - ...(showQuoteIcon + ...(showTrashIcon ? [ { - iconType: 'quote', - label: i18n.QUOTE, - onClick: onQuote, + iconType: 'trash', + color: 'danger' as const, + label: i18n.DELETE_COMMENT, + onClick: onModalOpen, }, ] : []), diff --git a/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap b/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap index ee6bc6e4a3681c..6e824f460a722d 100644 --- a/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap +++ b/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap @@ -1596,6 +1596,90 @@ Object { } `; +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" with an error and entity 1`] = ` +Object { + "error": Object { + "code": "Error", + "message": "an error", + }, + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "failure", + "type": Array [ + "access", + ], + }, + "kibana": Object { + "saved_object": Object { + "id": "1", + "type": "cases-user-actions", + }, + }, + "message": "Failed attempt to access cases-user-actions [id=1] as owner \\"awesome\\"", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" with an error but no entity 1`] = ` +Object { + "error": Object { + "code": "Error", + "message": "an error", + }, + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "failure", + "type": Array [ + "access", + ], + }, + "message": "Failed attempt to access a user actions as any owners", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" without an error but with an entity 1`] = ` +Object { + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "success", + "type": Array [ + "access", + ], + }, + "kibana": Object { + "saved_object": Object { + "id": "5", + "type": "cases-user-actions", + }, + }, + "message": "User has accessed cases-user-actions [id=5] as owner \\"super\\"", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getConnectors" without an error or entity 1`] = ` +Object { + "event": Object { + "action": "case_connectors_get", + "category": Array [ + "database", + ], + "outcome": "success", + "type": Array [ + "access", + ], + }, + "message": "User has accessed a user actions as any owners", +} +`; + exports[`audit_logger log function event structure creates the correct audit event for operation: "getReporters" with an error and entity 1`] = ` Object { "error": Object { diff --git a/x-pack/plugins/cases/server/authorization/index.ts b/x-pack/plugins/cases/server/authorization/index.ts index 723221d361d825..0c301f372ba5d7 100644 --- a/x-pack/plugins/cases/server/authorization/index.ts +++ b/x-pack/plugins/cases/server/authorization/index.ts @@ -318,6 +318,14 @@ export const Operations: Record ({ id: comment.id, @@ -150,7 +150,7 @@ export async function deleteComment( refresh: false, }); - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.comment, action: Actions.delete, caseId: id, diff --git a/x-pack/plugins/cases/server/client/cases/create.ts b/x-pack/plugins/cases/server/client/cases/create.ts index 0da0f42b93f2f3..a8f9975fee39ff 100644 --- a/x-pack/plugins/cases/server/client/cases/create.ts +++ b/x-pack/plugins/cases/server/client/cases/create.ts @@ -102,7 +102,7 @@ export const create = async ( refresh: false, }); - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.create_case, caseId: newCase.id, user, diff --git a/x-pack/plugins/cases/server/client/cases/delete.ts b/x-pack/plugins/cases/server/client/cases/delete.ts index 0b7a6a6839e5c8..81f5df0d2d2b39 100644 --- a/x-pack/plugins/cases/server/client/cases/delete.ts +++ b/x-pack/plugins/cases/server/client/cases/delete.ts @@ -68,7 +68,7 @@ export async function deleteCases(ids: string[], clientArgs: CasesClientArgs): P options: { refresh: 'wait_for' }, }); - await userActionService.bulkAuditLogCaseDeletion( + await userActionService.creator.bulkAuditLogCaseDeletion( cases.saved_objects.map((caseInfo) => caseInfo.id) ); } catch (error) { diff --git a/x-pack/plugins/cases/server/client/cases/push.ts b/x-pack/plugins/cases/server/client/cases/push.ts index 9f5e9adbb4815c..340a93dee2d4f3 100644 --- a/x-pack/plugins/cases/server/client/cases/push.ts +++ b/x-pack/plugins/cases/server/client/cases/push.ts @@ -257,7 +257,7 @@ export const push = async ( ]); if (shouldMarkAsClosed) { - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.status, payload: { status: CaseStatuses.closed }, user, @@ -271,7 +271,7 @@ export const push = async ( } } - await userActionService.createUserAction({ + await userActionService.creator.createUserAction({ type: ActionTypes.pushed, payload: { externalService }, user, diff --git a/x-pack/plugins/cases/server/client/cases/update.ts b/x-pack/plugins/cases/server/client/cases/update.ts index 6a304bf12e3e69..622665f139ad21 100644 --- a/x-pack/plugins/cases/server/client/cases/update.ts +++ b/x-pack/plugins/cases/server/client/cases/update.ts @@ -444,7 +444,7 @@ export const update = async ( ]; }, [] as CaseResponse[]); - await userActionService.bulkCreateUpdateCase({ + await userActionService.creator.bulkCreateUpdateCase({ originalCases: myCases.saved_objects, updatedCases: updatedCases.saved_objects, user, diff --git a/x-pack/plugins/cases/server/client/factory.ts b/x-pack/plugins/cases/server/client/factory.ts index 9816f8444e399b..63f0fdcb5a12b8 100644 --- a/x-pack/plugins/cases/server/client/factory.ts +++ b/x-pack/plugins/cases/server/client/factory.ts @@ -13,6 +13,7 @@ import type { SavedObjectsClientContract, IBasePath, } from '@kbn/core/server'; +import type { ISavedObjectsSerializer } from '@kbn/core-saved-objects-server'; import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server'; import type { AuditLogger, @@ -119,8 +120,11 @@ export class CasesClientFactory { excludedExtensions: [SECURITY_EXTENSION_ID], }); + const savedObjectsSerializer = savedObjectsService.createSerializer(); + const services = this.createServices({ unsecuredSavedObjectsClient, + savedObjectsSerializer, esClient: scopedClusterClient, request, auditLogger, @@ -152,11 +156,13 @@ export class CasesClientFactory { private createServices({ unsecuredSavedObjectsClient, + savedObjectsSerializer, esClient, request, auditLogger, }: { unsecuredSavedObjectsClient: SavedObjectsClientContract; + savedObjectsSerializer: ISavedObjectsSerializer; esClient: ElasticsearchClient; request: KibanaRequest; auditLogger: AuditLogger; @@ -201,6 +207,7 @@ export class CasesClientFactory { log: this.logger, persistableStateAttachmentTypeRegistry: this.options.persistableStateAttachmentTypeRegistry, unsecuredSavedObjectsClient, + savedObjectsSerializer, auditLogger, }), attachmentService, diff --git a/x-pack/plugins/cases/server/client/mocks.ts b/x-pack/plugins/cases/server/client/mocks.ts index 3281cd77642402..0ca2578d107a25 100644 --- a/x-pack/plugins/cases/server/client/mocks.ts +++ b/x-pack/plugins/cases/server/client/mocks.ts @@ -83,6 +83,7 @@ type UserActionsSubClientMock = jest.Mocked; const createUserActionsSubClientMock = (): UserActionsSubClientMock => { return { getAll: jest.fn(), + getConnectors: jest.fn(), }; }; diff --git a/x-pack/plugins/cases/server/client/user_actions/client.ts b/x-pack/plugins/cases/server/client/user_actions/client.ts index 3f14a313cd8f2e..bb529ae3b2c2f6 100644 --- a/x-pack/plugins/cases/server/client/user_actions/client.ts +++ b/x-pack/plugins/cases/server/client/user_actions/client.ts @@ -5,19 +5,12 @@ * 2.0. */ +import type { GetCaseConnectorsResponse } from '../../../common/api'; import type { ICaseUserActionsResponse } from '../typedoc_interfaces'; import type { CasesClientArgs } from '../types'; import { get } from './get'; - -/** - * Parameters for retrieving user actions for a particular case - */ -export interface UserActionGet { - /** - * The ID of the case - */ - caseId: string; -} +import { getConnectors } from './connectors'; +import type { GetConnectorsRequest, UserActionGet } from './types'; /** * API for interacting the actions performed by a user when interacting with the cases entities. @@ -27,16 +20,19 @@ export interface UserActionsSubClient { * Retrieves all user actions for a particular case. */ getAll(clientArgs: UserActionGet): Promise; + /** + * Retrieves all the connectors used within a given case + */ + getConnectors(clientArgs: GetConnectorsRequest): Promise; } /** * Creates an API object for interacting with the user action entities - * - * @ignore */ export const createUserActionsSubClient = (clientArgs: CasesClientArgs): UserActionsSubClient => { const attachmentSubClient: UserActionsSubClient = { getAll: (params: UserActionGet) => get(params, clientArgs), + getConnectors: (params: GetConnectorsRequest) => getConnectors(params, clientArgs), }; return Object.freeze(attachmentSubClient); diff --git a/x-pack/plugins/cases/server/client/user_actions/connectors.ts b/x-pack/plugins/cases/server/client/user_actions/connectors.ts new file mode 100644 index 00000000000000..18cba75d79948e --- /dev/null +++ b/x-pack/plugins/cases/server/client/user_actions/connectors.ts @@ -0,0 +1,265 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEqual } from 'lodash'; + +import type { SavedObject } from '@kbn/core/server'; +import type { PublicMethodsOf } from '@kbn/utility-types'; +import type { ActionResult, ActionsClient } from '@kbn/actions-plugin/server'; +import type { + CaseUserActionResponse, + GetCaseConnectorsResponse, + CaseConnector, +} from '../../../common/api'; +import { GetCaseConnectorsResponseRt } from '../../../common/api'; +import { isConnectorUserAction, isCreateCaseUserAction } from '../../../common/utils/user_actions'; +import { createCaseError } from '../../common/error'; +import type { CasesClientArgs } from '..'; +import type { Authorization, OwnerEntity } from '../../authorization'; +import { Operations } from '../../authorization'; +import type { GetConnectorsRequest } from './types'; +import type { CaseConnectorActivity, PushInfo } from '../../services/user_actions/types'; +import type { CaseUserActionService } from '../../services'; + +export const getConnectors = async ( + { caseId }: GetConnectorsRequest, + clientArgs: CasesClientArgs +): Promise => { + const { + services: { userActionService }, + logger, + authorization, + actionsClient, + } = clientArgs; + + try { + const [connectors, latestUserAction] = await Promise.all([ + userActionService.getCaseConnectorInformation(caseId), + userActionService.getMostRecentUserAction(caseId), + ]); + + await checkConnectorsAuthorization({ authorization, connectors, latestUserAction }); + + const results = await getConnectorsInfo({ + caseId, + actionsClient, + connectors, + latestUserAction, + userActionService, + }); + + return GetCaseConnectorsResponseRt.encode(results); + } catch (error) { + throw createCaseError({ + message: `Failed to retrieve the case connectors case id: ${caseId}: ${error}`, + error, + logger, + }); + } +}; + +const checkConnectorsAuthorization = async ({ + connectors, + latestUserAction, + authorization, +}: { + connectors: CaseConnectorActivity[]; + latestUserAction?: SavedObject; + authorization: PublicMethodsOf; +}) => { + const entities: OwnerEntity[] = latestUserAction + ? [{ owner: latestUserAction.attributes.owner, id: latestUserAction.id }] + : []; + + for (const connector of connectors) { + entities.push({ + owner: connector.fields.attributes.owner, + id: connector.connectorId, + }); + + if (connector.push) { + entities.push({ + owner: connector.push.attributes.owner, + id: connector.connectorId, + }); + } + } + + await authorization.ensureAuthorized({ + entities, + operation: Operations.getConnectors, + }); +}; + +interface EnrichedPushInfo { + pushDate: Date; + connectorFieldsUsedInPush: CaseConnector; +} + +const getConnectorsInfo = async ({ + caseId, + connectors, + latestUserAction, + actionsClient, + userActionService, +}: { + caseId: string; + connectors: CaseConnectorActivity[]; + latestUserAction?: SavedObject; + actionsClient: PublicMethodsOf; + userActionService: CaseUserActionService; +}): Promise => { + const connectorIds = connectors.map((connector) => connector.connectorId); + + const [pushInfo, actionConnectors] = await Promise.all([ + getPushInfo({ caseId, activity: connectors, userActionService }), + actionsClient.getBulk(connectorIds), + ]); + + return createConnectorInfoResult({ actionConnectors, connectors, pushInfo, latestUserAction }); +}; + +const getPushInfo = async ({ + caseId, + activity, + userActionService, +}: { + caseId: string; + activity: CaseConnectorActivity[]; + userActionService: CaseUserActionService; +}): Promise> => { + const pushRequest: PushInfo[] = []; + + for (const connectorInfo of activity) { + const pushCreatedAt = getDate(connectorInfo.push?.attributes.created_at); + + if (connectorInfo.push != null && pushCreatedAt != null) { + pushRequest.push({ connectorId: connectorInfo.connectorId, date: pushCreatedAt }); + } + } + + const connectorFieldsForPushes = await userActionService.getConnectorFieldsBeforeLatestPush( + caseId, + pushRequest + ); + + const enrichedPushInfo = new Map(); + for (const request of pushRequest) { + const connectorFieldsSO = connectorFieldsForPushes.get(request.connectorId); + const connectorFields = getConnectorInfoFromSavedObject(connectorFieldsSO); + + if (connectorFields != null) { + enrichedPushInfo.set(request.connectorId, { + pushDate: request.date, + connectorFieldsUsedInPush: connectorFields, + }); + } + } + + return enrichedPushInfo; +}; + +const getDate = (timestamp: string | undefined): Date | undefined => { + if (timestamp == null) { + return; + } + + const date = new Date(timestamp); + + if (isDateValid(date)) { + return date; + } +}; + +const isDateValid = (date: Date): boolean => { + return !isNaN(date.getTime()); +}; + +const getConnectorInfoFromSavedObject = ( + savedObject: SavedObject | undefined +): CaseConnector | undefined => { + if ( + savedObject != null && + (isConnectorUserAction(savedObject.attributes) || + isCreateCaseUserAction(savedObject.attributes)) + ) { + return savedObject.attributes.payload.connector; + } +}; + +const createConnectorInfoResult = ({ + actionConnectors, + connectors, + pushInfo, + latestUserAction, +}: { + actionConnectors: ActionResult[]; + connectors: CaseConnectorActivity[]; + pushInfo: Map; + latestUserAction?: SavedObject; +}) => { + const results: GetCaseConnectorsResponse = {}; + + for (let i = 0; i < connectors.length; i++) { + const connectorDetails = actionConnectors[i]; + const aggregationConnector = connectors[i]; + const connector = getConnectorInfoFromSavedObject(aggregationConnector.fields); + + const latestUserActionCreatedAt = getDate(latestUserAction?.attributes.created_at); + + if (connector != null) { + const enrichedPushInfo = pushInfo.get(aggregationConnector.connectorId); + const needsToBePushed = hasDataToPush({ + connector, + pushInfo: enrichedPushInfo, + latestUserActionDate: latestUserActionCreatedAt, + }); + + results[connector.id] = { + ...connector, + name: connectorDetails.name, + needsToBePushed, + latestPushDate: enrichedPushInfo?.pushDate.toISOString(), + hasBeenPushed: hasBeenPushed(enrichedPushInfo), + }; + } + } + + return results; +}; + +/** + * The algorithm to determine if a specific connector within a case needs to be pushed is as follows: + * 1. Check to see if the connector has been used to push, if it hasn't then we need to push + * 2. Check to see if the most recent connector fields are different than the connector fields used in the most recent push, + * if they are different then we need to push + * 3. Check to see if the most recent valid user action (a valid user action is one that changes the title, description, + * tags, or creation of a comment) was created after the most recent push (aka did the user do something new that needs + * to be pushed) + */ +const hasDataToPush = ({ + connector, + pushInfo, + latestUserActionDate, +}: { + connector: CaseConnector; + pushInfo?: EnrichedPushInfo; + latestUserActionDate?: Date; +}): boolean => { + return ( + /** + * This isEqual call satisfies the first two steps of the algorithm above because if a push never occurred then the + * push fields will be undefined which will not equal the latest connector fields anyway. + */ + !isEqual(connector, pushInfo?.connectorFieldsUsedInPush) || + (pushInfo != null && latestUserActionDate != null && latestUserActionDate > pushInfo.pushDate) + ); +}; + +const hasBeenPushed = (pushInfo: EnrichedPushInfo | undefined): boolean => { + return pushInfo != null; +}; diff --git a/x-pack/plugins/cases/server/client/user_actions/get.ts b/x-pack/plugins/cases/server/client/user_actions/get.ts index 3b1addfe7c6c51..63711419ad3b99 100644 --- a/x-pack/plugins/cases/server/client/user_actions/get.ts +++ b/x-pack/plugins/cases/server/client/user_actions/get.ts @@ -11,7 +11,7 @@ import { CaseUserActionsResponseRt } from '../../../common/api'; import { createCaseError } from '../../common/error'; import type { CasesClientArgs } from '..'; import { Operations } from '../../authorization'; -import type { UserActionGet } from './client'; +import type { UserActionGet } from './types'; export const get = async ( { caseId }: UserActionGet, diff --git a/x-pack/plugins/cases/server/client/user_actions/types.ts b/x-pack/plugins/cases/server/client/user_actions/types.ts new file mode 100644 index 00000000000000..a974c5136047c6 --- /dev/null +++ b/x-pack/plugins/cases/server/client/user_actions/types.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/** + * Parameters for retrieving user actions for a particular case + */ +export interface UserActionGet { + /** + * The ID of the case + */ + caseId: string; +} + +export type GetConnectorsRequest = UserActionGet; diff --git a/x-pack/plugins/cases/server/common/models/case_with_comments.ts b/x-pack/plugins/cases/server/common/models/case_with_comments.ts index 1cc40b48d51e60..62d6b44b613f83 100644 --- a/x-pack/plugins/cases/server/common/models/case_with_comments.ts +++ b/x-pack/plugins/cases/server/common/models/case_with_comments.ts @@ -182,7 +182,7 @@ export class CaseCommentModel { ) { const { id, version, ...queryRestAttributes } = updateRequest; - await this.params.services.userActionService.createUserAction({ + await this.params.services.userActionService.creator.createUserAction({ type: ActionTypes.comment, action: Actions.update, caseId: this.caseInfo.id, @@ -335,7 +335,7 @@ export class CaseCommentModel { comment: SavedObject, req: CommentRequest ) { - await this.params.services.userActionService.createUserAction({ + await this.params.services.userActionService.creator.createUserAction({ type: ActionTypes.comment, action: Actions.create, caseId: this.caseInfo.id, @@ -349,7 +349,7 @@ export class CaseCommentModel { } private async bulkCreateCommentUserAction(attachments: Array<{ id: string } & CommentRequest>) { - await this.params.services.userActionService.bulkCreateAttachmentCreation({ + await this.params.services.userActionService.creator.bulkCreateAttachmentCreation({ caseId: this.caseInfo.id, attachments: attachments.map(({ id, ...attachment }) => ({ id, diff --git a/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts b/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts index 096a57af6b8ca8..ca1f44706caf99 100644 --- a/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts +++ b/x-pack/plugins/cases/server/routes/api/get_internal_routes.ts @@ -6,6 +6,7 @@ */ import type { UserProfileService } from '../../services'; +import { getConnectorsRoute } from './internal/get_connectors'; import { bulkCreateAttachmentsRoute } from './internal/bulk_create_attachments'; import { bulkGetCasesRoute } from './internal/bulk_get_cases'; import { suggestUserProfilesRoute } from './internal/suggest_user_profiles'; @@ -15,5 +16,6 @@ export const getInternalRoutes = (userProfileService: UserProfileService) => [ bulkCreateAttachmentsRoute, suggestUserProfilesRoute(userProfileService), + getConnectorsRoute, bulkGetCasesRoute, ] as CaseRoute[]; diff --git a/x-pack/plugins/cases/server/routes/api/internal/get_connectors.ts b/x-pack/plugins/cases/server/routes/api/internal/get_connectors.ts new file mode 100644 index 00000000000000..ac48e17461fada --- /dev/null +++ b/x-pack/plugins/cases/server/routes/api/internal/get_connectors.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; +import { INTERNAL_CONNECTORS_URL } from '../../../../common/constants'; +import { createCaseError } from '../../../common/error'; +import { createCasesRoute } from '../create_cases_route'; + +export const getConnectorsRoute = createCasesRoute({ + method: 'get', + path: INTERNAL_CONNECTORS_URL, + params: { + params: schema.object({ + case_id: schema.string(), + }), + }, + handler: async ({ context, request, response }) => { + try { + const casesContext = await context.cases; + const casesClient = await casesContext.getCasesClient(); + const caseId = request.params.case_id; + + return response.ok({ + body: await casesClient.userActions.getConnectors({ caseId }), + }); + } catch (error) { + throw createCaseError({ + message: `Failed to retrieve connectors in route case id: ${request.params.case_id}: ${error}`, + error, + }); + } + }, +}); diff --git a/x-pack/plugins/cases/server/saved_object_types/user_actions.ts b/x-pack/plugins/cases/server/saved_object_types/user_actions.ts index 1862e180acc227..3060ca219ca427 100644 --- a/x-pack/plugins/cases/server/saved_object_types/user_actions.ts +++ b/x-pack/plugins/cases/server/saved_object_types/user_actions.ts @@ -50,6 +50,16 @@ export const createCaseUserActionSavedObjectType = ( type: { type: 'keyword' }, }, }, + comment: { + properties: { + // comment.type + type: { type: 'keyword' }, + // comment.externalReferenceAttachmentTypeId + externalReferenceAttachmentTypeId: { type: 'keyword' }, + // comment.persistableStateAttachmentTypeId + persistableStateAttachmentTypeId: { type: 'keyword' }, + }, + }, }, }, owner: { diff --git a/x-pack/plugins/cases/server/services/mocks.ts b/x-pack/plugins/cases/server/services/mocks.ts index 125fbc7ec96501..11ce2711bbbaef 100644 --- a/x-pack/plugins/cases/server/services/mocks.ts +++ b/x-pack/plugins/cases/server/services/mocks.ts @@ -16,11 +16,13 @@ import type { } from '.'; import type { LicensingService } from './licensing'; import type { EmailNotificationService } from './notifications/email_notification_service'; +import type { UserActionPersister } from './user_actions/operations/create'; export type CaseServiceMock = jest.Mocked; export type CaseConfigureServiceMock = jest.Mocked; export type ConnectorMappingsServiceMock = jest.Mocked; export type CaseUserActionServiceMock = jest.Mocked; +export type CaseUserActionPersisterServiceMock = jest.Mocked; export type AlertServiceMock = jest.Mocked; export type AttachmentServiceMock = jest.Mocked; export type LicensingServiceMock = jest.Mocked; @@ -73,13 +75,28 @@ export const connectorMappingsServiceMock = (): ConnectorMappingsServiceMock => return service as unknown as ConnectorMappingsServiceMock; }; -export const createUserActionServiceMock = (): CaseUserActionServiceMock => { - const service: PublicMethodsOf = { +const createUserActionPersisterServiceMock = (): CaseUserActionPersisterServiceMock => { + const service: PublicMethodsOf = { bulkAuditLogCaseDeletion: jest.fn(), bulkCreateUpdateCase: jest.fn(), bulkCreateAttachmentDeletion: jest.fn(), bulkCreateAttachmentCreation: jest.fn(), createUserAction: jest.fn(), + }; + + return service as unknown as CaseUserActionPersisterServiceMock; +}; + +type FakeUserActionService = PublicMethodsOf & { + creator: CaseUserActionPersisterServiceMock; +}; + +export const createUserActionServiceMock = (): CaseUserActionServiceMock => { + const service: FakeUserActionService = { + creator: createUserActionPersisterServiceMock(), + getConnectorFieldsBeforeLatestPush: jest.fn(), + getMostRecentUserAction: jest.fn(), + getCaseConnectorInformation: jest.fn(), getAll: jest.fn(), findStatusChanges: jest.fn(), getUniqueConnectors: jest.fn(), diff --git a/x-pack/plugins/cases/server/services/user_actions/index.test.ts b/x-pack/plugins/cases/server/services/user_actions/index.test.ts index e2aa6192cdccfc..f5fefebfc41b76 100644 --- a/x-pack/plugins/cases/server/services/user_actions/index.test.ts +++ b/x-pack/plugins/cases/server/services/user_actions/index.test.ts @@ -64,6 +64,7 @@ import { createPersistableStateAttachmentTypeRegistryMock, persistableStateAttachment, } from '../../attachment_framework/mocks'; +import { serializerMock } from '@kbn/core-saved-objects-base-server-mocks'; const createConnectorUserAction = ( overrides?: Partial @@ -661,6 +662,8 @@ describe('CaseUserActionService', () => { }; const mockAuditLogger = auditLoggerMock.create(); + const soSerializerMock = serializerMock.create(); + beforeEach(() => { jest.clearAllMocks(); service = new CaseUserActionService({ @@ -668,13 +671,14 @@ describe('CaseUserActionService', () => { log: mockLogger, persistableStateAttachmentTypeRegistry, auditLogger: mockAuditLogger, + savedObjectsSerializer: soSerializerMock, }); }); describe('createUserAction', () => { describe('create case', () => { it('creates a create case user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: casePayload, type: ActionTypes.create_case, @@ -726,7 +730,7 @@ describe('CaseUserActionService', () => { }); it('logs a create case user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: casePayload, type: ActionTypes.create_case, @@ -760,7 +764,7 @@ describe('CaseUserActionService', () => { describe('status', () => { it('creates an update status user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { status: CaseStatuses.closed }, type: ActionTypes.status, @@ -785,7 +789,7 @@ describe('CaseUserActionService', () => { }); it('logs an update status user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { status: CaseStatuses.closed }, type: ActionTypes.status, @@ -820,7 +824,7 @@ describe('CaseUserActionService', () => { describe('severity', () => { it('creates an update severity user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { severity: CaseSeverity.MEDIUM }, type: ActionTypes.severity, @@ -845,7 +849,7 @@ describe('CaseUserActionService', () => { }); it('logs an update severity user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { severity: CaseSeverity.MEDIUM }, type: ActionTypes.severity, @@ -880,7 +884,7 @@ describe('CaseUserActionService', () => { describe('push', () => { it('creates a push user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { externalService }, type: ActionTypes.pushed, @@ -924,7 +928,7 @@ describe('CaseUserActionService', () => { }); it('logs a push user action', async () => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, payload: { externalService }, type: ActionTypes.pushed, @@ -961,7 +965,7 @@ describe('CaseUserActionService', () => { it.each([[Actions.create], [Actions.delete], [Actions.update]])( 'creates a comment user action of action: %s', async (action) => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, type: ActionTypes.comment, action, @@ -1002,7 +1006,7 @@ describe('CaseUserActionService', () => { it.each([[Actions.create], [Actions.delete], [Actions.update]])( 'logs a comment user action of action: %s', async (action) => { - await service.createUserAction({ + await service.creator.createUserAction({ ...commonArgs, type: ActionTypes.comment, action, @@ -1020,7 +1024,7 @@ describe('CaseUserActionService', () => { describe('bulkAuditLogCaseDeletion', () => { it('logs a delete case audit log message', async () => { - await service.bulkAuditLogCaseDeletion(['1', '2']); + await service.creator.bulkAuditLogCaseDeletion(['1', '2']); expect(unsecuredSavedObjectsClient.bulkCreate).not.toHaveBeenCalled(); @@ -1076,7 +1080,7 @@ describe('CaseUserActionService', () => { describe('bulkCreateUpdateCase', () => { it('creates the correct user actions when bulk updating cases', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases, @@ -1244,7 +1248,7 @@ describe('CaseUserActionService', () => { }); it('logs the correct user actions when bulk updating cases', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases, @@ -1427,7 +1431,7 @@ describe('CaseUserActionService', () => { }); it('creates the correct user actions when an assignee is added', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedAssigneesCases, @@ -1474,7 +1478,7 @@ describe('CaseUserActionService', () => { }); it('logs the correct user actions when an assignee is added', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedAssigneesCases, @@ -1520,7 +1524,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: casesWithAssigneeRemoved, @@ -1577,7 +1581,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: casesWithAssigneeRemoved, @@ -1623,7 +1627,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: caseAssignees, @@ -1708,7 +1712,7 @@ describe('CaseUserActionService', () => { }, ]; - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases: originalCasesWithAssignee, updatedCases: caseAssignees, @@ -1765,7 +1769,7 @@ describe('CaseUserActionService', () => { }); it('creates the correct user actions when tags are added and removed', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedTagsCases, @@ -1837,7 +1841,7 @@ describe('CaseUserActionService', () => { }); it('logs the correct user actions when tags are added and removed', async () => { - await service.bulkCreateUpdateCase({ + await service.creator.bulkCreateUpdateCase({ ...commonArgs, originalCases, updatedCases: updatedTagsCases, @@ -1896,7 +1900,7 @@ describe('CaseUserActionService', () => { describe('bulkCreateAttachmentDeletion', () => { it('creates delete comment user action', async () => { - await service.bulkCreateAttachmentDeletion({ + await service.creator.bulkCreateAttachmentDeletion({ ...commonArgs, attachments, }); @@ -1956,7 +1960,7 @@ describe('CaseUserActionService', () => { }); it('logs delete comment user action', async () => { - await service.bulkCreateAttachmentDeletion({ + await service.creator.bulkCreateAttachmentDeletion({ ...commonArgs, attachments, }); diff --git a/x-pack/plugins/cases/server/services/user_actions/index.ts b/x-pack/plugins/cases/server/services/user_actions/index.ts index 9cf0095019c970..31060ebb86d28d 100644 --- a/x-pack/plugins/cases/server/services/user_actions/index.ts +++ b/x-pack/plugins/cases/server/services/user_actions/index.ts @@ -5,40 +5,26 @@ * 2.0. */ -import { get, isEmpty } from 'lodash'; - import type { - Logger, SavedObject, SavedObjectReference, - SavedObjectsBulkResponse, - SavedObjectsClientContract, SavedObjectsFindResponse, - SavedObjectsUpdateResponse, + SavedObjectsRawDoc, } from '@kbn/core/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { KueryNode } from '@kbn/es-query'; -import type { AuditLogger } from '@kbn/security-plugin/server'; import { isCommentRequestTypePersistableState } from '../../../common/utils/attachments'; import { isConnectorUserAction, isPushedUserAction, - isUserActionType, isCreateCaseUserAction, isCommentUserAction, } from '../../../common/utils/user_actions'; import type { - ActionTypeValues, - CaseAttributes, CaseUserActionAttributes, CaseUserActionAttributesWithoutConnectorId, CaseUserActionResponse, - CaseUserProfile, - CaseAssignees, - CommentRequest, - User, - UserAction as Action, } from '../../../common/api'; import { Actions, ActionTypes, NONE_CONNECTOR_ID } from '../../../common/api'; import { @@ -55,364 +41,466 @@ import { PUSH_CONNECTOR_ID_REFERENCE_NAME, } from '../../common/constants'; import { findConnectorIdReference } from '../transform'; -import { buildFilter, combineFilters, arraysDifference } from '../../client/utils'; -import type { - Attributes, - BuilderParameters, - CommonArguments, - CreateUserAction, - UserActionEvent, - UserActionParameters, -} from './types'; -import { BuilderFactory } from './builder_factory'; +import { buildFilter, combineFilters } from '../../client/utils'; +import type { CaseConnectorActivity, CaseConnectorFields, PushInfo, ServiceContext } from './types'; import { defaultSortField, isCommentRequestTypeExternalReferenceSO } from '../../common/utils'; import type { PersistableStateAttachmentTypeRegistry } from '../../attachment_framework/persistable_state_registry'; import { injectPersistableReferencesToSO } from '../../attachment_framework/so_references'; -import type { IndexRefresh } from '../types'; -import { isAssigneesArray, isStringArray } from './type_guards'; -import type { CaseSavedObject } from '../../common/types'; -import { UserActionAuditLogger } from './audit_logger'; +import { UserActionPersister } from './operations/create'; export interface UserActionItem { attributes: CaseUserActionAttributesWithoutConnectorId; references: SavedObjectReference[]; } -interface PostCaseUserActionArgs extends IndexRefresh { - actions: UserActionEvent[]; +interface MostRecentResults { + mostRecent: { + hits: { + total: number; + hits: SavedObjectsRawDoc[]; + }; + }; } -interface CreateUserActionES extends IndexRefresh { - attributes: T; - references: SavedObjectReference[]; +interface ConnectorActivityAggsResult { + references: { + connectors: { + ids: { + buckets: Array<{ + key: string; + reverse: { + connectorActivity: { + buckets: { + changeConnector: MostRecentResults; + createCase: MostRecentResults; + pushInfo: MostRecentResults; + }; + }; + }; + }>; + }; + }; + }; } -type CommonUserActionArgs = CommonArguments; - -interface GetUserActionItemByDifference extends CommonUserActionArgs { - field: string; - originalValue: unknown; - newValue: unknown; +interface ConnectorFieldsBeforePushAggsResult { + references: { + connectors: { + reverse: { + ids: { + buckets: Record; + }; + }; + }; + }; } -interface TypedUserActionDiffedItems extends GetUserActionItemByDifference { - originalValue: T[]; - newValue: T[]; -} +export class CaseUserActionService { + private readonly _creator: UserActionPersister; -interface BulkCreateBulkUpdateCaseUserActions extends IndexRefresh { - originalCases: CaseSavedObject[]; - updatedCases: Array>; - user: User; -} + constructor(private readonly context: ServiceContext) { + this._creator = new UserActionPersister(context); + } -interface BulkCreateAttachmentUserAction extends Omit, IndexRefresh { - attachments: Array<{ id: string; owner: string; attachment: CommentRequest }>; -} + public get creator() { + return this._creator; + } -type CreateUserActionClient = CreateUserAction & - CommonUserActionArgs & - IndexRefresh; + public async getConnectorFieldsBeforeLatestPush( + caseId: string, + pushes: PushInfo[] + ): Promise { + try { + this.context.log.debug( + `Attempting to retrieve the connector fields before the last push for case id: ${caseId}` + ); -type CreatePayloadFunction = ( - items: Item[] -) => UserActionParameters['payload']; + if (pushes.length <= 0) { + return new Map(); + } -export class CaseUserActionService { - private static readonly userActionFieldsAllowed: Set = new Set(Object.keys(ActionTypes)); - - private readonly unsecuredSavedObjectsClient: SavedObjectsClientContract; - private readonly builderFactory: BuilderFactory; - private readonly persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; - private readonly log: Logger; - private readonly auditLogger: UserActionAuditLogger; - - constructor({ - log, - persistableStateAttachmentTypeRegistry, - unsecuredSavedObjectsClient, - auditLogger, - }: { - log: Logger; - persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; - unsecuredSavedObjectsClient: SavedObjectsClientContract; - auditLogger: AuditLogger; - }) { - this.log = log; - this.unsecuredSavedObjectsClient = unsecuredSavedObjectsClient; - this.persistableStateAttachmentTypeRegistry = persistableStateAttachmentTypeRegistry; - - this.builderFactory = new BuilderFactory({ - persistableStateAttachmentTypeRegistry: this.persistableStateAttachmentTypeRegistry, - }); - - this.auditLogger = new UserActionAuditLogger(auditLogger); - } + const connectorsFilter = buildFilter({ + filters: [ActionTypes.connector, ActionTypes.create_case], + field: 'type', + operator: 'or', + type: CASE_USER_ACTION_SAVED_OBJECT, + }); - private getUserActionItemByDifference(params: GetUserActionItemByDifference): UserActionEvent[] { - const { field, originalValue, newValue, caseId, owner, user } = params; - - if (!CaseUserActionService.userActionFieldsAllowed.has(field)) { - return []; - } else if ( - field === ActionTypes.assignees && - isAssigneesArray(originalValue) && - isAssigneesArray(newValue) - ) { - return this.buildAssigneesUserActions({ ...params, originalValue, newValue }); - } else if ( - field === ActionTypes.tags && - isStringArray(originalValue) && - isStringArray(newValue) - ) { - return this.buildTagsUserActions({ ...params, originalValue, newValue }); - } else if (isUserActionType(field) && newValue != null) { - const userActionBuilder = this.builderFactory.getBuilder(ActionTypes[field]); - const fieldUserAction = userActionBuilder?.build({ - caseId, - owner, - user, - payload: { [field]: newValue }, + const response = await this.context.unsecuredSavedObjectsClient.find< + CaseUserActionAttributesWithoutConnectorId, + ConnectorFieldsBeforePushAggsResult + >({ + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, + page: 1, + perPage: 1, + sortField: defaultSortField, + aggs: CaseUserActionService.buildConnectorFieldsUsedInPushAggs(pushes), + filter: connectorsFilter, }); - return fieldUserAction ? [fieldUserAction] : []; + return this.createCaseConnectorFieldsUsedInPushes(response.aggregations); + } catch (error) { + this.context.log.error( + `Error while retrieving the connector fields before the last push: ${caseId}: ${error}` + ); + throw error; } - - return []; } - private buildAssigneesUserActions(params: TypedUserActionDiffedItems) { - const createPayload: CreatePayloadFunction = ( - items: CaseAssignees - ) => ({ assignees: items }); - - return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.assignees); - } + private static buildConnectorFieldsUsedInPushAggs( + pushes: PushInfo[] + ): Record { + const filters: estypes.AggregationsBuckets = {}; - private buildTagsUserActions(params: TypedUserActionDiffedItems) { - const createPayload: CreatePayloadFunction = ( - items: string[] - ) => ({ - tags: items, - }); + /** + * Group the user actions by the unique connector ids and bound the time range + * for that connector's push event. We want to search for the fields before the push timestamp. + */ + for (const push of pushes) { + filters[push.connectorId] = { + bool: { + filter: [ + { + // Search for connector field user action prior to the push occurrence + range: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.created_at`]: { + lt: push.date.toISOString(), + }, + }, + }, + { + nested: { + path: `${CASE_USER_ACTION_SAVED_OBJECT}.references`, + query: { + bool: { + filter: [ + { + // We only want to search a time frame for a specific connector id + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.references.id`]: { + value: push.connectorId, + }, + }, + }, + ], + }, + }, + }, + }, + ], + }, + }; + } - return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.tags); + return { + references: { + nested: { + path: `${CASE_USER_ACTION_SAVED_OBJECT}.references`, + }, + aggregations: { + connectors: { + filter: { + // Only search for user actions that have a connector reference aka a reference with type action + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.references.type`]: 'action', + }, + }, + aggregations: { + reverse: { + reverse_nested: {}, + aggregations: { + ids: { + filters: { + filters, + }, + aggregations: { + mostRecent: { + top_hits: { + sort: [ + { + [`${CASE_USER_ACTION_SAVED_OBJECT}.created_at`]: { + order: 'desc', + }, + }, + ], + size: 1, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }; } - private buildAddDeleteUserActions( - params: TypedUserActionDiffedItems, - createPayload: CreatePayloadFunction, - actionType: ActionType - ) { - const { originalValue, newValue } = params; - const compareValues = arraysDifference(originalValue, newValue); - - const addUserAction = this.buildUserAction({ - commonArgs: params, - actionType, - action: Actions.add, - createPayload, - modifiedItems: compareValues?.addedItems, - }); - const deleteUserAction = this.buildUserAction({ - commonArgs: params, - actionType, - action: Actions.delete, - createPayload, - modifiedItems: compareValues?.deletedItems, - }); - - return [ - ...(addUserAction ? [addUserAction] : []), - ...(deleteUserAction ? [deleteUserAction] : []), - ]; - } + private createCaseConnectorFieldsUsedInPushes( + aggsResults?: ConnectorFieldsBeforePushAggsResult + ): CaseConnectorFields { + const connectorFields: CaseConnectorFields = new Map(); - private buildUserAction({ - commonArgs, - actionType, - action, - createPayload, - modifiedItems, - }: { - commonArgs: CommonUserActionArgs; - actionType: ActionType; - action: Action; - createPayload: CreatePayloadFunction; - modifiedItems?: Item[] | null; - }) { - const userActionBuilder = this.builderFactory.getBuilder(actionType); - - if (!userActionBuilder || !modifiedItems || modifiedItems.length <= 0) { - return; + if (!aggsResults) { + return connectorFields; } - const { caseId, owner, user } = commonArgs; + for (const connectorId of Object.keys(aggsResults.references.connectors.reverse.ids.buckets)) { + const fields = aggsResults.references.connectors.reverse.ids.buckets[connectorId]; + + if (fields.mostRecent.hits.hits.length > 0) { + const rawFieldsDoc = fields.mostRecent.hits.hits[0]; + const doc = + this.context.savedObjectsSerializer.rawToSavedObject( + rawFieldsDoc + ); + + const fieldsDoc = transformToExternalModel( + doc, + this.context.persistableStateAttachmentTypeRegistry + ); - const userAction = userActionBuilder.build({ - action, - caseId, - user, - owner, - payload: createPayload(modifiedItems), - }); + connectorFields.set(connectorId, fieldsDoc); + } + } - return userAction; + return connectorFields; } - public async bulkAuditLogCaseDeletion(caseIds: string[]) { - this.log.debug(`Attempting to log bulk case deletion`); + public async getMostRecentUserAction( + caseId: string + ): Promise | undefined> { + try { + this.context.log.debug( + `Attempting to retrieve the most recent user action for case id: ${caseId}` + ); + + const id = caseId; + const type = CASE_SAVED_OBJECT; - for (const id of caseIds) { - this.auditLogger.log({ - getMessage: () => `User deleted case id: ${id}`, - action: Actions.delete, - descriptiveAction: 'case_user_action_delete_case', - savedObjectId: id, - savedObjectType: CASE_SAVED_OBJECT, + const connectorsFilter = buildFilter({ + filters: [ + ActionTypes.comment, + ActionTypes.description, + ActionTypes.tags, + ActionTypes.title, + ], + field: 'type', + operator: 'or', + type: CASE_USER_ACTION_SAVED_OBJECT, }); + + const userActions = + await this.context.unsecuredSavedObjectsClient.find( + { + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type, id }, + page: 1, + perPage: 1, + sortField: 'created_at', + sortOrder: 'desc', + filter: connectorsFilter, + } + ); + + if (userActions.saved_objects.length <= 0) { + return; + } + + return transformToExternalModel( + userActions.saved_objects[0], + this.context.persistableStateAttachmentTypeRegistry + ); + } catch (error) { + this.context.log.error( + `Error while retrieving the most recent user action for case id: ${caseId}: ${error}` + ); + throw error; } } - public async bulkCreateUpdateCase({ - originalCases, - updatedCases, - user, - refresh, - }: BulkCreateBulkUpdateCaseUserActions): Promise { - const builtUserActions = updatedCases.reduce((acc, updatedCase) => { - const originalCase = originalCases.find(({ id }) => id === updatedCase.id); - - if (originalCase == null) { - return acc; - } + public async getCaseConnectorInformation(caseId: string): Promise { + try { + this.context.log.debug(`Attempting to find connector information for case id: ${caseId}`); - const caseId = updatedCase.id; - const owner = originalCase.attributes.owner; - - const userActions: UserActionEvent[] = []; - const updatedFields = Object.keys(updatedCase.attributes); - - updatedFields - .filter((field) => CaseUserActionService.userActionFieldsAllowed.has(field)) - .forEach((field) => { - const originalValue = get(originalCase, ['attributes', field]); - const newValue = get(updatedCase, ['attributes', field]); - userActions.push( - ...this.getUserActionItemByDifference({ - field, - originalValue, - newValue, - user, - owner, - caseId, - }) - ); - }); + const connectorsFilter = buildFilter({ + filters: [ActionTypes.connector, ActionTypes.create_case, ActionTypes.pushed], + field: 'type', + operator: 'or', + type: CASE_USER_ACTION_SAVED_OBJECT, + }); - return [...acc, ...userActions]; - }, []); + const response = await this.context.unsecuredSavedObjectsClient.find< + CaseUserActionAttributesWithoutConnectorId, + ConnectorActivityAggsResult + >({ + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, + page: 1, + perPage: 1, + sortField: defaultSortField, + aggs: CaseUserActionService.buildConnectorInfoAggs(), + filter: connectorsFilter, + }); - await this.bulkCreateAndLog({ - userActions: builtUserActions, - refresh, - }); + return this.createCaseConnectorInformation(response.aggregations); + } catch (error) { + this.context.log.error( + `Error while retrieving the connector information for case id: ${caseId} ${error}` + ); + throw error; + } } - private async bulkCreateAttachment({ - caseId, - attachments, - user, - action = Actions.create, - refresh, - }: BulkCreateAttachmentUserAction): Promise { - this.log.debug(`Attempting to create a bulk create case user action`); - const userActions = attachments.reduce((acc, attachment) => { - const userActionBuilder = this.builderFactory.getBuilder(ActionTypes.comment); - const commentUserAction = userActionBuilder?.build({ - action, - caseId, - user, - owner: attachment.owner, - attachmentId: attachment.id, - payload: { attachment: attachment.attachment }, - }); + private createCaseConnectorInformation( + aggsResults?: ConnectorActivityAggsResult + ): CaseConnectorActivity[] { + const caseConnectorInfo: CaseConnectorActivity[] = []; - if (commentUserAction == null) { - return acc; + if (!aggsResults) { + return caseConnectorInfo; + } + + for (const connectorInfo of aggsResults.references.connectors.ids.buckets) { + const changeConnector = connectorInfo.reverse.connectorActivity.buckets.changeConnector; + const createCase = connectorInfo.reverse.connectorActivity.buckets.createCase; + let rawFieldsDoc: SavedObjectsRawDoc | undefined; + + if (changeConnector.mostRecent.hits.hits.length > 0) { + rawFieldsDoc = changeConnector.mostRecent.hits.hits[0]; + } else if (createCase.mostRecent.hits.hits.length > 0) { + /** + * If there is ever a connector update user action that takes precedence over the information stored + * in the create case user action because it indicates that the connector's fields were changed + */ + rawFieldsDoc = createCase.mostRecent.hits.hits[0]; } - return [...acc, commentUserAction]; - }, []); + let fieldsDoc: SavedObject | undefined; + if (rawFieldsDoc != null) { + const doc = + this.context.savedObjectsSerializer.rawToSavedObject( + rawFieldsDoc + ); + + fieldsDoc = transformToExternalModel( + doc, + this.context.persistableStateAttachmentTypeRegistry + ); + } - await this.bulkCreateAndLog({ - userActions, - refresh, - }); - } + const pushInfo = connectorInfo.reverse.connectorActivity.buckets.pushInfo; + let pushDoc: SavedObject | undefined; - public async bulkCreateAttachmentDeletion({ - caseId, - attachments, - user, - refresh, - }: BulkCreateAttachmentUserAction): Promise { - await this.bulkCreateAttachment({ - caseId, - attachments, - user, - action: Actions.delete, - refresh, - }); - } + if (pushInfo.mostRecent.hits.hits.length > 0) { + const rawPushDoc = pushInfo.mostRecent.hits.hits[0]; - public async bulkCreateAttachmentCreation({ - caseId, - attachments, - user, - refresh, - }: BulkCreateAttachmentUserAction): Promise { - await this.bulkCreateAttachment({ - caseId, - attachments, - user, - action: Actions.create, - refresh, - }); - } + const doc = + this.context.savedObjectsSerializer.rawToSavedObject( + rawPushDoc + ); - public async createUserAction({ - action, - type, - caseId, - user, - owner, - payload, - connectorId, - attachmentId, - refresh, - }: CreateUserActionClient) { - try { - this.log.debug(`Attempting to create a user action of type: ${type}`); - const userActionBuilder = this.builderFactory.getBuilder(type); - - const userAction = userActionBuilder?.build({ - action, - caseId, - user, - owner, - connectorId, - attachmentId, - payload, - }); + pushDoc = transformToExternalModel( + doc, + this.context.persistableStateAttachmentTypeRegistry + ); + } - if (userAction) { - await this.createAndLog({ userAction, refresh }); + if (fieldsDoc != null) { + caseConnectorInfo.push({ + connectorId: connectorInfo.key, + fields: fieldsDoc, + push: pushDoc, + }); + } else { + this.context.log.warn(`Unable to find fields for connector id: ${connectorInfo.key}`); } - } catch (error) { - this.log.error(`Error on creating user action of type: ${type}. Error: ${error}`); - throw error; } + + return caseConnectorInfo; + } + + private static buildConnectorInfoAggs(): Record< + string, + estypes.AggregationsAggregationContainer + > { + return { + references: { + nested: { + path: `${CASE_USER_ACTION_SAVED_OBJECT}.references`, + }, + aggregations: { + connectors: { + filter: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.references.type`]: 'action', + }, + }, + aggregations: { + ids: { + // Bucket by connector id + terms: { + field: `${CASE_USER_ACTION_SAVED_OBJECT}.references.id`, + // We're assuming that a case will not have more than 1000 connectors + size: 1000, + }, + aggregations: { + reverse: { + reverse_nested: {}, + aggregations: { + connectorActivity: { + filters: { + filters: { + // look for connector fields user actions from "change connector" occurrence + changeConnector: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.attributes.type`]: + ActionTypes.connector, + }, + }, + // If the case was initialized with a connector, the fields could exist in the create_case + // user action + createCase: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.attributes.type`]: + ActionTypes.create_case, + }, + }, + // Also grab the most recent push occurrence for the connector + pushInfo: { + term: { + [`${CASE_USER_ACTION_SAVED_OBJECT}.attributes.type`]: + ActionTypes.pushed, + }, + }, + }, + }, + aggregations: { + mostRecent: { + top_hits: { + sort: [ + { + [`${CASE_USER_ACTION_SAVED_OBJECT}.created_at`]: { + order: 'desc', + }, + }, + ], + size: 1, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }; } public async getAll(caseId: string): Promise> { @@ -421,30 +509,34 @@ export class CaseUserActionService { const type = CASE_SAVED_OBJECT; const userActions = - await this.unsecuredSavedObjectsClient.find({ - type: CASE_USER_ACTION_SAVED_OBJECT, - hasReference: { type, id }, - page: 1, - perPage: MAX_DOCS_PER_PAGE, - sortField: 'created_at', - sortOrder: 'asc', - }); + await this.context.unsecuredSavedObjectsClient.find( + { + type: CASE_USER_ACTION_SAVED_OBJECT, + hasReference: { type, id }, + page: 1, + perPage: MAX_DOCS_PER_PAGE, + sortField: 'created_at', + sortOrder: 'asc', + } + ); return transformFindResponseToExternalModel( userActions, - this.persistableStateAttachmentTypeRegistry + this.context.persistableStateAttachmentTypeRegistry ); } catch (error) { - this.log.error(`Error on GET case user action case id: ${caseId}: ${error}`); + this.context.log.error(`Error on GET case user action case id: ${caseId}: ${error}`); throw error; } } public async getUserActionIdsForCases(caseIds: string[]) { try { - this.log.debug(`Attempting to retrieve user actions associated with cases: [${caseIds}]`); + this.context.log.debug( + `Attempting to retrieve user actions associated with cases: [${caseIds}]` + ); - const finder = this.unsecuredSavedObjectsClient.createPointInTimeFinder({ + const finder = this.context.unsecuredSavedObjectsClient.createPointInTimeFinder({ type: CASE_USER_ACTION_SAVED_OBJECT, hasReference: caseIds.map((id) => ({ id, type: CASE_SAVED_OBJECT })), sortField: 'created_at', @@ -465,78 +557,7 @@ export class CaseUserActionService { return ids; } catch (error) { - this.log.error(`Error retrieving user action ids for cases: [${caseIds}]: ${error}`); - throw error; - } - } - - private async createAndLog({ - userAction, - refresh, - }: { - userAction: UserActionEvent; - } & IndexRefresh): Promise { - const createdUserAction = await this.create({ ...userAction.parameters, refresh }); - this.auditLogger.log(userAction.eventDetails, createdUserAction.id); - } - - private async create({ - attributes, - references, - refresh, - }: CreateUserActionES): Promise> { - try { - this.log.debug(`Attempting to POST a new case user action`); - - return await this.unsecuredSavedObjectsClient.create( - CASE_USER_ACTION_SAVED_OBJECT, - attributes, - { - references: references ?? [], - refresh, - } - ); - } catch (error) { - this.log.error(`Error on POST a new case user action: ${error}`); - throw error; - } - } - - private async bulkCreateAndLog({ - userActions, - refresh, - }: { userActions: UserActionEvent[] } & IndexRefresh) { - const createdUserActions = await this.bulkCreate({ actions: userActions, refresh }); - - if (!createdUserActions) { - return; - } - - for (let i = 0; i < userActions.length; i++) { - this.auditLogger.log(userActions[i].eventDetails, createdUserActions.saved_objects[i].id); - } - } - - private async bulkCreate({ - actions, - refresh, - }: PostCaseUserActionArgs): Promise | undefined> { - if (isEmpty(actions)) { - return; - } - - try { - this.log.debug(`Attempting to POST a new case user action`); - - return await this.unsecuredSavedObjectsClient.bulkCreate( - actions.map((action) => ({ - type: CASE_USER_ACTION_SAVED_OBJECT, - ...action.parameters, - })), - { refresh } - ); - } catch (error) { - this.log.error(`Error on POST a new case user action: ${error}`); + this.context.log.error(`Error retrieving user action ids for cases: [${caseIds}]: ${error}`); throw error; } } @@ -549,7 +570,7 @@ export class CaseUserActionService { filter?: KueryNode; }): Promise>> { try { - this.log.debug('Attempting to find status changes'); + this.context.log.debug('Attempting to find status changes'); const updateActionFilter = buildFilter({ filters: Actions.update, @@ -568,7 +589,7 @@ export class CaseUserActionService { const combinedFilters = combineFilters([updateActionFilter, statusChangeFilter, filter]); const finder = - this.unsecuredSavedObjectsClient.createPointInTimeFinder( + this.context.unsecuredSavedObjectsClient.createPointInTimeFinder( { type: CASE_USER_ACTION_SAVED_OBJECT, hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, @@ -583,14 +604,14 @@ export class CaseUserActionService { for await (const findResults of finder.find()) { userActions = userActions.concat( findResults.saved_objects.map((so) => - transformToExternalModel(so, this.persistableStateAttachmentTypeRegistry) + transformToExternalModel(so, this.context.persistableStateAttachmentTypeRegistry) ) ); } return userActions; } catch (error) { - this.log.error(`Error finding status changes: ${error}`); + this.context.log.error(`Error finding status changes: ${error}`); throw error; } } @@ -603,7 +624,7 @@ export class CaseUserActionService { filter?: KueryNode; }): Promise> { try { - this.log.debug(`Attempting to count connectors for case id ${caseId}`); + this.context.log.debug(`Attempting to count connectors for case id ${caseId}`); const connectorsFilter = buildFilter({ filters: [ActionTypes.connector, ActionTypes.create_case], field: 'type', @@ -613,7 +634,7 @@ export class CaseUserActionService { const combinedFilter = combineFilters([connectorsFilter, filter]); - const response = await this.unsecuredSavedObjectsClient.find< + const response = await this.context.unsecuredSavedObjectsClient.find< CaseUserActionAttributesWithoutConnectorId, { references: { connectors: { ids: { buckets: Array<{ key: string }> } } } } >({ @@ -632,7 +653,7 @@ export class CaseUserActionService { })) ?? [] ); } catch (error) { - this.log.error(`Error while counting connectors for case id ${caseId}: ${error}`); + this.context.log.error(`Error while counting connectors for case id ${caseId}: ${error}`); throw error; } } diff --git a/x-pack/plugins/cases/server/services/user_actions/operations/create.ts b/x-pack/plugins/cases/server/services/user_actions/operations/create.ts new file mode 100644 index 00000000000000..9160445ec2474a --- /dev/null +++ b/x-pack/plugins/cases/server/services/user_actions/operations/create.ts @@ -0,0 +1,433 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + SavedObject, + SavedObjectReference, + SavedObjectsBulkResponse, + SavedObjectsUpdateResponse, +} from '@kbn/core/server'; +import { get, isEmpty } from 'lodash'; +import { CASE_SAVED_OBJECT, CASE_USER_ACTION_SAVED_OBJECT } from '../../../../common/constants'; +import type { CaseSavedObject } from '../../../common/types'; +import { arraysDifference } from '../../../client/utils'; +import { isUserActionType } from '../../../../common/utils/user_actions'; +import type { + ActionTypeValues, + CaseAssignees, + CaseAttributes, + CaseUserProfile, + CommentRequest, + User, + UserAction as Action, +} from '../../../../common/api'; +import { Actions, ActionTypes } from '../../../../common/api'; +import { BuilderFactory } from '../builder_factory'; +import type { + Attributes, + BuilderParameters, + CommonArguments, + CreateUserAction, + ServiceContext, + UserActionEvent, + UserActionParameters, +} from '../types'; +import { isAssigneesArray, isStringArray } from '../type_guards'; +import type { IndexRefresh } from '../../types'; +import { UserActionAuditLogger } from '../audit_logger'; + +type CommonUserActionArgs = CommonArguments; + +interface GetUserActionItemByDifference extends CommonUserActionArgs { + field: string; + originalValue: unknown; + newValue: unknown; +} + +interface TypedUserActionDiffedItems extends GetUserActionItemByDifference { + originalValue: T[]; + newValue: T[]; +} + +type CreatePayloadFunction = ( + items: Item[] +) => UserActionParameters['payload']; + +interface BulkCreateBulkUpdateCaseUserActions extends IndexRefresh { + originalCases: CaseSavedObject[]; + updatedCases: Array>; + user: User; +} + +interface BulkCreateAttachmentUserAction extends Omit, IndexRefresh { + attachments: Array<{ id: string; owner: string; attachment: CommentRequest }>; +} + +type CreateUserActionClient = CreateUserAction & + CommonUserActionArgs & + IndexRefresh; + +interface CreateUserActionES extends IndexRefresh { + attributes: T; + references: SavedObjectReference[]; +} + +interface PostCaseUserActionArgs extends IndexRefresh { + actions: UserActionEvent[]; +} + +export class UserActionPersister { + private static readonly userActionFieldsAllowed: Set = new Set(Object.keys(ActionTypes)); + + private readonly builderFactory: BuilderFactory; + private readonly auditLogger: UserActionAuditLogger; + + constructor(private readonly context: ServiceContext) { + this.builderFactory = new BuilderFactory({ + persistableStateAttachmentTypeRegistry: this.context.persistableStateAttachmentTypeRegistry, + }); + + this.auditLogger = new UserActionAuditLogger(this.context.auditLogger); + } + + public async bulkCreateUpdateCase({ + originalCases, + updatedCases, + user, + refresh, + }: BulkCreateBulkUpdateCaseUserActions): Promise { + const builtUserActions = updatedCases.reduce((acc, updatedCase) => { + const originalCase = originalCases.find(({ id }) => id === updatedCase.id); + + if (originalCase == null) { + return acc; + } + + const caseId = updatedCase.id; + const owner = originalCase.attributes.owner; + + const userActions: UserActionEvent[] = []; + const updatedFields = Object.keys(updatedCase.attributes); + + updatedFields + .filter((field) => UserActionPersister.userActionFieldsAllowed.has(field)) + .forEach((field) => { + const originalValue = get(originalCase, ['attributes', field]); + const newValue = get(updatedCase, ['attributes', field]); + userActions.push( + ...this.getUserActionItemByDifference({ + field, + originalValue, + newValue, + user, + owner, + caseId, + }) + ); + }); + + return [...acc, ...userActions]; + }, []); + + await this.bulkCreateAndLog({ + userActions: builtUserActions, + refresh, + }); + } + + private getUserActionItemByDifference(params: GetUserActionItemByDifference): UserActionEvent[] { + const { field, originalValue, newValue, caseId, owner, user } = params; + + if (!UserActionPersister.userActionFieldsAllowed.has(field)) { + return []; + } else if ( + field === ActionTypes.assignees && + isAssigneesArray(originalValue) && + isAssigneesArray(newValue) + ) { + return this.buildAssigneesUserActions({ ...params, originalValue, newValue }); + } else if ( + field === ActionTypes.tags && + isStringArray(originalValue) && + isStringArray(newValue) + ) { + return this.buildTagsUserActions({ ...params, originalValue, newValue }); + } else if (isUserActionType(field) && newValue != null) { + const userActionBuilder = this.builderFactory.getBuilder(ActionTypes[field]); + const fieldUserAction = userActionBuilder?.build({ + caseId, + owner, + user, + payload: { [field]: newValue }, + }); + + return fieldUserAction ? [fieldUserAction] : []; + } + + return []; + } + + private buildAssigneesUserActions(params: TypedUserActionDiffedItems) { + const createPayload: CreatePayloadFunction = ( + items: CaseAssignees + ) => ({ assignees: items }); + + return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.assignees); + } + + private buildTagsUserActions(params: TypedUserActionDiffedItems) { + const createPayload: CreatePayloadFunction = ( + items: string[] + ) => ({ + tags: items, + }); + + return this.buildAddDeleteUserActions(params, createPayload, ActionTypes.tags); + } + + private buildAddDeleteUserActions( + params: TypedUserActionDiffedItems, + createPayload: CreatePayloadFunction, + actionType: ActionType + ) { + const { originalValue, newValue } = params; + const compareValues = arraysDifference(originalValue, newValue); + + const addUserAction = this.buildUserAction({ + commonArgs: params, + actionType, + action: Actions.add, + createPayload, + modifiedItems: compareValues?.addedItems, + }); + const deleteUserAction = this.buildUserAction({ + commonArgs: params, + actionType, + action: Actions.delete, + createPayload, + modifiedItems: compareValues?.deletedItems, + }); + + return [ + ...(addUserAction ? [addUserAction] : []), + ...(deleteUserAction ? [deleteUserAction] : []), + ]; + } + + private buildUserAction({ + commonArgs, + actionType, + action, + createPayload, + modifiedItems, + }: { + commonArgs: CommonUserActionArgs; + actionType: ActionType; + action: Action; + createPayload: CreatePayloadFunction; + modifiedItems?: Item[] | null; + }) { + const userActionBuilder = this.builderFactory.getBuilder(actionType); + + if (!userActionBuilder || !modifiedItems || modifiedItems.length <= 0) { + return; + } + + const { caseId, owner, user } = commonArgs; + + const userAction = userActionBuilder.build({ + action, + caseId, + user, + owner, + payload: createPayload(modifiedItems), + }); + + return userAction; + } + + public async bulkCreateAttachmentDeletion({ + caseId, + attachments, + user, + refresh, + }: BulkCreateAttachmentUserAction): Promise { + await this.bulkCreateAttachment({ + caseId, + attachments, + user, + action: Actions.delete, + refresh, + }); + } + + public async bulkCreateAttachmentCreation({ + caseId, + attachments, + user, + refresh, + }: BulkCreateAttachmentUserAction): Promise { + await this.bulkCreateAttachment({ + caseId, + attachments, + user, + action: Actions.create, + refresh, + }); + } + + private async bulkCreateAttachment({ + caseId, + attachments, + user, + action = Actions.create, + refresh, + }: BulkCreateAttachmentUserAction): Promise { + this.context.log.debug(`Attempting to create a bulk create case user action`); + const userActions = attachments.reduce((acc, attachment) => { + const userActionBuilder = this.builderFactory.getBuilder(ActionTypes.comment); + const commentUserAction = userActionBuilder?.build({ + action, + caseId, + user, + owner: attachment.owner, + attachmentId: attachment.id, + payload: { attachment: attachment.attachment }, + }); + + if (commentUserAction == null) { + return acc; + } + + return [...acc, commentUserAction]; + }, []); + + await this.bulkCreateAndLog({ + userActions, + refresh, + }); + } + + private async bulkCreateAndLog({ + userActions, + refresh, + }: { userActions: UserActionEvent[] } & IndexRefresh) { + const createdUserActions = await this.bulkCreate({ actions: userActions, refresh }); + + if (!createdUserActions) { + return; + } + + for (let i = 0; i < userActions.length; i++) { + this.auditLogger.log(userActions[i].eventDetails, createdUserActions.saved_objects[i].id); + } + } + + private async bulkCreate({ + actions, + refresh, + }: PostCaseUserActionArgs): Promise | undefined> { + if (isEmpty(actions)) { + return; + } + + try { + this.context.log.debug(`Attempting to POST a new case user action`); + + return await this.context.unsecuredSavedObjectsClient.bulkCreate( + actions.map((action) => ({ + type: CASE_USER_ACTION_SAVED_OBJECT, + ...action.parameters, + })), + { refresh } + ); + } catch (error) { + this.context.log.error(`Error on POST a new case user action: ${error}`); + throw error; + } + } + + public async createUserAction({ + action, + type, + caseId, + user, + owner, + payload, + connectorId, + attachmentId, + refresh, + }: CreateUserActionClient) { + try { + this.context.log.debug(`Attempting to create a user action of type: ${type}`); + const userActionBuilder = this.builderFactory.getBuilder(type); + + const userAction = userActionBuilder?.build({ + action, + caseId, + user, + owner, + connectorId, + attachmentId, + payload, + }); + + if (userAction) { + await this.createAndLog({ userAction, refresh }); + } + } catch (error) { + this.context.log.error(`Error on creating user action of type: ${type}. Error: ${error}`); + throw error; + } + } + + private async createAndLog({ + userAction, + refresh, + }: { + userAction: UserActionEvent; + } & IndexRefresh): Promise { + const createdUserAction = await this.create({ ...userAction.parameters, refresh }); + this.auditLogger.log(userAction.eventDetails, createdUserAction.id); + } + + private async create({ + attributes, + references, + refresh, + }: CreateUserActionES): Promise> { + try { + this.context.log.debug(`Attempting to POST a new case user action`); + + return await this.context.unsecuredSavedObjectsClient.create( + CASE_USER_ACTION_SAVED_OBJECT, + attributes, + { + references: references ?? [], + refresh, + } + ); + } catch (error) { + this.context.log.error(`Error on POST a new case user action: ${error}`); + throw error; + } + } + + public async bulkAuditLogCaseDeletion(caseIds: string[]) { + this.context.log.debug(`Attempting to log bulk case deletion`); + + for (const id of caseIds) { + this.auditLogger.log({ + getMessage: () => `User deleted case id: ${id}`, + action: Actions.delete, + descriptiveAction: 'case_user_action_delete_case', + savedObjectId: id, + savedObjectType: CASE_SAVED_OBJECT, + }); + } + } +} diff --git a/x-pack/plugins/cases/server/services/user_actions/types.ts b/x-pack/plugins/cases/server/services/user_actions/types.ts index be3fc602c132a4..377a7217cdd025 100644 --- a/x-pack/plugins/cases/server/services/user_actions/types.ts +++ b/x-pack/plugins/cases/server/services/user_actions/types.ts @@ -5,13 +5,21 @@ * 2.0. */ -import type { SavedObjectReference } from '@kbn/core/server'; +import type { + SavedObjectReference, + SavedObjectsClientContract, + Logger, + ISavedObjectsSerializer, + SavedObject, +} from '@kbn/core/server'; +import type { AuditLogger } from '@kbn/security-plugin/server'; import type { CaseAssignees } from '../../../common/api/cases/assignee'; import type { CasePostRequest, CaseSettings, CaseSeverity, CaseStatuses, + CaseUserActionResponse, CommentUserAction, ConnectorUserAction, PushedUserAction, @@ -126,3 +134,24 @@ export type CommonBuilderArguments = CommonArguments & { export interface BuilderDeps { persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; } + +export interface ServiceContext { + log: Logger; + persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry; + unsecuredSavedObjectsClient: SavedObjectsClientContract; + savedObjectsSerializer: ISavedObjectsSerializer; + auditLogger: AuditLogger; +} + +export interface CaseConnectorActivity { + connectorId: string; + fields: SavedObject; + push?: SavedObject; +} + +export type CaseConnectorFields = Map>; + +export interface PushInfo { + date: Date; + connectorId: string; +} diff --git a/x-pack/plugins/cases/tsconfig.json b/x-pack/plugins/cases/tsconfig.json index cb1039e1eff7b5..bb4cc5f9e59c78 100644 --- a/x-pack/plugins/cases/tsconfig.json +++ b/x-pack/plugins/cases/tsconfig.json @@ -52,6 +52,7 @@ "@kbn/safer-lodash-set", "@kbn/logging-mocks", "@kbn/ecs", + "@kbn/core-saved-objects-base-server-mocks", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/cloud_integrations/cloud_data_migration/public/application/components/app.tsx b/x-pack/plugins/cloud_integrations/cloud_data_migration/public/application/components/app.tsx index 013adce3e04c68..d48cb672e05c36 100755 --- a/x-pack/plugins/cloud_integrations/cloud_data_migration/public/application/components/app.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_data_migration/public/application/components/app.tsx @@ -132,7 +132,13 @@ export const CloudDataMigrationApp = ({ http, breadcrumbService }: CloudDataMigr
    - + { +export class CloudDataMigrationPlugin + implements Plugin +{ private breadcrumbService = new BreadcrumbService(); public setup(core: CoreSetup, { cloud, management }: CloudDataMigrationPluginSetup) { @@ -41,8 +44,20 @@ export class CloudDataMigrationPlugin implements Plugin ( - -); +}: CspNoDataPageProps) => { + const { euiTheme } = useEuiTheme(); + return ( + + ); +}; const packageNotInstalledRenderer = ({ kspmIntegrationLink, diff --git a/x-pack/plugins/enterprise_search/common/stats.ts b/x-pack/plugins/enterprise_search/common/stats.ts index f09c124283b152..e324777aeb7c1d 100644 --- a/x-pack/plugins/enterprise_search/common/stats.ts +++ b/x-pack/plugins/enterprise_search/common/stats.ts @@ -8,10 +8,10 @@ export interface SyncJobsStats { connected: number; errors: number; + idle: number; in_progress: number; incomplete: number; orphaned_jobs: number; - stuck: number; } export interface CloudHealth { has_min_connector_memory: boolean; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx index d86cb8592635ab..3d98b684f8dfcb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/curations_table.test.tsx @@ -84,8 +84,8 @@ describe('CurationsTable', () => { expect(tableContent).toContain('mountains, valleys'); expect(tableContent).toContain('Last updated'); - expect(tableContent).toContain('Jan 1, 1970 12:00 PM'); - expect(tableContent).toContain('Jan 2, 1970 12:00 PM'); + expect(tableContent).toContain('Jan 1, 1970 12:00 PM'); + expect(tableContent).toContain('Jan 2, 1970 12:00 PM'); }); it('renders queries with curation links and curation suggestion badges', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.test.ts new file mode 100644 index 00000000000000..d7b322bdcef3f8 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.test.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mockHttpValues } from '../../../__mocks__/kea_logic'; + +import { nextTick } from '@kbn/test-jest-helpers'; + +import { deleteEngine } from './delete_engines_api_logic'; + +describe('deleteEngineApiLogic', () => { + const { http } = mockHttpValues; + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('deleteEngine', () => { + it('calls correct api', async () => { + const promise = Promise.resolve(); + http.post.mockReturnValue(promise); + const result = deleteEngine({ engineName: 'deleteEngineName' }); + await nextTick(); + expect(http.delete).toHaveBeenCalledWith( + '/internal/enterprise_search/engines/deleteEngineName' + ); + await expect(result).resolves; + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.ts new file mode 100644 index 00000000000000..c99e8c641c2db7 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/engines/delete_engines_api_logic.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface DeleteEnginesApiLogicArguments { + engineName: string; +} +export interface DeleteEnginesApiLogicResponse { + engineName: string; +} + +export const deleteEngine = async ({ + engineName, +}: DeleteEnginesApiLogicArguments): Promise => { + const route = `/internal/enterprise_search/engines/${engineName}`; + await HttpLogic.values.http.delete(route); + return { engineName }; +}; +export const DeleteEngineAPILogic = createApiLogic( + ['content', 'delete_engine_api_logic'], + deleteEngine, + { + showSuccessFlashFn: ({ engineName }) => + i18n.translate('xpack.enterpriseSearch.content.engineList.deleteEngine.successToast.title', { + defaultMessage: '{engineName} has been deleted', + values: { + engineName, + }, + }), + } +); + +export type DeleteEnginesApiLogicActions = Actions< + DeleteEnginesApiLogicArguments, + DeleteEnginesApiLogicResponse +>; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawler_domain_detail.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawler_domain_detail.tsx deleted file mode 100644 index 26dd7ad0adf896..00000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawler_domain_detail.tsx +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect } from 'react'; - -import { useParams } from 'react-router-dom'; - -import { useActions, useValues } from 'kea'; - -import { EuiButton, EuiPanel, EuiSpacer } from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; - -import { generateEncodedPath } from '../../../shared/encode_path_params'; -import { EuiButtonTo } from '../../../shared/react_router_helpers'; -import { SEARCH_INDEX_TAB_PATH } from '../../routes'; -import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; -import { CrawlCustomSettingsFlyout } from '../search_index/crawler/crawl_custom_settings_flyout/crawl_custom_settings_flyout'; -import { CrawlerStatusBanner } from '../search_index/crawler/domain_management/crawler_status_banner'; -import { DeleteDomainModal } from '../search_index/crawler/domain_management/delete_domain_modal'; -import { DeleteDomainModalLogic } from '../search_index/crawler/domain_management/delete_domain_modal_logic'; -import { IndexNameLogic } from '../search_index/index_name_logic'; -import { SearchIndexTabId } from '../search_index/search_index'; -import { baseBreadcrumbs } from '../search_indices'; -import { CrawlerStatusIndicator } from '../shared/crawler_status_indicator/crawler_status_indicator'; - -import { AuthenticationPanel } from './authentication_panel/authentication_panel'; -import { CrawlRulesTable } from './crawl_rules_table'; -import { CrawlerDomainDetailLogic } from './crawler_domain_detail_logic'; -import { DeduplicationPanel } from './deduplication_panel/deduplication_panel'; -import { EntryPointsTable } from './entry_points_table'; -import { SitemapsTable } from './sitemaps_table'; - -export const CrawlerDomainDetail: React.FC = () => { - const { domainId } = useParams<{ - domainId: string; - }>(); - - const { indexName } = useValues(IndexNameLogic); - const crawlerDomainDetailLogic = CrawlerDomainDetailLogic({ domainId }); - const { domain, getLoading } = useValues(crawlerDomainDetailLogic); - const { fetchDomainData } = useActions(crawlerDomainDetailLogic); - const { showModal } = useActions(DeleteDomainModalLogic); - - useEffect(() => { - fetchDomainData(domainId); - }, [domainId]); - - const domainUrl = domain?.url ?? '...'; - - return ( - , - { - if (domain) { - showModal(domain); - } - }} - > - {i18n.translate('xpack.enterpriseSearch.crawler.domainDetail.deleteDomainButtonLabel', { - defaultMessage: 'Delete domain', - })} - , - ], - }} - > - - - {i18n.translate('xpack.enterpriseSearch.crawler.domainDetail.allDomainsButtonLabel', { - defaultMessage: 'All domains', - })} - - - {domain && ( - <> - - - - - - - - - - - - - - - - - )} - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx index 7168f37c8b6789..537c83cac5b1ea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engine/engine_indices.tsx @@ -92,15 +92,15 @@ export const EngineIndices: React.FC = () => { width: '15%', }, { - field: 'ingestionMethod', + field: 'source', name: i18n.translate( 'xpack.enterpriseSearch.content.engine.indices.ingestionMethod.columnTitle', { defaultMessage: 'Ingestion method', } ), - render: (ingestionMethod: IngestionMethod) => ( - {ingestionMethodToText(ingestionMethod)} + render: (source: IngestionMethod) => ( + {ingestionMethodToText(source)} ), truncateText: true, width: '15%', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx index b06264e85012a0..6bdb73a074d4b8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/components/tables/engines_table.tsx @@ -14,13 +14,15 @@ import { CriteriaWithPagination, EuiBasicTable, EuiBasicTableColumn } from '@ela import { i18n } from '@kbn/i18n'; import { EnterpriseSearchEngine } from '../../../../../../../common/types/engines'; +import { MANAGE_BUTTON_LABEL } from '../../../../../shared/constants'; -import { DELETE_BUTTON_LABEL, MANAGE_BUTTON_LABEL } from '../../../../../shared/constants'; import { generateEncodedPath } from '../../../../../shared/encode_path_params'; +import { FormattedDateTime } from '../../../../../shared/formatted_date_time'; import { KibanaLogic } from '../../../../../shared/kibana'; import { EuiLinkTo } from '../../../../../shared/react_router_helpers'; import { ENGINE_PATH } from '../../../../routes'; + import { convertMetaToPagination, Meta } from '../../types'; // add health status @@ -30,12 +32,14 @@ interface EnginesListTableProps { loading: boolean; meta: Meta; onChange: (criteria: CriteriaWithPagination) => void; + onDelete: (engine: EnterpriseSearchEngine) => void; } export const EnginesListTable: React.FC = ({ enginesList, - meta, isLoading, + meta, onChange, + onDelete, }) => { const { navigateToUrl } = useValues(KibanaLogic); const columns: Array> = [ @@ -52,6 +56,7 @@ export const EnginesListTable: React.FC = ({ render: (name: string) => ( {name} @@ -61,11 +66,12 @@ export const EnginesListTable: React.FC = ({ width: '30%', }, { - field: 'last_updated', + field: 'updated', name: i18n.translate('xpack.enterpriseSearch.content.enginesList.table.column.lastUpdated', { defaultMessage: 'Last updated', }), dataType: 'string', + render: (dateString: string) => , }, { field: 'indices.length', @@ -83,9 +89,9 @@ export const EnginesListTable: React.FC = ({ { name: MANAGE_BUTTON_LABEL, description: i18n.translate( - 'xpack.enterpriseSearch.content.enginesList.table.column.action.manage.buttonDescription', + 'xpack.enterpriseSearch.content.enginesList.table.column.actions.view.buttonDescription', { - defaultMessage: 'Manage this engine', + defaultMessage: 'View this engine', } ), type: 'icon', @@ -98,7 +104,7 @@ export const EnginesListTable: React.FC = ({ ), }, { - name: DELETE_BUTTON_LABEL, + color: 'danger', description: i18n.translate( 'xpack.enterpriseSearch.content.enginesList.table.column.action.delete.buttonDescription', { @@ -107,8 +113,17 @@ export const EnginesListTable: React.FC = ({ ), type: 'icon', icon: 'trash', - color: 'danger', - onClick: () => {}, + isPrimary: false, + name: () => + i18n.translate( + 'xpack.enterpriseSearch.content.engineList.table.column.actions.deleteEngineLabel', + { + defaultMessage: 'Delete this engine', + } + ), + onClick: (engine) => { + onDelete(engine); + }, }, ], }, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/delete_engine_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/delete_engine_modal.tsx new file mode 100644 index 00000000000000..16dfdf50a74707 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/delete_engine_modal.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { EuiConfirmModal } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { CANCEL_BUTTON_LABEL } from '../../../shared/constants'; + +import { EnginesListLogic } from './engines_list_logic'; + +export const DeleteEngineModal: React.FC = () => { + const { closeDeleteEngineModal, deleteEngine } = useActions(EnginesListLogic); + const { + deleteModalEngineName: engineName, + isDeleteModalVisible, + isDeleteLoading, + } = useValues(EnginesListLogic); + + if (isDeleteModalVisible) { + return ( + { + deleteEngine({ engineName }); + }} + cancelButtonText={CANCEL_BUTTON_LABEL} + confirmButtonText={i18n.translate( + 'xpack.enterpriseSearch.content.engineList.deleteEngineModal.confirmButton.title', + { + defaultMessage: 'Yes, delete this engine ', + } + )} + buttonColor="danger" + isLoading={isDeleteLoading} + > +

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

    +
    + ); + } else { + return <>; + } +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts index 3dc99d5717845e..e6128bab79bb61 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engine_list_logic.test.ts @@ -19,13 +19,19 @@ import { DEFAULT_META } from './types'; const DEFAULT_VALUES = { data: undefined, - results: [], + deleteModalEngine: null, + deleteModalEngineName: '', + deleteStatus: Status.IDLE, + isDeleteLoading: false, + isDeleteModalVisible: false, + isLoading: false, meta: DEFAULT_META, parameters: { meta: DEFAULT_META }, + results: [], status: Status.IDLE, }; -// sample engines list +// may need to call mock engines response when ready const results: EnterpriseSearchEngine[] = [ { @@ -33,24 +39,18 @@ const results: EnterpriseSearchEngine[] = [ indices: ['index-18', 'index-23'], name: 'engine-name-1', updated: '1999-12-31T23:59:59Z', - // last_updated: '21 March 2021', - // document_count: 18, }, { created: '1999-12-31T23:59:59Z', indices: ['index-180', 'index-230', 'index-8', 'index-2'], name: 'engine-name-2', updated: '1999-12-31T23:59:59Z', - // last_updated: '10 Jul 2018', - // document_count: 10, }, { created: '1999-12-31T23:59:59Z', indices: ['index-2', 'index-3'], name: 'engine-name-3', updated: '1999-12-31T23:59:59Z', - // last_updated: '21 December 2022', - // document_count: 8, }, ]; @@ -71,21 +71,57 @@ describe('EnginesListLogic', () => { describe('onPaginate', () => { it('updates meta with newPageIndex', () => { expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - // test below code when pagination is ready - // EnginesListLogic.actions.onPaginate(1); - // expect(EnginesListLogic.values).toEqual({ - // ...DEFAULT_VALUES, - // meta: { - // ...DEFAULT_META, - // from: 1, - // }, - // parameters: { - // meta: { - // ...DEFAULT_META, - // from: 1, - // }, - // }, - // }); + + EnginesListLogic.actions.onPaginate({ page: { index: 1 } }); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + meta: { + ...DEFAULT_META, + from: 10, + }, + parameters: { + meta: { + ...DEFAULT_META, + from: 10, + }, + }, + }); + + EnginesListLogic.actions.onPaginate({ page: { index: 0 } }); + expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); + + EnginesListLogic.actions.onPaginate({ page: { index: 3 } }); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + meta: { + ...DEFAULT_META, + from: 30, + }, + parameters: { + meta: { + ...DEFAULT_META, + from: 30, + }, + }, + }); + }); + }); + describe('closeDeleteEngineModal', () => { + it('set isDeleteModalVisible to false and engineName to empty string', () => { + EnginesListLogic.actions.openDeleteEngineModal(results[0]); + EnginesListLogic.actions.closeDeleteEngineModal(); + expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); + }); + }); + describe('openDeleteEngineModal', () => { + it('set deleteModalEngineName and set isDeleteModalVisible to true', () => { + EnginesListLogic.actions.openDeleteEngineModal(results[0]); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteModalEngine: results[0], + deleteModalEngineName: 'engine-name-1', + isDeleteModalVisible: true, + }); }); }); }); @@ -120,14 +156,50 @@ describe('EnginesListLogic', () => { }); }); }); + describe('request to delete Engine', () => { + it('should set isDeleteLoading to true on delete engine request', () => { + EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); + EnginesListLogic.actions.deleteError({} as HttpError); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteStatus: Status.ERROR, + isDeleteLoading: false, + }); + }); + it('should set isDeleteLoading to false on delete apiError', () => { + EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); + EnginesListLogic.actions.deleteError({} as HttpError); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteStatus: Status.ERROR, + isDeleteLoading: false, + }); + }); + it('should set isDeleteLoading to false on delete apiSuccess', () => { + EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); + EnginesListLogic.actions.deleteSuccess({ engineName: results[0].name }); + expect(EnginesListLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteStatus: Status.SUCCESS, + isDeleteLoading: false, + isLoading: true, + status: Status.LOADING, // fetchEngine api status + }); + }); + }); }); describe('listeners', () => { - it('call flashAPIErrors on apiError', () => { - EnginesListLogic.actions.apiError({} as HttpError); - expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledTimes(1); - expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledWith({}); - }); + it('calls flashSuccessToast, closeDeleteEngineModal and fetchEngines on deleteSuccess', () => { + EnginesListLogic.actions.fetchEngines = jest.fn(); + EnginesListLogic.actions.closeDeleteEngineModal = jest.fn(); + EnginesListLogic.actions.deleteSuccess({ engineName: results[0].name }); + expect(mockFlashMessageHelpers.flashSuccessToast).toHaveBeenCalledTimes(1); + expect(EnginesListLogic.actions.fetchEngines).toHaveBeenCalledWith( + EnginesListLogic.values.parameters + ); + expect(EnginesListLogic.actions.closeDeleteEngineModal).toHaveBeenCalled(); + }); it('call makeRequest on fetchEngines', async () => { jest.useFakeTimers({ legacyFakeTimers: true }); EnginesListLogic.actions.makeRequest = jest.fn(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx index 6c7540cd3f92dc..7ca7c0994e4e47 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list.tsx @@ -16,14 +16,14 @@ import { FormattedMessage, FormattedNumber } from '@kbn/i18n-react'; import { DataPanel } from '../../../shared/data_panel/data_panel'; -import { handlePageChange } from '../../../shared/table_pagination'; import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; import { EnginesListTable } from './components/tables/engines_table'; +import { DeleteEngineModal } from './delete_engine_modal'; import { EnginesListLogic } from './engines_list_logic'; export const EnginesList: React.FC = () => { - const { fetchEngines, onPaginate } = useActions(EnginesListLogic); + const { fetchEngines, onPaginate, openDeleteEngineModal } = useActions(EnginesListLogic); const { meta, results } = useValues(EnginesListLogic); const [searchQuery, setSearchValue] = useState(''); @@ -35,106 +35,127 @@ export const EnginesList: React.FC = () => { }, [meta.from, meta.size, searchQuery]); return ( - - {i18n.translate('xpack.enterpriseSearch.content.engines.createEngineButtonLabel', { - defaultMessage: 'Create engine', - })} -
    , - ], - }} - pageViewTelemetry="Engines" - isLoading={false} - > - - {i18n.translate('xpack.enterpriseSearch.content.engines.description', { - defaultMessage: - 'Engines allow you to query indexed data with a complete set of relevance, analytics and personalization tools. To learn more about how engines work in Enterprise search ', - })} - - - {i18n.translate('xpack.enterpriseSearch.content.engines.documentation', { - defaultMessage: 'explore our Engines documentation', - })} - - - -
    - + + + {i18n.translate('xpack.enterpriseSearch.content.engines.createEngineButtonLabel', { + defaultMessage: 'Create engine', + })} + , + ], + }} + pageViewTelemetry="Engines" + isLoading={false} + > + + + {' '} + {/* TODO: navigate to documentation url */}{' '} + {i18n.translate('xpack.enterpriseSearch.content.engines.documentation', { + defaultMessage: 'explore our Engines documentation', + })} + + ), + }} + /> + + +
    + { + setSearchValue(event.currentTarget.value); + }} + /> +
    + + + {i18n.translate('xpack.enterpriseSearch.content.engines.searchPlaceholder.description', { + defaultMessage: 'Locate an engine via name or indices', })} - fullWidth - onChange={(event) => { - setSearchValue(event.currentTarget.value); - }} - /> -
    - - - {i18n.translate('xpack.enterpriseSearch.content.engines.searchPlaceholder.description', { - defaultMessage: 'Locate an engine via name or indices', - })} - + - - - - - - ), - size: ( - - - - ), - total: , - }} - /> - - - {i18n.translate('xpack.enterpriseSearch.content.engines.title', { - defaultMessage: 'Engines', - })} - - } - > - - + + + + + + ), + to: ( + + + + ), + total: , + }} + /> + + + {i18n.translate('xpack.enterpriseSearch.content.engines.title', { + defaultMessage: 'Engines', + })} + + } + > + + - -
    - + +
    + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts index 10f13265c4ea50..8f7a012518905a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/engines_list_logic.ts @@ -7,6 +7,8 @@ import { kea, MakeLogicType } from 'kea'; +import { Status } from '../../../../../common/types/api'; + import { EnterpriseSearchEngine, EnterpriseSearchEnginesResponse, @@ -14,6 +16,11 @@ import { import { Actions } from '../../../shared/api_logic/create_api_logic'; +import { + DeleteEngineAPILogic, + DeleteEnginesApiLogicActions, +} from '../../api/engines/delete_engines_api_logic'; + import { EnginesListAPIArguments, FetchEnginesAPILogic, @@ -21,44 +28,81 @@ import { import { DEFAULT_META, Meta, updateMetaPageIndex } from './types'; +interface EuiBasicTableOnChange { + page: { index: number }; +} + type EnginesListActions = Pick< Actions, 'apiError' | 'apiSuccess' | 'makeRequest' > & { + closeDeleteEngineModal(): void; + deleteEngine: DeleteEnginesApiLogicActions['makeRequest']; + deleteError: DeleteEnginesApiLogicActions['apiError']; + deleteSuccess: DeleteEnginesApiLogicActions['apiSuccess']; + fetchEngines({ meta, searchQuery }: { meta: Meta; searchQuery?: string }): { meta: Meta; searchQuery?: string; }; - onPaginate(pageNumber: number): { pageNumber: number }; + + onPaginate(args: EuiBasicTableOnChange): { pageNumber: number }; + openDeleteEngineModal: (engine: EnterpriseSearchEngine) => { engine: EnterpriseSearchEngine }; }; interface EngineListValues { data: typeof FetchEnginesAPILogic.values.data; + deleteModalEngine: EnterpriseSearchEngine | null; + deleteModalEngineName: string; + deleteStatus: typeof DeleteEngineAPILogic.values.status; + isDeleteLoading: boolean; + isDeleteModalVisible: boolean; + isLoading: boolean; meta: Meta; - results: EnterpriseSearchEngine[]; // stores engine list value from data parameters: { meta: Meta; searchQuery?: string }; // Added this variable to store to the search Query value as well + results: EnterpriseSearchEngine[]; // stores engine list value from data status: typeof FetchEnginesAPILogic.values.status; } export const EnginesListLogic = kea>({ + connect: { + actions: [ + FetchEnginesAPILogic, + ['makeRequest', 'apiSuccess', 'apiError'], + DeleteEngineAPILogic, + ['apiSuccess as deleteSuccess', 'makeRequest as deleteEngine', 'apiError as deleteError'], + ], + values: [ + FetchEnginesAPILogic, + ['data', 'status'], + DeleteEngineAPILogic, + ['status as deleteStatus'], + ], + }, actions: { + closeDeleteEngineModal: true, fetchEngines: ({ meta, searchQuery }) => ({ meta, searchQuery, }), - - onPaginate: (pageNumber) => ({ pageNumber }), + onPaginate: (args: EuiBasicTableOnChange) => ({ pageNumber: args.page.index }), + openDeleteEngineModal: (engine) => ({ engine }), }, - connect: { - actions: [FetchEnginesAPILogic, ['makeRequest', 'apiSuccess', 'apiError']], - values: [FetchEnginesAPILogic, ['data', 'status']], - }, - listeners: ({ actions }) => ({ - fetchEngines: async (input) => { - actions.makeRequest(input); - }, - }), path: ['enterprise_search', 'content', 'engine_list_logic'], reducers: ({}) => ({ + deleteModalEngine: [ + null, + { + closeDeleteEngineModal: () => null, + openDeleteEngineModal: (_, { engine }) => engine, + }, + ], + isDeleteModalVisible: [ + false, + { + closeDeleteEngineModal: () => false, + openDeleteEngineModal: () => true, + }, + ], parameters: [ { meta: DEFAULT_META }, { @@ -73,7 +117,25 @@ export const EnginesListLogic = kea ({ - meta: [() => [selectors.parameters], (parameters) => parameters.meta], + deleteModalEngineName: [() => [selectors.deleteModalEngine], (engine) => engine?.name ?? ''], + isDeleteLoading: [ + () => [selectors.deleteStatus], + (status: EngineListValues['deleteStatus']) => [Status.LOADING].includes(status), + ], + isLoading: [ + () => [selectors.status], + (status: EngineListValues['status']) => [Status.LOADING].includes(status), + ], results: [() => [selectors.data], (data) => data?.results ?? []], + meta: [() => [selectors.parameters], (parameters) => parameters.meta], + }), + listeners: ({ actions, values }) => ({ + deleteSuccess: () => { + actions.closeDeleteEngineModal(); + actions.fetchEngines(values.parameters); + }, + fetchEngines: async (input) => { + actions.makeRequest(input); + }, }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts index 2dc0b2f7fe3352..90fb49a054688a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/engines/types.ts @@ -17,11 +17,13 @@ export const DEFAULT_META = { total: 0, }; -export const convertMetaToPagination = (meta: Meta) => ({ - pageIndex: meta.from - 1, - pageSize: meta.size, - totalItemCount: meta.total, -}); +export const convertMetaToPagination = (meta: Meta) => { + return { + pageIndex: meta.from / meta.size, + pageSize: meta.size, + totalItemCount: meta.total, + }; +}; export const updateMetaPageIndex = (oldState: Meta, newPageIndex: number) => { - return { ...oldState, from: newPageIndex }; + return { ...oldState, from: newPageIndex * oldState.size }; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel.scss b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel.scss similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel.scss rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel.scss diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel.tsx similarity index 55% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel.tsx index ddfa88cf27ff04..4f406ebe679396 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel.tsx @@ -9,11 +9,10 @@ import React from 'react'; import { useValues } from 'kea'; +import { EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { DataPanel } from '../../../../shared/data_panel/data_panel'; - import { AuthenticationPanelActions } from './authentication_panel_actions'; import { AuthenticationPanelDeleteConfirmationModal } from './authentication_panel_delete_confirmation_modal'; import { AuthenticationPanelEditContent } from './authentication_panel_edit_content'; @@ -27,26 +26,31 @@ export const AuthenticationPanel: React.FC = () => { return ( <> - - {i18n.translate('xpack.enterpriseSearch.crawler.authenticationPanel.title', { - defaultMessage: 'Authentication', - })} - - } - action={} - subtitle={ - - } - > +
    + + + +

    + {i18n.translate('xpack.enterpriseSearch.crawler.authenticationPanel.title', { + defaultMessage: 'Authentication', + })} +

    +
    +
    + + + +
    + +

    + +

    +
    {isEditing ? : } - +
    {isModalVisible && } ); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_actions.tsx similarity index 95% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_actions.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_actions.tsx index 28285e004182e3..f07f9369e2b8c2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_actions.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_actions.tsx @@ -17,8 +17,8 @@ import { SAVE_BUTTON_LABEL, CANCEL_BUTTON_LABEL, DELETE_BUTTON_LABEL, -} from '../../../../shared/constants'; -import { CrawlerAuth } from '../../../api/crawler/types'; +} from '../../../../../../shared/constants'; +import { CrawlerAuth } from '../../../../../api/crawler/types'; import { CrawlerDomainDetailLogic } from '../crawler_domain_detail_logic'; import { AuthenticationPanelLogic } from './authentication_panel_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_delete_confirmation_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_delete_confirmation_modal.tsx similarity index 95% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_delete_confirmation_modal.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_delete_confirmation_modal.tsx index 98c97378018872..cf51dd692a63d1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_delete_confirmation_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_delete_confirmation_modal.tsx @@ -12,7 +12,7 @@ import { useActions } from 'kea'; import { EuiConfirmModal } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { CANCEL_BUTTON_LABEL } from '../../../../shared/constants'; +import { CANCEL_BUTTON_LABEL } from '../../../../../../shared/constants'; import { AuthenticationPanelLogic } from './authentication_panel_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_edit_content.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_edit_content.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_edit_content.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_edit_content.tsx index 55b930e7c9c21e..c8d24525747e09 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_edit_content.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_edit_content.tsx @@ -23,7 +23,7 @@ import { import { i18n } from '@kbn/i18n'; -import { USERNAME_LABEL, PASSWORD_LABEL } from '../../../../shared/constants'; +import { USERNAME_LABEL, PASSWORD_LABEL } from '../../../../../../shared/constants'; import { AuthenticationPanelLogic } from './authentication_panel_logic'; import { AUTHENTICATION_LABELS } from './constants'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_logic.ts similarity index 96% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_logic.ts index de78802ca2ee0a..e0e71575eb1d03 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_logic.ts @@ -7,8 +7,8 @@ import { kea, MakeLogicType } from 'kea'; -import { CrawlerAuth } from '../../../api/crawler/types'; -import { isRawCrawlerAuth, isBasicCrawlerAuth } from '../../../api/crawler/utils'; +import { CrawlerAuth } from '../../../../../api/crawler/types'; +import { isRawCrawlerAuth, isBasicCrawlerAuth } from '../../../../../api/crawler/utils'; import { CrawlerDomainDetailActions, CrawlerDomainDetailLogic, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_view_content.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_view_content.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/authentication_panel_view_content.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/authentication_panel_view_content.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/constants.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/constants.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/authentication_panel/constants.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/authentication_panel/constants.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawl_rules_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawl_rules_table.test.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawl_rules_table.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawl_rules_table.test.tsx index c5d871a70cf208..7eb4c04db44804 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawl_rules_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawl_rules_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mockFlashMessageHelpers, setMockActions } from '../../../__mocks__/kea_logic'; +import { mockFlashMessageHelpers, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; @@ -13,8 +13,8 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { EuiFieldText, EuiSelect } from '@elastic/eui'; -import { GenericEndpointInlineEditableTable } from '../../../shared/tables/generic_endpoint_inline_editable_table'; -import { CrawlerPolicies, CrawlerRules } from '../../api/crawler/types'; +import { GenericEndpointInlineEditableTable } from '../../../../../shared/tables/generic_endpoint_inline_editable_table'; +import { CrawlerPolicies, CrawlerRules } from '../../../../api/crawler/types'; import { CrawlRulesTable, CrawlRulesTableProps } from './crawl_rules_table'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawl_rules_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawl_rules_table.tsx similarity index 95% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawl_rules_table.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawl_rules_table.tsx index ea4617139d045a..6bead7b4314d91 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawl_rules_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawl_rules_table.tsx @@ -23,13 +23,13 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { docLinks } from '../../../shared/doc_links'; -import { clearFlashMessages, flashSuccessToast } from '../../../shared/flash_messages'; -import { GenericEndpointInlineEditableTable } from '../../../shared/tables/generic_endpoint_inline_editable_table'; +import { docLinks } from '../../../../../shared/doc_links'; +import { clearFlashMessages, flashSuccessToast } from '../../../../../shared/flash_messages'; +import { GenericEndpointInlineEditableTable } from '../../../../../shared/tables/generic_endpoint_inline_editable_table'; -import { InlineEditableTableColumn } from '../../../shared/tables/inline_editable_table/types'; -import { ItemWithAnID } from '../../../shared/tables/types'; -import { CrawlerPolicies, CrawlRule, CrawlerRules } from '../../api/crawler/types'; +import { InlineEditableTableColumn } from '../../../../../shared/tables/inline_editable_table/types'; +import { ItemWithAnID } from '../../../../../shared/tables/types'; +import { CrawlerPolicies, CrawlRule, CrawlerRules } from '../../../../api/crawler/types'; import { CrawlerDomainDetailLogic } from './crawler_domain_detail_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail.tsx new file mode 100644 index 00000000000000..cdee1ca599689e --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail.tsx @@ -0,0 +1,111 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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, { useEffect } from 'react'; + +import { useActions, useValues } from 'kea'; + +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiSplitPanel, + EuiTitle, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { generateEncodedPath } from '../../../../../shared/encode_path_params'; +import { Loading } from '../../../../../shared/loading'; +import { EuiButtonTo } from '../../../../../shared/react_router_helpers'; +import { SEARCH_INDEX_TAB_PATH } from '../../../../routes'; +import { IndexNameLogic } from '../../index_name_logic'; +import { SearchIndexTabId } from '../../search_index'; +import { CrawlCustomSettingsFlyout } from '../crawl_custom_settings_flyout/crawl_custom_settings_flyout'; +import { DeleteDomainModal } from '../domain_management/delete_domain_modal'; +import { DeleteDomainModalLogic } from '../domain_management/delete_domain_modal_logic'; + +import { CrawlerDomainDetailLogic } from './crawler_domain_detail_logic'; +import { CrawlerDomainDetailTabs } from './crawler_domain_detail_tabs'; + +export const CrawlerDomainDetail: React.FC<{ domainId: string }> = ({ domainId }) => { + const { indexName } = useValues(IndexNameLogic); + const crawlerDomainDetailLogic = CrawlerDomainDetailLogic({ domainId }); + const { domain, getLoading } = useValues(crawlerDomainDetailLogic); + const { fetchDomainData } = useActions(crawlerDomainDetailLogic); + const { showModal } = useActions(DeleteDomainModalLogic); + + useEffect(() => { + fetchDomainData(domainId); + }, [domainId]); + + const domainUrl = domain?.url ?? '...'; + + return getLoading ? ( + + ) : ( + <> + + + {i18n.translate('xpack.enterpriseSearch.crawler.domainDetail.allDomainsButtonLabel', { + defaultMessage: 'All domains', + })} + + + + + + + +

    + {i18n.translate('xpack.enterpriseSearch.content.crawler.domainDetail.title', { + defaultMessage: 'Manage {domain}', + values: { domain: domainUrl }, + })} +

    +
    +
    + + { + if (domain) { + showModal(domain); + } + }} + > + {i18n.translate( + 'xpack.enterpriseSearch.crawler.domainDetail.deleteDomainButtonLabel', + { + defaultMessage: 'Delete domain', + } + )} + + +
    +
    + + {domain && } + + + +
    + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawler_domain_detail_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail_logic.ts similarity index 89% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawler_domain_detail_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail_logic.ts index e36f62333a5884..b36671d4927145 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/crawler_domain_detail_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail_logic.ts @@ -7,19 +7,19 @@ import { kea, MakeLogicType } from 'kea'; -import { HttpError, Status } from '../../../../../common/types/api'; +import { HttpError, Status } from '../../../../../../../common/types/api'; -import { generateEncodedPath } from '../../../shared/encode_path_params'; +import { generateEncodedPath } from '../../../../../shared/encode_path_params'; -import { flashAPIErrors } from '../../../shared/flash_messages'; +import { flashAPIErrors } from '../../../../../shared/flash_messages'; -import { HttpLogic } from '../../../shared/http'; -import { KibanaLogic } from '../../../shared/kibana'; +import { HttpLogic } from '../../../../../shared/http'; +import { KibanaLogic } from '../../../../../shared/kibana'; import { DeleteCrawlerDomainApiLogic, DeleteCrawlerDomainArgs, DeleteCrawlerDomainResponse, -} from '../../api/crawler/delete_crawler_domain_api_logic'; +} from '../../../../api/crawler/delete_crawler_domain_api_logic'; import { CrawlerAuth, CrawlerDomain, @@ -27,11 +27,11 @@ import { CrawlRule, EntryPoint, Sitemap, -} from '../../api/crawler/types'; -import { crawlerDomainServerToClient } from '../../api/crawler/utils'; -import { SEARCH_INDEX_TAB_PATH } from '../../routes'; -import { IndexNameLogic } from '../search_index/index_name_logic'; -import { SearchIndexTabId } from '../search_index/search_index'; +} from '../../../../api/crawler/types'; +import { crawlerDomainServerToClient } from '../../../../api/crawler/utils'; +import { SEARCH_INDEX_TAB_PATH } from '../../../../routes'; +import { IndexNameLogic } from '../../index_name_logic'; +import { SearchIndexTabId } from '../../search_index'; export interface CrawlerDomainDetailProps { domainId: string; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail_tabs.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail_tabs.tsx new file mode 100644 index 00000000000000..a62dc8bf3d558f --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/crawler_domain_detail_tabs.tsx @@ -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 React, { useState } from 'react'; + +import { EuiSpacer, EuiTabbedContent, EuiTabbedContentTab } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { CrawlerDomain } from '../../../../api/crawler/types'; + +import { AuthenticationPanel } from './authentication_panel/authentication_panel'; +import { CrawlRulesTable } from './crawl_rules_table'; +import { DeduplicationPanel } from './deduplication_panel/deduplication_panel'; +import { EntryPointsTable } from './entry_points_table'; +import { SitemapsTable } from './sitemaps_table'; + +export enum CrawlerDomainTabId { + ENTRY_POINTS = 'entry_points', + AUTHENTICATION = 'authentication', + SITE_MAPS = 'site_maps', + CRAWL_RULES = 'crawl_rules', + DEDUPLICATION = 'deduplication', +} + +export interface CrawlerDomainDetailTabsProps { + domain: CrawlerDomain; + indexName: string; +} + +export const CrawlerDomainDetailTabs: React.FC = ({ + domain, + indexName, +}) => { + const [tabIndex, setTabIndex] = useState(0); + const tabs = [ + { + content: ( + <> + + + + ), + id: CrawlerDomainTabId.ENTRY_POINTS, + name: i18n.translate('xpack.enterpriseSearch.content.crawler.entryPoints', { + defaultMessage: 'Entry points', + }), + }, + { + content: ( + <> + + + + ), + id: CrawlerDomainTabId.AUTHENTICATION, + name: i18n.translate('xpack.enterpriseSearch.content.crawler.authentication', { + defaultMessage: 'Authentication', + }), + }, + { + content: ( + <> + + + + ), + id: CrawlerDomainTabId.SITE_MAPS, + name: i18n.translate('xpack.enterpriseSearch.content.crawler.siteMaps', { + defaultMessage: 'Site maps', + }), + }, + { + content: ( + <> + + + + ), + id: CrawlerDomainTabId.CRAWL_RULES, + name: i18n.translate('xpack.enterpriseSearch.content.crawler.crawlRules', { + defaultMessage: 'Crawl rules', + }), + }, + { + content: , + id: CrawlerDomainTabId.DEDUPLICATION, + name: i18n.translate('xpack.enterpriseSearch.content.crawler.deduplication', { + defaultMessage: 'Duplicate document handling', + }), + }, + ]; + return ( + { + setTabIndex(tabs.findIndex(({ id }) => id === tab.id) || 0); + }} + /> + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.scss b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.scss similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.scss rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.scss diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.test.tsx similarity index 93% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.test.tsx index bf6caaf0b03c6c..54c93ff744ede3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; +import { setMockActions, setMockValues } from '../../../../../../__mocks__/kea_logic'; import React from 'react'; @@ -26,8 +26,7 @@ import { import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { DataPanel } from '../../../../shared/data_panel/data_panel'; -import { rerender } from '../../../../test_helpers'; +import { rerender } from '../../../../../../test_helpers'; import { DeduplicationPanel } from './deduplication_panel'; @@ -63,7 +62,7 @@ describe('DeduplicationPanel', () => { it('contains a button to reset to defaults', () => { const wrapper = shallow(); - wrapper.find(DataPanel).dive().find(EuiButton).simulate('click'); + wrapper.find('EuiFlexGroup').first().dive().find(EuiButton).simulate('click'); expect(MOCK_ACTIONS.submitDeduplicationUpdate).toHaveBeenCalledWith({ fields: [], diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.tsx similarity index 75% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.tsx index b8963ea3ef3abc..8076b3e49aa1f3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/deduplication_panel.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/deduplication_panel.tsx @@ -21,6 +21,8 @@ import { EuiSelectable, EuiSpacer, EuiSwitch, + EuiText, + EuiTitle, } from '@elastic/eui'; import { EuiSelectableLIOption } from '@elastic/eui/src/components/selectable/selectable_option'; @@ -28,8 +30,7 @@ import { EuiSelectableLIOption } from '@elastic/eui/src/components/selectable/se import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { DataPanel } from '../../../../shared/data_panel/data_panel'; -import { docLinks } from '../../../../shared/doc_links'; +import { docLinks } from '../../../../../../shared/doc_links'; import { CrawlerDomainDetailLogic } from '../crawler_domain_detail_logic'; import { getCheckedOptionLabels, getSelectableOptions } from './utils'; @@ -52,53 +53,60 @@ export const DeduplicationPanel: React.FC = () => { const selectableOptions = getSelectableOptions(domain, showAllFields); return ( - - {i18n.translate('xpack.enterpriseSearch.crawler.deduplicationPanel.title', { - defaultMessage: 'Duplicate document handling', - })} - - } - action={ - submitDeduplicationUpdate({ fields: [] })} - disabled={deduplicationFields.length === 0} - > - {i18n.translate( - 'xpack.enterpriseSearch.crawler.deduplicationPanel.resetToDefaultsButtonLabel', - { - defaultMessage: 'Reset to defaults', - } - )} - - } - subtitle={ - + + + + +

    + {i18n.translate('xpack.enterpriseSearch.crawler.deduplicationPanel.title', { + defaultMessage: 'Duplicate document handling', + })} +

    +
    +
    + + submitDeduplicationUpdate({ fields: [] })} + disabled={deduplicationFields.length === 0} + > + {i18n.translate( + 'xpack.enterpriseSearch.crawler.deduplicationPanel.resetToDefaultsButtonLabel', + { + defaultMessage: 'Reset to defaults', + } + )} + + +
    + + +

    + - {i18n.translate( - 'xpack.enterpriseSearch.crawler.deduplicationPanel.learnMoreMessage', - { - defaultMessage: 'Learn more about content hashing', - } - )} - - ), - }} - /> - } - > + values={{ + documentationLink: ( + + {i18n.translate( + 'xpack.enterpriseSearch.crawler.deduplicationPanel.learnMoreMessage', + { + defaultMessage: 'Learn more about content hashing', + } + )} + + ), + }} + /> +

    +
    + {
    - +
    ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/utils.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/utils.ts similarity index 95% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/utils.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/utils.ts index 256385722c1881..162761f43057d3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/deduplication_panel/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/deduplication_panel/utils.ts @@ -6,7 +6,7 @@ */ import { EuiSelectableLIOption } from '@elastic/eui/src/components/selectable/selectable_option'; -import { CrawlerDomain } from '../../../api/crawler/types'; +import { CrawlerDomain } from '../../../../../api/crawler/types'; export const getSelectableOptions = ( domain: CrawlerDomain, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table.test.tsx similarity index 95% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table.test.tsx index a540a24188783c..cf1224cb0dc473 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table.test.tsx @@ -13,8 +13,8 @@ import { EuiFieldText } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { GenericEndpointInlineEditableTable } from '../../../shared/tables/generic_endpoint_inline_editable_table'; -import { CrawlerDomain } from '../../api/crawler/types'; +import { GenericEndpointInlineEditableTable } from '../../../../../shared/tables/generic_endpoint_inline_editable_table'; +import { CrawlerDomain } from '../../../../api/crawler/types'; import { EntryPointsTable, EntryPointsTableProps } from './entry_points_table'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table.tsx similarity index 91% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table.tsx index 5f637c506e1856..a80ecc85646b3b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table.tsx @@ -14,12 +14,12 @@ import { EuiFieldText, EuiLink, EuiSpacer, EuiText, EuiTitle } from '@elastic/eu import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { docLinks } from '../../../shared/doc_links'; -import { GenericEndpointInlineEditableTable } from '../../../shared/tables/generic_endpoint_inline_editable_table'; +import { docLinks } from '../../../../../shared/doc_links'; +import { GenericEndpointInlineEditableTable } from '../../../../../shared/tables/generic_endpoint_inline_editable_table'; -import { InlineEditableTableColumn } from '../../../shared/tables/inline_editable_table/types'; -import { ItemWithAnID } from '../../../shared/tables/types'; -import { CrawlerDomain, EntryPoint } from '../../api/crawler/types'; +import { InlineEditableTableColumn } from '../../../../../shared/tables/inline_editable_table/types'; +import { ItemWithAnID } from '../../../../../shared/tables/types'; +import { CrawlerDomain, EntryPoint } from '../../../../api/crawler/types'; import { EntryPointsTableLogic } from './entry_points_table_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table_logic.test.ts similarity index 98% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table_logic.test.ts index b5a0a3aec37ce7..afe1eb941f83be 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table_logic.test.ts @@ -13,7 +13,7 @@ jest.mock('./crawler_domain_detail_logic', () => ({ }, })); -import { LogicMounter, mockFlashMessageHelpers } from '../../../__mocks__/kea_logic'; +import { LogicMounter, mockFlashMessageHelpers } from '../../../../../__mocks__/kea_logic'; import { CrawlerDomainDetailLogic } from './crawler_domain_detail_logic'; import { EntryPointsTableLogic } from './entry_points_table_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table_logic.ts similarity index 95% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table_logic.ts index b7b2daa525a8df..d79fff69b9f62c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/entry_points_table_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/entry_points_table_logic.ts @@ -7,9 +7,9 @@ import { kea, MakeLogicType } from 'kea'; -import { clearFlashMessages, flashSuccessToast } from '../../../shared/flash_messages'; +import { clearFlashMessages, flashSuccessToast } from '../../../../../shared/flash_messages'; -import { EntryPoint } from '../../api/crawler/types'; +import { EntryPoint } from '../../../../api/crawler/types'; import { CrawlerDomainDetailLogic } from './crawler_domain_detail_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/sitemaps_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/sitemaps_table.test.tsx similarity index 96% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/sitemaps_table.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/sitemaps_table.test.tsx index f8d1ddd3d4b570..1cae5f5cbe0960 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/sitemaps_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/sitemaps_table.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { mockFlashMessageHelpers, setMockActions } from '../../../__mocks__/kea_logic'; +import { mockFlashMessageHelpers, setMockActions } from '../../../../../__mocks__/kea_logic'; import React from 'react'; @@ -14,9 +14,9 @@ import { shallow } from 'enzyme'; import { EuiEmptyPrompt, EuiFieldText } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { GenericEndpointInlineEditableTable } from '../../../shared/tables/generic_endpoint_inline_editable_table'; +import { GenericEndpointInlineEditableTable } from '../../../../../shared/tables/generic_endpoint_inline_editable_table'; -import { CrawlerDomain } from '../../api/crawler/types'; +import { CrawlerDomain } from '../../../../api/crawler/types'; import { SitemapsTable } from './sitemaps_table'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/sitemaps_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/sitemaps_table.tsx similarity index 90% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/sitemaps_table.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/sitemaps_table.tsx index d4c2ab5f4955a1..c486cb2eeaed71 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/crawler_domain_detail/sitemaps_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/crawler_domain_detail/sitemaps_table.tsx @@ -13,12 +13,12 @@ import { EuiButton, EuiEmptyPrompt, EuiFieldText, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { clearFlashMessages, flashSuccessToast } from '../../../shared/flash_messages'; -import { GenericEndpointInlineEditableTable } from '../../../shared/tables/generic_endpoint_inline_editable_table'; +import { clearFlashMessages, flashSuccessToast } from '../../../../../shared/flash_messages'; +import { GenericEndpointInlineEditableTable } from '../../../../../shared/tables/generic_endpoint_inline_editable_table'; -import { InlineEditableTableColumn } from '../../../shared/tables/inline_editable_table/types'; -import { ItemWithAnID } from '../../../shared/tables/types'; -import { CrawlerDomain, Sitemap } from '../../api/crawler/types'; +import { InlineEditableTableColumn } from '../../../../../shared/tables/inline_editable_table/types'; +import { ItemWithAnID } from '../../../../../shared/tables/types'; +import { CrawlerDomain, Sitemap } from '../../../../api/crawler/types'; import { CrawlerDomainDetailLogic } from './crawler_domain_detail_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_logic.test.ts index c2933889aa4a8f..16947a575cf5f5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_logic.test.ts @@ -301,7 +301,7 @@ describe('AddDomainLogic', () => { expect(flashSuccessToast).toHaveBeenCalled(); expect(navigateToUrl).toHaveBeenCalledWith( - '/search_indices/index-name/crawler/domains/test-domain' + '/search_indices/index-name/domain_management/test-domain' ); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domain_management.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domain_management.tsx index 3400dd19347d2a..1bcecb5c05e705 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domain_management.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domain_management.tsx @@ -7,6 +7,8 @@ import React from 'react'; +import { useParams } from 'react-router-dom'; + import { useValues } from 'kea'; import { EuiSpacer } from '@elastic/eui'; @@ -16,6 +18,8 @@ import { Loading } from '../../../../../shared/loading'; import { DeleteCrawlerDomainApiLogic } from '../../../../api/crawler/delete_crawler_domain_api_logic'; import { GetCrawlerDomainsApiLogic } from '../../../../api/crawler/get_crawler_domains_api_logic'; +import { CrawlerDomainDetail } from '../crawler_domain_detail/crawler_domain_detail'; + import { AddDomainFlyout } from './add_domain/add_domain_flyout'; import { CrawlerStatusBanner } from './crawler_status_banner'; import { DeleteDomainModal } from './delete_domain_modal'; @@ -28,11 +32,17 @@ export const SearchIndexDomainManagement: React.FC = () => { GetCrawlerDomainsApiLogic.mount(); const { domains, isLoading } = useValues(DomainManagementLogic); + const { detailId } = useParams<{ + detailId?: string; + }>(); + if (isLoading) { return ; } - return ( + return detailId ? ( + + ) : ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.test.tsx index 6ef7512a594837..46b3ed3ba6058f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.test.tsx @@ -117,7 +117,7 @@ describe('DomainsTable', () => { expect(link.dive().text()).toContain('elastic.co'); expect(link.props()).toEqual( expect.objectContaining({ - to: '/search_indices/index-name/crawler/domains/1234', + to: '/search_indices/index-name/domain_management/1234', }) ); }); @@ -157,7 +157,7 @@ describe('DomainsTable', () => { getManageAction().simulate('click'); expect(navigateToUrl).toHaveBeenCalledWith( - '/search_indices/index-name/crawler/domains/1234' + '/search_indices/index-name/domain_management/1234' ); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index_router.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index_router.tsx index 75d27d4208dc57..e7be83aa644320 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index_router.tsx @@ -6,19 +6,18 @@ */ import React, { useEffect } from 'react'; -import { Route, Switch, useParams } from 'react-router-dom'; +import { Redirect, Route, Switch, useParams } from 'react-router-dom'; import { useActions } from 'kea'; import { - SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH, + OLD_SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH, SEARCH_INDEX_PATH, SEARCH_INDEX_SELECT_CONNECTOR_PATH, + SEARCH_INDEX_TAB_DETAIL_PATH, SEARCH_INDEX_TAB_PATH, } from '../../routes'; -import { CrawlerDomainDetail } from '../crawler_domain_detail/crawler_domain_detail'; - import { SelectConnector } from './connector/select_connector/select_connector'; import { IndexNameLogic } from './index_name_logic'; import { IndexViewLogic } from './index_view_logic'; @@ -49,15 +48,19 @@ export const SearchIndexRouter: React.FC = () => { - - - + + + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_stats.tsx index afb25decdfdc38..d4c4fd4f6633e9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_stats.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_stats.tsx @@ -26,6 +26,11 @@ export const IndicesStats: React.FC = () => { makeRequest({}); }, []); + const UNKNOWN_STRING = i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.jobStats.unknown', + { defaultMessage: 'Unknown' } + ); + return ( @@ -44,7 +49,7 @@ export const IndicesStats: React.FC = () => { } )} isLoading={isLoading} - title={data?.connected} + title={data?.connected ?? UNKNOWN_STRING} /> @@ -62,7 +67,7 @@ export const IndicesStats: React.FC = () => { } )} isLoading={isLoading} - title={data?.incomplete} + title={data?.incomplete ?? UNKNOWN_STRING} /> @@ -80,21 +85,21 @@ export const IndicesStats: React.FC = () => { } )} isLoading={isLoading} - title={data?.in_progress} + title={data?.in_progress ?? UNKNOWN_STRING} /> - + @@ -112,7 +117,7 @@ export const IndicesStats: React.FC = () => { } )} isLoading={isLoading} - title={data?.orphaned_jobs} + title={data?.orphaned_jobs ?? UNKNOWN_STRING} /> @@ -126,7 +131,7 @@ export const IndicesStats: React.FC = () => { } )} isLoading={isLoading} - title={data?.errors} + title={data?.errors ?? UNKNOWN_STRING} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts index 3617c097ad4018..4185addb31445a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts @@ -19,10 +19,13 @@ export const NEW_DIRECT_UPLOAD_PATH = `${NEW_INDEX_PATH}/upload`; export const SEARCH_INDEX_PATH = `${SEARCH_INDICES_PATH}/:indexName`; export const SEARCH_INDEX_TAB_PATH = `${SEARCH_INDEX_PATH}/:tabId`; -export const SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH = `${SEARCH_INDEX_PATH}/crawler/domains/:domainId`; +export const SEARCH_INDEX_TAB_DETAIL_PATH = `${SEARCH_INDEX_TAB_PATH}/:detailId`; +export const SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH = `${SEARCH_INDEX_PATH}/domain_management/:domainId`; +export const OLD_SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH = `${SEARCH_INDEX_PATH}/crawler/domains/:domainId`; export const SEARCH_INDEX_SELECT_CONNECTOR_PATH = `${SEARCH_INDEX_PATH}/select_connector`; export const ENGINES_PATH = `${ROOT_PATH}engines`; + export const ENGINE_CREATION_PATH = `${ENGINES_PATH}/new`; export const ENGINE_PATH = `${ENGINES_PATH}/:engineName`; export const ENGINE_TAB_PATH = `${ENGINE_PATH}/:tabId`; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts index 3bc19bb2a8b652..fd87b60bd99a85 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/indices.ts @@ -129,20 +129,26 @@ export function indexToViewIndex(index: ElasticsearchIndex): ApiViewIndex { } export function ingestionMethodToText(ingestionMethod: IngestionMethod) { - if (ingestionMethod === IngestionMethod.CONNECTOR) { - return i18n.translate( - 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.connector', - { - defaultMessage: 'Connector', - } - ); + switch (ingestionMethod) { + case IngestionMethod.CONNECTOR: + return i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.connector', + { + defaultMessage: 'Connector', + } + ); + case IngestionMethod.CRAWLER: + return i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.crawler', + { + defaultMessage: 'Crawler', + } + ); + case IngestionMethod.API: + return i18n.translate('xpack.enterpriseSearch.content.searchIndices.ingestionMethod.api', { + defaultMessage: 'API', + }); + default: + return ingestionMethod; } - if (ingestionMethod === IngestionMethod.CRAWLER) { - return i18n.translate('xpack.enterpriseSearch.content.searchIndices.ingestionMethod.crawler', { - defaultMessage: 'Crawler', - }); - } - return i18n.translate('xpack.enterpriseSearch.content.searchIndices.ingestionMethod.api', { - defaultMessage: 'API', - }); } diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx index f74125b1528c7f..fd76943d3e7275 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/formatted_date_time/index.test.tsx @@ -16,7 +16,7 @@ describe('FormattedDateTime', () => { const date = new Date('1970-01-01T12:00:00'); const wrapper = mountWithIntl(); - expect(wrapper.text()).toEqual('Jan 1, 1970 12:00 PM'); + expect(wrapper.text()).toEqual('Jan 1, 1970 12:00 PM'); }); it('does not render time if hideTime is passed', () => { diff --git a/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts b/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts index 2160ca21650076..4e428c797eca5d 100644 --- a/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts +++ b/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts @@ -45,7 +45,7 @@ export const fetchSyncJobsStats = async (client: IScopedClusterClient): Promise< }, }); - const stuckJobsCountResponse = await client.asCurrentUser.count({ + const idleJobsCountResponse = await client.asCurrentUser.count({ index: CONNECTORS_JOBS_INDEX, query: { bool: { @@ -127,10 +127,10 @@ export const fetchSyncJobsStats = async (client: IScopedClusterClient): Promise< const response = { connected: connectedResponse.count, errors: errorResponse.count, + idle: idleJobsCountResponse.count, in_progress: inProgressJobsCountResponse.count, incomplete: incompleteResponse.count, orphaned_jobs: orphanedJobsCountResponse.count, - stuck: stuckJobsCountResponse.count, }; return response; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts index cc3337147934b7..c4e216f52183de 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/engines.ts @@ -62,6 +62,9 @@ export function registerEnginesRoutes({ }), }, }, - enterpriseSearchRequestHandler.createRequest({ path: '/api/engines/:engine_name' }) + enterpriseSearchRequestHandler.createRequest({ + path: '/api/engines/:engine_name', + hasJsonResponse: false, + }) ); } diff --git a/x-pack/plugins/features/common/kibana_feature.ts b/x-pack/plugins/features/common/kibana_feature.ts index 2989872d024c92..debcec588dee0d 100644 --- a/x-pack/plugins/features/common/kibana_feature.ts +++ b/x-pack/plugins/features/common/kibana_feature.ts @@ -32,6 +32,11 @@ export interface KibanaFeatureConfig { */ name: string; + /** + * An optional description that will appear as subtext underneath the feature name + */ + description?: string; + /** * The category for this feature. * This will be used to organize the list of features for display within the @@ -156,6 +161,10 @@ export class KibanaFeature { return this.config.name; } + public get description() { + return this.config.description; + } + public get order() { return this.config.order; } diff --git a/x-pack/plugins/features/common/sub_feature.ts b/x-pack/plugins/features/common/sub_feature.ts index 58142fd88c0c38..e51fc42195797b 100644 --- a/x-pack/plugins/features/common/sub_feature.ts +++ b/x-pack/plugins/features/common/sub_feature.ts @@ -29,6 +29,11 @@ export interface SubFeatureConfig { /** Collection of privilege groups */ privilegeGroups: readonly SubFeaturePrivilegeGroupConfig[]; + + /** + * An optional description that will appear as subtext underneath the sub-feature name + */ + description?: string; } /** @@ -105,6 +110,10 @@ export class SubFeature { return this.config.requireAllSpaces ?? false; } + public get description() { + return this.config.description || ''; + } + public toRaw() { return { ...this.config }; } diff --git a/x-pack/plugins/features/server/feature_schema.ts b/x-pack/plugins/features/server/feature_schema.ts index 05d172887d870d..cfc7c2ee47eaa2 100644 --- a/x-pack/plugins/features/server/feature_schema.ts +++ b/x-pack/plugins/features/server/feature_schema.ts @@ -165,6 +165,7 @@ const kibanaSubFeatureSchema = schema.object({ name: schema.string(), requireAllSpaces: schema.maybe(schema.boolean()), privilegesTooltip: schema.maybe(schema.string()), + description: schema.maybe(schema.string()), privilegeGroups: schema.maybe( schema.arrayOf( schema.oneOf([ @@ -198,6 +199,7 @@ const kibanaFeatureSchema = schema.object({ }), name: schema.string(), category: appCategorySchema, + description: schema.maybe(schema.string()), order: schema.maybe(schema.number()), excludeFromBasePrivileges: schema.maybe(schema.boolean()), minimumLicense: schema.maybe(validLicenseSchema), diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx index 32100ea1379308..4e371767c0ece4 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_create_inline.tsx @@ -22,8 +22,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; -import { dataTypes } from '../../../../../../common/constants'; - +import { generateNewAgentPolicyWithDefaults } from '../../../services'; import type { AgentPolicy, NewAgentPolicy } from '../../../types'; import { sendCreateAgentPolicy, useStartServices } from '../../../hooks'; @@ -57,13 +56,12 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent = ({ const [isLoading, setIsLoading] = useState(false); - const [newAgentPolicy, setNewAgentPolicy] = useState({ - name: agentPolicyName, - description: '', - namespace: 'default', - monitoring_enabled: Object.values(dataTypes), - has_fleet_server: isFleetServerPolicy, - }); + const [newAgentPolicy, setNewAgentPolicy] = useState( + generateNewAgentPolicyWithDefaults({ + name: agentPolicyName, + has_fleet_server: isFleetServerPolicy, + }) + ); const updateNewAgentPolicy = useCallback( (updatedFields: Partial) => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx index 888c6807976d39..0c51b78c8d1af9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_agent_policy_or_default.tsx @@ -14,6 +14,8 @@ import { sendGetEnrollmentAPIKeys, } from '../../../../../../../hooks'; +import { generateNewAgentPolicyWithDefaults } from '../../../../../../../services'; + import type { AgentPolicy, NewAgentPolicy, EnrollmentAPIKey } from '../../../../../../../types'; interface UseGetAgentPolicyOrDefaultResponse { @@ -24,14 +26,14 @@ interface UseGetAgentPolicyOrDefaultResponse { created?: boolean; } export const DEFAULT_AGENT_POLICY_ID: string = 'fleet-first-agent-policy'; -export const DEFAULT_AGENT_POLICY: NewAgentPolicy = Object.freeze({ - id: DEFAULT_AGENT_POLICY_ID, - name: i18n.translate('xpack.fleet.createPackagePolicy.firstAgentPolicyNameText', { - defaultMessage: 'My first agent policy', - }), - namespace: 'default', - monitoring_enabled: ['logs', 'metrics'] as NewAgentPolicy['monitoring_enabled'], -}); +export const DEFAULT_AGENT_POLICY: NewAgentPolicy = Object.freeze( + generateNewAgentPolicyWithDefaults({ + id: DEFAULT_AGENT_POLICY_ID, + name: i18n.translate('xpack.fleet.createPackagePolicy.firstAgentPolicyNameText', { + defaultMessage: 'My first agent policy', + }), + }) +); const sendGetAgentPolicy = async (agentPolicyId: string) => { let result; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx index 0cdc581260b53b..5c80b2276ae090 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.test.tsx @@ -383,6 +383,7 @@ describe('when on the package policy create page', () => { monitoring_enabled: ['logs', 'metrics'], name: 'Agent policy 2', namespace: 'default', + inactivity_timeout: 1209600, }, { withSysMonitoring: false } ); @@ -413,6 +414,7 @@ describe('when on the package policy create page', () => { monitoring_enabled: ['logs', 'metrics'], name: 'Agent policy 2', namespace: 'default', + inactivity_timeout: 1209600, }, { withSysMonitoring: true } ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx index 9146dfe36eee02..cd5b997d9c788c 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx @@ -25,7 +25,7 @@ import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; import { useCancelAddPackagePolicy } from '../hooks'; import { splitPkgKey } from '../../../../../../../common/services'; -import { dataTypes } from '../../../../../../../common/constants'; +import { generateNewAgentPolicyWithDefaults } from '../../../../services'; import type { NewAgentPolicy } from '../../../../types'; import { useConfig, sendGetAgentStatus, useGetPackageInfoByKey } from '../../../../hooks'; import { @@ -80,12 +80,9 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ } = useConfig(); const { params } = useRouteMatch(); - const [newAgentPolicy, setNewAgentPolicy] = useState({ - name: 'Agent policy 1', - description: '', - namespace: 'default', - monitoring_enabled: Object.values(dataTypes), - }); + const [newAgentPolicy, setNewAgentPolicy] = useState( + generateNewAgentPolicyWithDefaults({ name: 'Agent policy 1' }) + ); const [withSysMonitoring, setWithSysMonitoring] = useState(true); const validation = agentPolicyFormValidation(newAgentPolicy); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx index ec1b19679760bf..2c48eac8923a82 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/components/create_agent_policy.tsx @@ -24,13 +24,15 @@ import { EuiSpacer, } from '@elastic/eui'; -import { dataTypes } from '../../../../../../../common/constants'; import type { NewAgentPolicy, AgentPolicy } from '../../../../types'; import { useAuthz, useStartServices, sendCreateAgentPolicy } from '../../../../hooks'; import { AgentPolicyForm, agentPolicyFormValidation } from '../../components'; import { DevtoolsRequestFlyoutButton } from '../../../../components'; import { generateCreateAgentPolicyDevToolsRequest } from '../../services'; -import { ExperimentalFeaturesService } from '../../../../services'; +import { + ExperimentalFeaturesService, + generateNewAgentPolicyWithDefaults, +} from '../../../../services'; const FlyoutWithHigherZIndex = styled(EuiFlyout)` z-index: ${(props) => props.theme.eui.euiZLevel5}; @@ -47,12 +49,9 @@ export const CreateAgentPolicyFlyout: React.FunctionComponent = ({ }) => { const { notifications } = useStartServices(); const hasFleetAllPrivileges = useAuthz().fleet.all; - const [agentPolicy, setAgentPolicy] = useState({ - name: '', - description: '', - namespace: 'default', - monitoring_enabled: Object.values(dataTypes), - }); + const [agentPolicy, setAgentPolicy] = useState( + generateNewAgentPolicyWithDefaults() + ); const [isLoading, setIsLoading] = useState(false); const [withSysMonitoring, setWithSysMonitoring] = useState(true); const validation = agentPolicyFormValidation(agentPolicy); diff --git a/x-pack/plugins/fleet/public/services/generate_new_agent_policy.test.ts b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.test.ts new file mode 100644 index 00000000000000..5cd6c5d144019e --- /dev/null +++ b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { generateNewAgentPolicyWithDefaults } from './generate_new_agent_policy'; + +describe('generateNewAgentPolicyWithDefaults', () => { + it('should generate a new agent policy with defaults', () => { + const newAgentPolicy = generateNewAgentPolicyWithDefaults(); + + expect(newAgentPolicy).toEqual({ + name: '', + description: '', + namespace: 'default', + monitoring_enabled: ['logs', 'metrics'], + inactivity_timeout: 1209600, + }); + }); + + it('should override defaults', () => { + const newAgentPolicy = generateNewAgentPolicyWithDefaults({ + name: 'test', + description: 'test description', + namespace: 'test-namespace', + monitoring_enabled: ['logs'], + }); + + expect(newAgentPolicy).toEqual({ + name: 'test', + description: 'test description', + namespace: 'test-namespace', + monitoring_enabled: ['logs'], + inactivity_timeout: 1209600, + }); + }); +}); diff --git a/x-pack/plugins/fleet/public/services/generate_new_agent_policy.ts b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.ts new file mode 100644 index 00000000000000..94fdf5f26632c0 --- /dev/null +++ b/x-pack/plugins/fleet/public/services/generate_new_agent_policy.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { dataTypes } from '../../common/constants'; + +import type { NewAgentPolicy } from '../types'; + +const TWO_WEEKS_SECONDS = 1209600; +// create a new agent policy with the defaults set +// used by forms which create new agent policies for initial state value +export function generateNewAgentPolicyWithDefaults( + overrideProps: Partial = {} +): NewAgentPolicy { + return { + name: '', + description: '', + namespace: 'default', + monitoring_enabled: Object.values(dataTypes), + inactivity_timeout: TWO_WEEKS_SECONDS, + ...overrideProps, + }; +} diff --git a/x-pack/plugins/fleet/public/services/index.ts b/x-pack/plugins/fleet/public/services/index.ts index 7f29e0ba452dad..07a0d68a22c1c9 100644 --- a/x-pack/plugins/fleet/public/services/index.ts +++ b/x-pack/plugins/fleet/public/services/index.ts @@ -49,3 +49,4 @@ export { createExtensionRegistrationCallback } from './ui_extensions'; export { incrementPolicyName } from './increment_policy_name'; export { policyHasFleetServer } from './has_fleet_server'; export { isPackagePrerelease } from './package_prerelease'; +export { generateNewAgentPolicyWithDefaults } from './generate_new_agent_policy'; diff --git a/x-pack/plugins/fleet/server/collectors/register.ts b/x-pack/plugins/fleet/server/collectors/register.ts index 820a51f7f29fcb..de199234693ec7 100644 --- a/x-pack/plugins/fleet/server/collectors/register.ts +++ b/x-pack/plugins/fleet/server/collectors/register.ts @@ -19,7 +19,6 @@ import type { PackageUsage } from './package_collectors'; import { getFleetServerUsage, getFleetServerConfig } from './fleet_server_collector'; import type { FleetServerUsage } from './fleet_server_collector'; import { getAgentPoliciesUsage } from './agent_policies'; -import { getAgentLogsTopErrors } from './agent_logs'; export interface Usage { agents_enabled: boolean; @@ -40,8 +39,8 @@ export interface FleetUsage extends Usage { degraded: number; }; agents_per_policy: number[]; - agent_logs_top_errors: string[]; - fleet_server_logs_top_errors: string[]; + agent_logs_top_errors?: string[]; + fleet_server_logs_top_errors?: string[]; } export const fetchFleetUsage = async ( @@ -61,7 +60,8 @@ export const fetchFleetUsage = async ( ...(await getAgentData(esClient, abortController)), fleet_server_config: await getFleetServerConfig(soClient), agent_policies: await getAgentPoliciesUsage(esClient, abortController), - ...(await getAgentLogsTopErrors(esClient)), + // TODO removed top errors telemetry as it causes this issue: https://github.com/elastic/kibana/issues/148976 + // ...(await getAgentLogsTopErrors(esClient)), }; return usage; }; diff --git a/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts b/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts index e6a55e0585af93..d662f283000205 100644 --- a/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts @@ -286,8 +286,8 @@ describe('fleet usage telemetry', () => { ], }, agent_policies: { count: 3, output_types: ['elasticsearch'] }, - agent_logs_top_errors: ['stderr panic close of closed channel'], - fleet_server_logs_top_errors: ['failed to unenroll offline agents'], + // agent_logs_top_errors: ['stderr panic close of closed channel'], + // fleet_server_logs_top_errors: ['failed to unenroll offline agents'], }) ); }); diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index ea8b3ff572e326..d054f8dcb9b8c4 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -1042,7 +1042,7 @@ class AgentPolicyService { type: SAVED_OBJECT_TYPE, page: 1, perPage: SO_SEARCH_LIMIT, - filter: `${SAVED_OBJECT_TYPE}.attributes.inactivity_timeout: *`, + filter: `${SAVED_OBJECT_TYPE}.attributes.inactivity_timeout > 0`, fields: [`inactivity_timeout`], }); diff --git a/x-pack/plugins/fleet/server/services/epm/archive/extract.ts b/x-pack/plugins/fleet/server/services/epm/archive/extract.ts index 03caf8901f40b9..84c2457f4dafe2 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/extract.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/extract.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { finished } from 'stream/promises'; + import tar from 'tar'; import yauzl from 'yauzl'; @@ -16,19 +18,20 @@ export async function untarBuffer( buffer: Buffer, filter = (entry: ArchiveEntry): boolean => true, onEntry = (entry: ArchiveEntry): void => {} -): Promise { +) { const deflatedStream = bufferToStream(buffer); // use tar.list vs .extract to avoid writing to disk - const inflateStream = tar.list().on('entry', (entry: tar.FileStat) => { - const path = entry.header.path || ''; + const inflateStream = tar.list().on('entry', (entry) => { + const path = entry.path || ''; if (!filter({ path })) return; - streamToBuffer(entry).then((entryBuffer) => onEntry({ buffer: entryBuffer, path })); + streamToBuffer(entry as unknown as NodeJS.ReadableStream).then((entryBuffer) => + onEntry({ buffer: entryBuffer, path }) + ); }); - return new Promise((resolve, reject) => { - inflateStream.on('end', resolve).on('error', reject); - deflatedStream.pipe(inflateStream); - }); + deflatedStream.pipe(inflateStream); + + await finished(inflateStream); } export async function unzipBuffer( diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index f709c7b92f89a5..750613abfd21a1 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -17,6 +17,8 @@ function validateNonEmptyString(val: string) { } } +const TWO_WEEKS_SECONDS = 1209600; + export const AgentPolicyBaseSchema = { id: schema.maybe(schema.string()), name: schema.string({ minLength: 1, validate: validateNonEmptyString }), @@ -27,7 +29,7 @@ export const AgentPolicyBaseSchema = { is_default: schema.maybe(schema.boolean()), is_default_fleet_server: schema.maybe(schema.boolean()), unenroll_timeout: schema.maybe(schema.number({ min: 0 })), - inactivity_timeout: schema.maybe(schema.number({ min: 0 })), + inactivity_timeout: schema.number({ min: 0, defaultValue: TWO_WEEKS_SECONDS }), monitoring_enabled: schema.maybe( schema.arrayOf( schema.oneOf([schema.literal(dataTypes.Logs), schema.literal(dataTypes.Metrics)]) diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx index c00885de6b9678..8c26701498f0d6 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx @@ -448,7 +448,7 @@ export const PARAMETERS_DEFINITION: { [key in ParameterName]: ParameterDefinitio }, ], }, - schema: t.string, + schema: t.union([t.string, t.array(t.string)]), }, value: { fieldConfig: { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts index d41821bf3aebab..2006f72a7e35de 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts @@ -183,6 +183,23 @@ describe('Properties validator', () => { expect(errors).toEqual([]); }); + it(`should allow copy_to to be an array of strings`, () => { + const properties = { + text1: { type: 'text', copy_to: ['field1', 'field2'] }, + field1: { type: 'text' }, + field2: { type: 'text' }, + }; + + const { value, errors } = validateProperties(properties as any); + + expect(value).toEqual({ + text1: { type: 'text', copy_to: ['field1', 'field2'] }, + field1: { type: 'text' }, + field2: { type: 'text' }, + }); + expect(errors).toEqual([]); + }); + it('should strip field whose type is not a string or is unknown', () => { const properties = { prop1: { type: 123 }, @@ -254,7 +271,7 @@ describe('Properties validator', () => { ignore_malformed: 0, null_value_numeric: 'abc', null_value_boolean: [], - copy_to: [], + copy_to: [1], max_input_length: true, locale: 1, orientation: [], diff --git a/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts b/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts index c31e6a6fa7854d..549dff69eabb1b 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts @@ -314,6 +314,37 @@ describe('IndexPattern Data Source', () => { }; expect(FormBasedDatasource?.getSelectedFields?.(state)).toEqual([]); }); + + it('should support columns with multiple fields', async () => { + const state = { + currentIndexPatternId: '1', + layers: { + first: { + indexPatternId: '1', + columnOrder: ['col1'], + columns: { + col1: { + label: 'My Op', + dataType: 'string', + isBucketed: true, + + // Private + operationType: 'terms', + sourceField: 'op', + params: { + size: 5, + orderBy: { type: 'alphabetical' }, + orderDirection: 'asc', + secondaryFields: ['source', 'geo.src'], + }, + } as TermsIndexPatternColumn, + }, + }, + }, + }; + + expect(FormBasedDatasource?.getSelectedFields?.(state)).toEqual(['op', 'source', 'geo.src']); + }); }); describe('#toExpression', () => { diff --git a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx index e4b6adf8f85ab6..e3f6df8e0887ff 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx @@ -408,7 +408,9 @@ export function getFormBasedDatasource({ Object.values(state?.layers)?.forEach((l) => { const { columns } = l; Object.values(columns).forEach((c) => { - if ('sourceField' in c) { + if (operationDefinitionMap[c.operationType]?.getCurrentFields) { + fields.push(...(operationDefinitionMap[c.operationType]?.getCurrentFields?.(c) || [])); + } else if ('sourceField' in c) { fields.push(c.sourceField); } }); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/README.md b/x-pack/plugins/monitoring/server/routes/api/v1/_health/README.md index 09fc9452ae112b..f335bef44d012f 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/_health/README.md +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/README.md @@ -12,3 +12,4 @@ The response includes sections that can provide useful informations in a debuggi - settings: a subset of the kibana.yml settings relevant to stack monitoring - monitoredClusters: a representation of the monitoring documents available to the running kibana. It exposes which metricsets are collected by what collection mode and when was the last time it was ingested. The query groups the metricsets by products and can help identify missing documents that could explain why a page is not loading or crashing - metricbeatErrors: a list of errors encountered by metricbeat processes when collecting data +- packageErrors: a list of errors encountered by integration package processes when collecting data \ No newline at end of file diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/build_errors.test.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/build_errors.test.ts new file mode 100644 index 00000000000000..2424d807aa4732 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/build_errors.test.ts @@ -0,0 +1,141 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { buildErrors } from './build_errors'; +import assert from 'assert'; + +describe(__filename, () => { + describe('buildErrors', () => { + test('Metricbeat: it should build an object containing dedup error messages per event.dataset', () => { + const metricbeatErrors = [ + { + key: 'beat', + errors_by_dataset: { + buckets: [ + { + key: 'state', + latest_docs: { + hits: { + hits: [ + { + _source: { + '@timestamp': '2022-07-26T08:43:32.625Z', + error: { + message: + 'error making http request: Get "http://host.docker.internal:5067/state": dial tcp 192.168.65.2:5067: connect: connection refused', + }, + }, + }, + { + _source: { + '@timestamp': '2022-07-26T08:42:32.625Z', + error: { + message: + 'error making http request: Get "http://host.docker.internal:5067/state": dial tcp 192.168.65.2:5067: connect: connection refused', + }, + }, + }, + { + _source: { + '@timestamp': '2022-07-26T08:41:32.625Z', + error: { + message: 'Generic random error', + }, + }, + }, + ], + }, + }, + }, + ], + }, + }, + ]; + + const monitoredClusters = buildErrors(metricbeatErrors); + assert.deepEqual(monitoredClusters, { + beat: { + state: [ + { + lastSeen: '2022-07-26T08:43:32.625Z', + message: + 'error making http request: Get "http://host.docker.internal:5067/state": dial tcp 192.168.65.2:5067: connect: connection refused', + }, + { + lastSeen: '2022-07-26T08:41:32.625Z', + message: 'Generic random error', + }, + ], + }, + }); + }); + + test('Packages: it should build an object containing dedup error messages per event.dataset', () => { + const packageErrors = [ + { + key: 'elasticsearch', + errors_by_dataset: { + buckets: [ + { + key: 'state', + latest_docs: { + hits: { + hits: [ + { + _source: { + '@timestamp': '2023-01-10T14:39:37.114Z', + error: { + message: + 'error making http request: Get "https://localhost:9200/_nodes/_local": dial tcp [::1]:9200: connect: cannot assign requested address', + }, + }, + }, + { + _source: { + '@timestamp': '2023-01-10T14:39:27.114Z', + error: { + message: + 'error making http request: Get "https://localhost:9200/_nodes/_local": dial tcp [::1]:9200: connect: cannot assign requested address', + }, + }, + }, + { + _source: { + '@timestamp': '2022-07-26T08:41:32.625Z', + error: { + message: 'Generic random error', + }, + }, + }, + ], + }, + }, + }, + ], + }, + }, + ]; + + const monitoredClusters = buildErrors(packageErrors); + assert.deepEqual(monitoredClusters, { + elasticsearch: { + state: [ + { + lastSeen: '2023-01-10T14:39:37.114Z', + message: + 'error making http request: Get "https://localhost:9200/_nodes/_local": dial tcp [::1]:9200: connect: cannot assign requested address', + }, + { + lastSeen: '2022-07-26T08:41:32.625Z', + message: 'Generic random error', + }, + ], + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/build_metricbeat_errors.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/build_errors.ts similarity index 84% rename from x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/build_metricbeat_errors.ts rename to x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/build_errors.ts index 44f0df8c067cc1..9e9704828548be 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/build_metricbeat_errors.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/build_errors.ts @@ -5,10 +5,10 @@ * 2.0. */ -import type { MetricbeatMonitoredProduct } from '../types'; +import type { MonitoredProduct } from '../types'; -export type MetricbeatProducts = { - [product in MetricbeatMonitoredProduct]?: ErrorsByMetricset; +export type Products = { + [product in MonitoredProduct]?: ErrorsByMetricset; }; interface ErrorsByMetricset { @@ -21,14 +21,14 @@ interface ErrorDetails { } /** - * builds a normalized representation of the metricbeat errors from the provided + * builds a normalized representation of the metricbeat and integration package errors from the provided * query buckets with a product->metricset hierarchy where * product: the monitored products (eg elasticsearch) * metricset: the collected metricsets for a given entity * * example: * { - * "product": { + * "products": { * "logstash": { * "node": { * "message": "some error message", @@ -38,7 +38,7 @@ interface ErrorDetails { * } * } */ -export const buildMetricbeatErrors = (modulesBucket: any[]): MetricbeatProducts => { +export const buildErrors = (modulesBucket: any[]): Products => { return (modulesBucket ?? []).reduce((module, { key, errors_by_dataset: errorsByDataset }) => { const datasets = buildMetricsets(errorsByDataset.buckets); if (Object.keys(datasets).length === 0) { @@ -49,7 +49,7 @@ export const buildMetricbeatErrors = (modulesBucket: any[]): MetricbeatProducts ...module, [key]: datasets, }; - }, {} as MetricbeatProducts); + }, {} as Products); }; const buildMetricsets = (errorsByDataset: any[]): ErrorsByMetricset => { diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/metricbeat_errors_query.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/errors_query.ts similarity index 53% rename from x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/metricbeat_errors_query.ts rename to x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/errors_query.ts index 28d1b5cc8d2271..0c2fd16bf487cc 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/metricbeat_errors_query.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/errors_helpers/errors_query.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { MetricbeatMonitoredProduct, QueryOptions } from '../types'; +import type { MetricbeatMonitoredProduct, PackagesMonitoredProduct, QueryOptions } from '../types'; const MAX_BUCKET_SIZE = 50; @@ -13,16 +13,20 @@ const MAX_BUCKET_SIZE = 50; * Returns a nested aggregation of error messages per event.datasets. * Each module (beats, kibana...) can contain one or multiple metricsets with error messages */ -interface MetricbeatErrorsQueryOptions extends QueryOptions { - products: MetricbeatMonitoredProduct[]; +interface ErrorsQueryOptions extends QueryOptions { + products: MetricbeatMonitoredProduct[] | PackagesMonitoredProduct[]; + errorQueryType: 'metricbeatErrorsQuery' | 'packageErrorsQuery'; + errorQueryIsDataStream?: boolean; } -export const metricbeatErrorsQuery = ({ +export const errorsQuery = ({ timeRange, timeout, products, -}: MetricbeatErrorsQueryOptions) => { - if (!timeRange) throw new Error('metricbeatErrorsQuery: missing timeRange parameter'); + errorQueryType, + errorQueryIsDataStream, +}: ErrorsQueryOptions) => { + if (!timeRange) throw new Error(`${errorQueryType}: missing timeRange parameter`); return { timeout: `${timeout}s`, query: { @@ -37,7 +41,8 @@ export const metricbeatErrorsQuery = ({ }, { terms: { - 'event.module': Object.values(products), + [errorQueryIsDataStream ? 'service.type' : 'event.module']: + Object.values(products), }, }, { @@ -54,7 +59,7 @@ export const metricbeatErrorsQuery = ({ }, }, aggs: { - errors_aggregation: errorsAggregation, + errors_aggregation: errorsAggregation(errorQueryIsDataStream), }, }; }; @@ -82,11 +87,34 @@ const errorsByMetricset = { }, }; -const errorsAggregation = { +const errorsByDataStream = { terms: { - field: 'event.module', + field: 'data_stream.dataset', }, aggs: { - errors_by_dataset: errorsByMetricset, + latest_docs: { + top_hits: { + sort: [ + { + '@timestamp': { + order: 'desc', + }, + }, + ], + size: MAX_BUCKET_SIZE, + _source: { + includes: ['@timestamp', 'error', 'data_stream'], + }, + }, + }, }, }; + +const errorsAggregation = (errorQueryIsDataStream?: boolean) => ({ + terms: { + field: errorQueryIsDataStream ? 'service.type' : 'event.module', + }, + aggs: { + errors_by_dataset: errorQueryIsDataStream ? errorsByDataStream : errorsByMetricset, + }, +}); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/index.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/index.ts index aa05b442dca1ae..1b5f7e7eac2942 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/_health/index.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/index.ts @@ -8,13 +8,14 @@ import type { LegacyRequest, MonitoringCore } from '../../../../types'; import type { MonitoringConfig } from '../../../../config'; import { createValidationFunction } from '../../../../lib/create_route_validation_function'; -import { getIndexPatterns } from '../../../../lib/cluster/get_index_patterns'; +import { getIndexPatterns, getDsIndexPattern } from '../../../../lib/cluster/get_index_patterns'; import { getHealthRequestQueryRT } from '../../../../../common/http_api/_health'; import type { TimeRange } from '../../../../../common/http_api/shared'; import { fetchMonitoredClusters } from './monitored_clusters'; import { fetchMetricbeatErrors } from './metricbeat'; import type { FetchParameters } from './types'; +import { fetchPackageErrors } from './package/fetch_package_errors'; const DEFAULT_QUERY_TIMERANGE = { min: 'now-15m', max: 'now' }; const DEFAULT_QUERY_TIMEOUT_SECONDS = 15; @@ -53,6 +54,14 @@ export function registerV1HealthRoute(server: MonitoringCore) { getIndexPatterns({ config, moduleType: 'logstash' }), getIndexPatterns({ config, moduleType: 'beats' }), ].join(','); + + const metricsPackageIndex = [ + getDsIndexPattern({ config, moduleType: 'elasticsearch' }), + getDsIndexPattern({ config, moduleType: 'kibana' }), + getDsIndexPattern({ config, moduleType: 'logstash' }), + getDsIndexPattern({ config, moduleType: 'beats' }), + ].join(','); + const entSearchIndex = getIndexPatterns({ config, moduleType: 'enterprise_search' }); const monitoredClustersFn = () => @@ -74,12 +83,22 @@ export function registerV1HealthRoute(server: MonitoringCore) { return { error: err.message }; }); - const [monitoredClusters, metricbeatErrors] = await Promise.all([ + const packageErrorsFn = () => + fetchPackageErrors({ + ...fetchArgs, + packageIndex: metricsPackageIndex, + }).catch((err: Error) => { + logger.error(`_health: failed to retrieve package data:\n${err.stack}`); + return { error: err.message }; + }); + + const [monitoredClusters, metricbeatErrors, packageErrors] = await Promise.all([ monitoredClustersFn(), metricbeatErrorsFn(), + packageErrorsFn(), ]); - return { monitoredClusters, metricbeatErrors, settings }; + return { monitoredClusters, metricbeatErrors, packageErrors, settings }; }, }); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/build_metricbeat_errors.test.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/build_metricbeat_errors.test.ts deleted file mode 100644 index ea14de84735ef8..00000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/build_metricbeat_errors.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { buildMetricbeatErrors } from './build_metricbeat_errors'; -import assert from 'assert'; - -describe(__filename, () => { - describe('buildMetricbeatErrors', () => { - test('it should build an object containing dedup error messages per event.dataset', () => { - const metricbeatErrors = [ - { - key: 'beat', - errors_by_dataset: { - buckets: [ - { - key: 'state', - latest_docs: { - hits: { - hits: [ - { - _source: { - '@timestamp': '2022-07-26T08:43:32.625Z', - error: { - message: - 'error making http request: Get "http://host.docker.internal:5067/state": dial tcp 192.168.65.2:5067: connect: connection refused', - }, - }, - }, - { - _source: { - '@timestamp': '2022-07-26T08:42:32.625Z', - error: { - message: - 'error making http request: Get "http://host.docker.internal:5067/state": dial tcp 192.168.65.2:5067: connect: connection refused', - }, - }, - }, - { - _source: { - '@timestamp': '2022-07-26T08:41:32.625Z', - error: { - message: 'Generic random error', - }, - }, - }, - ], - }, - }, - }, - ], - }, - }, - ]; - - const monitoredClusters = buildMetricbeatErrors(metricbeatErrors); - assert.deepEqual(monitoredClusters, { - beat: { - state: [ - { - lastSeen: '2022-07-26T08:43:32.625Z', - message: - 'error making http request: Get "http://host.docker.internal:5067/state": dial tcp 192.168.65.2:5067: connect: connection refused', - }, - { - lastSeen: '2022-07-26T08:41:32.625Z', - message: 'Generic random error', - }, - ], - }, - }); - }); - }); -}); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/fetch_metricbeat_errors.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/fetch_metricbeat_errors.ts index ed445c1658c3b9..3c864004f783ea 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/fetch_metricbeat_errors.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/metricbeat/fetch_metricbeat_errors.ts @@ -7,13 +7,13 @@ import { FetchParameters, FetchExecution, MonitoredProduct } from '../types'; -import type { MetricbeatProducts } from './build_metricbeat_errors'; +import type { Products } from '../errors_helpers/build_errors'; -import { metricbeatErrorsQuery } from './metricbeat_errors_query'; -import { buildMetricbeatErrors } from './build_metricbeat_errors'; +import { errorsQuery } from '../errors_helpers/errors_query'; +import { buildErrors } from '../errors_helpers/build_errors'; interface MetricbeatResponse { - products?: MetricbeatProducts; + products?: Products; execution: FetchExecution; } @@ -29,7 +29,7 @@ export const fetchMetricbeatErrors = async ({ const getMetricbeatErrors = async () => { const { aggregations, timed_out: timedOut } = await search({ index: metricbeatIndex, - body: metricbeatErrorsQuery({ + body: errorsQuery({ timeRange, timeout, products: [ @@ -39,12 +39,13 @@ export const fetchMetricbeatErrors = async ({ MonitoredProduct.Kibana, MonitoredProduct.Logstash, ], + errorQueryType: 'metricbeatErrorsQuery', }), size: 0, ignore_unavailable: true, }); const buckets = aggregations?.errors_aggregation?.buckets ?? []; - return { products: buildMetricbeatErrors(buckets), timedOut: Boolean(timedOut) }; + return { products: buildErrors(buckets), timedOut: Boolean(timedOut) }; }; try { diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/fetch_package_errors.test.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/fetch_package_errors.test.ts new file mode 100644 index 00000000000000..fe2c7dc2f8ac7a --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/fetch_package_errors.test.ts @@ -0,0 +1,143 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 assert from 'assert'; +import sinon from 'sinon'; +import type { Logger } from '@kbn/core/server'; +import { fetchPackageErrors } from './fetch_package_errors'; + +const getMockLogger = () => + ({ + warn: sinon.spy(), + error: sinon.spy(), + } as unknown as Logger); + +describe(__filename, () => { + describe('fetchPackageErrors', () => { + test('it fetch and build package errors response', async () => { + const response = { + aggregations: { + errors_aggregation: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'elasticsearch', + doc_count: 22, + errors_by_dataset: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'elasticsearch.stack_monitoring.pending_tasks', + doc_count: 22, + latest_docs: { + hits: { + total: { + value: 22, + relation: 'eq', + }, + max_score: null, + hits: [ + { + _index: + '.ds-metrics-elasticsearch.stack_monitoring.node-default-2023.01.10-000001', + _id: '-oAfnIUB94omKO-pWCeN', + _score: null, + _source: { + '@timestamp': '2023-01-10T14:39:37.114Z', + metricset: { + period: 10000, + name: 'node', + }, + error: { + message: + 'error making http request: Get "https://localhost:9200/_nodes/_local": dial tcp [::1]:9200: connect: cannot assign requested address', + }, + }, + }, + ], + }, + }, + }, + { + key: 'elasticsearch.stack_monitoring.node', + doc_count: 22, + latest_docs: { + hits: { + total: { + value: 22, + relation: 'eq', + }, + max_score: null, + hits: [ + { + _index: + '.ds-metrics-elasticsearch.stack_monitoring.node-default-2023.01.10-000001', + _id: '-oAfnIUB94omKO-pWCeN', + _score: null, + _source: { + '@timestamp': '2023-01-10T14:39:37.156Z', + metricset: { + period: 10000, + name: 'node', + }, + error: { + message: + 'error making http request: Get "https://localhost:9200/_nodes/_local": dial tcp [::1]:9200: connect: cannot assign requested address', + }, + }, + }, + ], + }, + }, + }, + ], + }, + }, + ], + }, + }, + }; + + const searchFn = jest.fn().mockResolvedValueOnce(response); + + const monitoredClusters = await fetchPackageErrors({ + timeout: 10, + timeRange: { min: 1673361577110, max: 1673361567118 }, + packageIndex: 'metrics-*', + search: searchFn, + logger: getMockLogger(), + }); + + assert.deepEqual(monitoredClusters, { + execution: { + timedOut: false, + errors: [], + }, + products: { + elasticsearch: { + 'elasticsearch.stack_monitoring.node': [ + { + message: + 'error making http request: Get "https://localhost:9200/_nodes/_local": dial tcp [::1]:9200: connect: cannot assign requested address', + lastSeen: '2023-01-10T14:39:37.156Z', + }, + ], + 'elasticsearch.stack_monitoring.pending_tasks': [ + { + message: + 'error making http request: Get "https://localhost:9200/_nodes/_local": dial tcp [::1]:9200: connect: cannot assign requested address', + lastSeen: '2023-01-10T14:39:37.114Z', + }, + ], + }, + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/fetch_package_errors.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/fetch_package_errors.ts new file mode 100644 index 00000000000000..122c375dc9d252 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/fetch_package_errors.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 { FetchParameters, FetchExecution, MonitoredProduct } from '../types'; + +import type { Products } from '../errors_helpers/build_errors'; + +import { errorsQuery } from '../errors_helpers/errors_query'; +import { buildErrors } from '../errors_helpers/build_errors'; + +interface PackageResponse { + products?: Products; + execution: FetchExecution; +} + +export const fetchPackageErrors = async ({ + timeout, + timeRange, + search, + logger, + packageIndex, +}: FetchParameters & { + packageIndex: string; +}): Promise => { + const getPackageErrors = async () => { + const { aggregations, timed_out: timedOut } = await search({ + index: packageIndex, + body: errorsQuery({ + timeRange, + timeout, + products: [ + MonitoredProduct.Beats, + MonitoredProduct.Elasticsearch, + MonitoredProduct.Kibana, + MonitoredProduct.Logstash, + ], + errorQueryType: 'packageErrorsQuery', + errorQueryIsDataStream: true, + }), + size: 0, + ignore_unavailable: true, + }); + const buckets = aggregations?.errors_aggregation?.buckets ?? []; + return { products: buildErrors(buckets), timedOut: Boolean(timedOut) }; + }; + + try { + const { products, timedOut } = await getPackageErrors(); + return { + products, + execution: { + timedOut, + errors: [], + }, + }; + } catch (err) { + logger.error(`fetchPackageErrors: failed to fetch:\n${err.stack}`); + return { + execution: { + timedOut: false, + errors: [err.message], + }, + }; + } +}; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/index.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/index.ts new file mode 100644 index 00000000000000..84e020965e80c5 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/package/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 { fetchPackageErrors } from './fetch_package_errors'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/_health/types.ts b/x-pack/plugins/monitoring/server/routes/api/v1/_health/types.ts index 7d3db44aeac746..df9abf1a0aa6c6 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/_health/types.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/_health/types.ts @@ -18,6 +18,10 @@ export enum MonitoredProduct { EnterpriseSearch = 'enterpriseSearch', } export type MetricbeatMonitoredProduct = Exclude; +export type PackagesMonitoredProduct = Exclude< + MetricbeatMonitoredProduct, + MonitoredProduct.EnterpriseSearch +>; export type SearchFn = (params: any) => Promise; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts index 8aace1b7a2a1fd..f6187e1117f993 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts @@ -119,6 +119,18 @@ export function getSyntheticsKPIConfig({ dataView }: ConfigProps): SeriesConfig }, ], }, + { + label: 'Total runs', + id: 'monitor.check_group', + field: 'monitor.check_group', + columnType: OPERATION_COLUMN, + columnFilters: [ + { + language: 'kuery', + query: `summary: *`, + }, + ], + }, { field: SUMMARY_UP, id: SUMMARY_UP, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/single_metric_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/single_metric_config.ts index 41cb58c978ae4a..7e19ae43b37bdb 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/single_metric_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/single_metric_config.ts @@ -103,7 +103,7 @@ export function getSyntheticsSingleMetricConfig({ dataView }: ConfigProps): Seri titlePosition: 'bottom', }, columnType: FORMULA_COLUMN, - formula: 'unique_count(monitor.check_group)', + formula: "unique_count(monitor.check_group, kql='summary: *')", format: 'number', }, { diff --git a/x-pack/plugins/observability/server/assets/component_templates/slo_mappings_template.ts b/x-pack/plugins/observability/server/assets/component_templates/slo_mappings_template.ts index 96d3564f18ca95..faf415a3d91e8e 100644 --- a/x-pack/plugins/observability/server/assets/component_templates/slo_mappings_template.ts +++ b/x-pack/plugins/observability/server/assets/component_templates/slo_mappings_template.ts @@ -29,6 +29,9 @@ export const getSLOMappingsTemplate = (name: string) => ({ denominator: { type: 'long', }, + isGoodSlice: { + type: 'byte', + }, context: { type: 'flattened', }, diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/duration.ts b/x-pack/plugins/observability/server/services/slo/fixtures/duration.ts index 0086754150e8d7..3d13bc1042b3e4 100644 --- a/x-pack/plugins/observability/server/services/slo/fixtures/duration.ts +++ b/x-pack/plugins/observability/server/services/slo/fixtures/duration.ts @@ -22,3 +22,11 @@ export function sixHours(): Duration { export function oneMinute(): Duration { return new Duration(1, DurationUnit.Minute); } + +export function twoMinute(): Duration { + return new Duration(2, DurationUnit.Minute); +} + +export function fiveMinute(): Duration { + return new Duration(5, DurationUnit.Minute); +} diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts index b040254d570b25..c2fa25f05b13ce 100644 --- a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts +++ b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts @@ -22,7 +22,7 @@ import { StoredSLO, } from '../../../domain/models'; import { Paginated } from '../slo_repository'; -import { sevenDays } from './duration'; +import { sevenDays, twoMinute } from './duration'; import { sevenDaysRolling } from './time_window'; export const createAPMTransactionErrorRateIndicator = ( @@ -108,6 +108,18 @@ export const createSLO = (params: Partial = {}): SLO => { }); }; +export const createSLOWithTimeslicesBudgetingMethod = (params: Partial = {}): SLO => { + return createSLO({ + budgetingMethod: 'timeslices', + objective: { + target: 0.98, + timesliceTarget: 0.95, + timesliceWindow: twoMinute(), + }, + ...params, + }); +}; + export const createSLOWithCalendarTimeWindow = (params: Partial = {}): SLO => { return createSLO({ timeWindow: { diff --git a/x-pack/plugins/observability/server/services/slo/sli_client.test.ts b/x-pack/plugins/observability/server/services/slo/sli_client.test.ts index 163e2397480501..17965b36fc9cde 100644 --- a/x-pack/plugins/observability/server/services/slo/sli_client.test.ts +++ b/x-pack/plugins/observability/server/services/slo/sli_client.test.ts @@ -226,47 +226,14 @@ describe('SLIClient', () => { }, }, aggs: { - slices: { - date_histogram: { - field: '@timestamp', - fixed_interval: '10m', - }, - aggs: { - good: { - sum: { - field: 'slo.numerator', - }, - }, - total: { - sum: { - field: 'slo.denominator', - }, - }, - good_slice: { - bucket_script: { - buckets_path: { - good: 'good', - total: 'total', - }, - script: `params.good / params.total >= ${slo.objective.timesliceTarget} ? 1 : 0`, - }, - }, - count_slice: { - bucket_script: { - buckets_path: {}, - script: '1', - }, - }, - }, - }, good: { - sum_bucket: { - buckets_path: 'slices>good_slice.value', + sum: { + field: 'slo.isGoodSlice', }, }, total: { - sum_bucket: { - buckets_path: 'slices>count_slice.value', + value_count: { + field: 'slo.isGoodSlice', }, }, }, @@ -314,47 +281,14 @@ describe('SLIClient', () => { }, }, aggs: { - slices: { - date_histogram: { - field: '@timestamp', - fixed_interval: '10m', - }, - aggs: { - good: { - sum: { - field: 'slo.numerator', - }, - }, - total: { - sum: { - field: 'slo.denominator', - }, - }, - good_slice: { - bucket_script: { - buckets_path: { - good: 'good', - total: 'total', - }, - script: `params.good / params.total >= ${slo.objective.timesliceTarget} ? 1 : 0`, - }, - }, - count_slice: { - bucket_script: { - buckets_path: {}, - script: '1', - }, - }, - }, - }, good: { - sum_bucket: { - buckets_path: 'slices>good_slice.value', + sum: { + field: 'slo.isGoodSlice', }, }, total: { - sum_bucket: { - buckets_path: 'slices>count_slice.value', + value_count: { + field: 'slo.isGoodSlice', }, }, }, @@ -519,47 +453,14 @@ describe('SLIClient', () => { ranges: [{ from: 'now-1h/m', to: 'now/m' }], }, aggs: { - slices: { - date_histogram: { - field: '@timestamp', - fixed_interval: '10m', - }, - aggs: { - good: { - sum: { - field: 'slo.numerator', - }, - }, - total: { - sum: { - field: 'slo.denominator', - }, - }, - good_slice: { - bucket_script: { - buckets_path: { - good: 'good', - total: 'total', - }, - script: 'params.good / params.total >= 0.9 ? 1 : 0', - }, - }, - count_slice: { - bucket_script: { - buckets_path: {}, - script: '1', - }, - }, - }, - }, good: { - sum_bucket: { - buckets_path: 'slices>good_slice.value', + sum: { + field: 'slo.isGoodSlice', }, }, total: { - sum_bucket: { - buckets_path: 'slices>count_slice.value', + value_count: { + field: 'slo.isGoodSlice', }, }, }, @@ -570,47 +471,14 @@ describe('SLIClient', () => { ranges: [{ from: 'now-5m/m', to: 'now/m' }], }, aggs: { - slices: { - date_histogram: { - field: '@timestamp', - fixed_interval: '10m', - }, - aggs: { - good: { - sum: { - field: 'slo.numerator', - }, - }, - total: { - sum: { - field: 'slo.denominator', - }, - }, - good_slice: { - bucket_script: { - buckets_path: { - good: 'good', - total: 'total', - }, - script: 'params.good / params.total >= 0.9 ? 1 : 0', - }, - }, - count_slice: { - bucket_script: { - buckets_path: {}, - script: '1', - }, - }, - }, - }, good: { - sum_bucket: { - buckets_path: 'slices>good_slice.value', + sum: { + field: 'slo.isGoodSlice', }, }, total: { - sum_bucket: { - buckets_path: 'slices>count_slice.value', + value_count: { + field: 'slo.isGoodSlice', }, }, }, @@ -636,6 +504,7 @@ expect.extend({ }; }, }); + declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace jest { diff --git a/x-pack/plugins/observability/server/services/slo/sli_client.ts b/x-pack/plugins/observability/server/services/slo/sli_client.ts index d229d6fb66a6c2..07e63ef768845e 100644 --- a/x-pack/plugins/observability/server/services/slo/sli_client.ts +++ b/x-pack/plugins/observability/server/services/slo/sli_client.ts @@ -126,39 +126,14 @@ function generateSearchQuery(slo: SLO, dateRange: DateRange): MsearchMultisearch return { ...commonQuery(slo, dateRange), aggs: { - slices: { - date_histogram: { - field: '@timestamp', - fixed_interval: toInterval(slo.objective.timesliceWindow), - }, - aggs: { - good: { sum: { field: 'slo.numerator' } }, - total: { sum: { field: 'slo.denominator' } }, - good_slice: { - bucket_script: { - buckets_path: { - good: 'good', - total: 'total', - }, - script: `params.good / params.total >= ${slo.objective.timesliceTarget} ? 1 : 0`, - }, - }, - count_slice: { - bucket_script: { - buckets_path: {}, - script: '1', - }, - }, - }, - }, good: { - sum_bucket: { - buckets_path: 'slices>good_slice.value', + sum: { + field: 'slo.isGoodSlice', }, }, total: { - sum_bucket: { - buckets_path: 'slices>count_slice.value', + value_count: { + field: 'slo.isGoodSlice', }, }, }, @@ -240,47 +215,14 @@ function toLookbackWindowsSlicedAggregationsQuery(slo: SLO, lookbackWindows: Loo ], }, aggs: { - slices: { - date_histogram: { - field: '@timestamp', - fixed_interval: toInterval(slo.objective.timesliceWindow), - }, - aggs: { - good: { - sum: { - field: 'slo.numerator', - }, - }, - total: { - sum: { - field: 'slo.denominator', - }, - }, - good_slice: { - bucket_script: { - buckets_path: { - good: 'good', - total: 'total', - }, - script: `params.good / params.total >= ${slo.objective.timesliceTarget} ? 1 : 0`, - }, - }, - count_slice: { - bucket_script: { - buckets_path: {}, - script: '1', - }, - }, - }, - }, good: { - sum_bucket: { - buckets_path: 'slices>good_slice.value', + sum: { + field: 'slo.isGoodSlice', }, }, total: { - sum_bucket: { - buckets_path: 'slices>count_slice.value', + value_count: { + field: 'slo.isGoodSlice', }, }, }, @@ -320,9 +262,3 @@ function handleWindowedResult( return indicatorDataPerLookbackWindow; } - -function toInterval(duration: Duration | undefined): string { - if (duration === undefined) return '1m'; - - return duration.format(); -} diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap index 3b30834d985c95..3802416f29ff53 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap @@ -21,7 +21,194 @@ Object { } `; -exports[`APM Transaction Duration Transform Generator returns the correct transform params with every specified indicator params 1`] = ` +exports[`APM Transaction Duration Transform Generator returns the expected transform params for timeslices slo 1`] = ` +Object { + "_meta": Object { + "version": 1, + }, + "dest": Object { + "index": "slo-observability.sli-v1", + "pipeline": "slo-observability.sli.monthly", + }, + "frequency": "1m", + "pivot": Object { + "aggregations": Object { + "_numerator": Object { + "range": Object { + "field": "transaction.duration.histogram", + "ranges": Array [ + Object { + "to": 500000, + }, + ], + }, + }, + "slo.denominator": Object { + "value_count": Object { + "field": "transaction.duration.histogram", + }, + }, + "slo.isGoodSlice": Object { + "bucket_script": Object { + "buckets_path": Object { + "goodEvents": "slo.numerator.value", + "totalEvents": "slo.denominator.value", + }, + "script": "params.goodEvents / params.totalEvents >= 0.95 ? 1 : 0", + }, + }, + "slo.numerator": Object { + "bucket_script": Object { + "buckets_path": Object { + "numerator": "_numerator['*-500000.0']>_count", + }, + "script": "params.numerator", + }, + }, + }, + "group_by": Object { + "@timestamp": Object { + "date_histogram": Object { + "field": "@timestamp", + "fixed_interval": "2m", + }, + }, + "slo._internal.budgeting_method": Object { + "terms": Object { + "field": "slo._internal.budgeting_method", + }, + }, + "slo._internal.name": Object { + "terms": Object { + "field": "slo._internal.name", + }, + }, + "slo._internal.objective.target": Object { + "terms": Object { + "field": "slo._internal.objective.target", + }, + }, + "slo._internal.time_window.duration": Object { + "terms": Object { + "field": "slo._internal.time_window.duration", + }, + }, + "slo._internal.time_window.is_rolling": Object { + "terms": Object { + "field": "slo._internal.time_window.is_rolling", + }, + }, + "slo.id": Object { + "terms": Object { + "field": "slo.id", + }, + }, + "slo.revision": Object { + "terms": Object { + "field": "slo.revision", + }, + }, + }, + }, + "settings": Object { + "deduce_mappings": false, + }, + "source": Object { + "index": "metrics-apm*", + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "match": Object { + "transaction.root": true, + }, + }, + Object { + "range": Object { + "@timestamp": Object { + "gte": "now-7d", + }, + }, + }, + Object { + "match": Object { + "service.name": "irrelevant", + }, + }, + Object { + "match": Object { + "service.environment": "irrelevant", + }, + }, + Object { + "match": Object { + "transaction.name": "irrelevant", + }, + }, + Object { + "match": Object { + "transaction.type": "irrelevant", + }, + }, + ], + }, + }, + "runtime_mappings": Object { + "slo._internal.budgeting_method": Object { + "script": Object { + "source": "emit('timeslices')", + }, + "type": "keyword", + }, + "slo._internal.name": Object { + "script": Object { + "source": "emit('irrelevant')", + }, + "type": "keyword", + }, + "slo._internal.objective.target": Object { + "script": Object { + "source": "emit(0.98)", + }, + "type": "double", + }, + "slo._internal.time_window.duration": Object { + "script": Object { + "source": "emit('7d')", + }, + "type": "keyword", + }, + "slo._internal.time_window.is_rolling": Object { + "script": Object { + "source": "emit(true)", + }, + "type": "boolean", + }, + "slo.id": Object { + "script": Object { + "source": Any, + }, + "type": "keyword", + }, + "slo.revision": Object { + "script": Object { + "source": "emit(1)", + }, + "type": "long", + }, + }, + }, + "sync": Object { + "time": Object { + "delay": "1m", + "field": "@timestamp", + }, + }, + "transform_id": Any, +} +`; + +exports[`APM Transaction Duration Transform Generator returns the expected transform params with every specified indicator params 1`] = ` Object { "_meta": Object { "version": 1, @@ -60,8 +247,8 @@ Object { "group_by": Object { "@timestamp": Object { "date_histogram": Object { - "calendar_interval": "1m", "field": "@timestamp", + "fixed_interval": "1m", }, }, "slo._internal.budgeting_method": Object { diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap index acd7770c32746a..3a87b3031fdc0e 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap @@ -21,7 +21,199 @@ Object { } `; -exports[`APM Transaction Error Rate Transform Generator returns the correct transform params with every specified indicator params 1`] = ` +exports[`APM Transaction Error Rate Transform Generator returns the expected transform params for timeslices slo 1`] = ` +Object { + "_meta": Object { + "version": 1, + }, + "dest": Object { + "index": "slo-observability.sli-v1", + "pipeline": "slo-observability.sli.monthly", + }, + "frequency": "1m", + "pivot": Object { + "aggregations": Object { + "slo.denominator": Object { + "value_count": Object { + "field": "transaction.duration.histogram", + }, + }, + "slo.isGoodSlice": Object { + "bucket_script": Object { + "buckets_path": Object { + "goodEvents": "slo.numerator>_count", + "totalEvents": "slo.denominator.value", + }, + "script": "params.goodEvents / params.totalEvents >= 0.95 ? 1 : 0", + }, + }, + "slo.numerator": Object { + "filter": Object { + "bool": Object { + "should": Array [ + Object { + "match": Object { + "transaction.result": "HTTP 2xx", + }, + }, + Object { + "match": Object { + "transaction.result": "HTTP 3xx", + }, + }, + Object { + "match": Object { + "transaction.result": "HTTP 4xx", + }, + }, + ], + }, + }, + }, + }, + "group_by": Object { + "@timestamp": Object { + "date_histogram": Object { + "field": "@timestamp", + "fixed_interval": "2m", + }, + }, + "slo._internal.budgeting_method": Object { + "terms": Object { + "field": "slo._internal.budgeting_method", + }, + }, + "slo._internal.name": Object { + "terms": Object { + "field": "slo._internal.name", + }, + }, + "slo._internal.objective.target": Object { + "terms": Object { + "field": "slo._internal.objective.target", + }, + }, + "slo._internal.time_window.duration": Object { + "terms": Object { + "field": "slo._internal.time_window.duration", + }, + }, + "slo._internal.time_window.is_rolling": Object { + "terms": Object { + "field": "slo._internal.time_window.is_rolling", + }, + }, + "slo.id": Object { + "terms": Object { + "field": "slo.id", + }, + }, + "slo.revision": Object { + "terms": Object { + "field": "slo.revision", + }, + }, + }, + }, + "settings": Object { + "deduce_mappings": false, + }, + "source": Object { + "index": "metrics-apm*", + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "match": Object { + "transaction.root": true, + }, + }, + Object { + "range": Object { + "@timestamp": Object { + "gte": "now-7d", + }, + }, + }, + Object { + "match": Object { + "service.name": "irrelevant", + }, + }, + Object { + "match": Object { + "service.environment": "irrelevant", + }, + }, + Object { + "match": Object { + "transaction.name": "irrelevant", + }, + }, + Object { + "match": Object { + "transaction.type": "irrelevant", + }, + }, + ], + }, + }, + "runtime_mappings": Object { + "slo._internal.budgeting_method": Object { + "script": Object { + "source": "emit('timeslices')", + }, + "type": "keyword", + }, + "slo._internal.name": Object { + "script": Object { + "source": "emit('irrelevant')", + }, + "type": "keyword", + }, + "slo._internal.objective.target": Object { + "script": Object { + "source": "emit(0.98)", + }, + "type": "double", + }, + "slo._internal.time_window.duration": Object { + "script": Object { + "source": "emit('7d')", + }, + "type": "keyword", + }, + "slo._internal.time_window.is_rolling": Object { + "script": Object { + "source": "emit(true)", + }, + "type": "boolean", + }, + "slo.id": Object { + "script": Object { + "source": Any, + }, + "type": "keyword", + }, + "slo.revision": Object { + "script": Object { + "source": "emit(1)", + }, + "type": "long", + }, + }, + }, + "sync": Object { + "time": Object { + "delay": "1m", + "field": "@timestamp", + }, + }, + "transform_id": Any, +} +`; + +exports[`APM Transaction Error Rate Transform Generator returns the expected transform params with every specified indicator params 1`] = ` Object { "_meta": Object { "version": 1, @@ -65,8 +257,8 @@ Object { "group_by": Object { "@timestamp": Object { "date_histogram": Object { - "calendar_interval": "1m", "field": "@timestamp", + "fixed_interval": "1m", }, }, "slo._internal.budgeting_method": Object { diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap index 1aa05dfb2cf3bb..f984620b8eefbe 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap @@ -100,7 +100,166 @@ Object { } `; -exports[`KQL Custom Transform Generator returns the correct transform params with every specified indicator params 1`] = ` +exports[`KQL Custom Transform Generator returns the expected transform params for timeslices slo 1`] = ` +Object { + "_meta": Object { + "version": 1, + }, + "dest": Object { + "index": "slo-observability.sli-v1", + "pipeline": "slo-observability.sli.monthly", + }, + "frequency": "1m", + "pivot": Object { + "aggregations": Object { + "slo.denominator": Object { + "filter": Object { + "match_all": Object {}, + }, + }, + "slo.isGoodSlice": Object { + "bucket_script": Object { + "buckets_path": Object { + "goodEvents": "slo.numerator>_count", + "totalEvents": "slo.denominator>_count", + }, + "script": "params.goodEvents / params.totalEvents >= 0.95 ? 1 : 0", + }, + }, + "slo.numerator": Object { + "filter": Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "range": Object { + "latency": Object { + "lt": "300", + }, + }, + }, + ], + }, + }, + }, + }, + "group_by": Object { + "@timestamp": Object { + "date_histogram": Object { + "field": "@timestamp", + "fixed_interval": "2m", + }, + }, + "slo._internal.budgeting_method": Object { + "terms": Object { + "field": "slo._internal.budgeting_method", + }, + }, + "slo._internal.name": Object { + "terms": Object { + "field": "slo._internal.name", + }, + }, + "slo._internal.objective.target": Object { + "terms": Object { + "field": "slo._internal.objective.target", + }, + }, + "slo._internal.time_window.duration": Object { + "terms": Object { + "field": "slo._internal.time_window.duration", + }, + }, + "slo._internal.time_window.is_rolling": Object { + "terms": Object { + "field": "slo._internal.time_window.is_rolling", + }, + }, + "slo.id": Object { + "terms": Object { + "field": "slo.id", + }, + }, + "slo.revision": Object { + "terms": Object { + "field": "slo.revision", + }, + }, + }, + }, + "settings": Object { + "deduce_mappings": false, + }, + "source": Object { + "index": "my-index*", + "query": Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "labels.groupId": "group-3", + }, + }, + ], + }, + }, + "runtime_mappings": Object { + "slo._internal.budgeting_method": Object { + "script": Object { + "source": "emit('timeslices')", + }, + "type": "keyword", + }, + "slo._internal.name": Object { + "script": Object { + "source": "emit('irrelevant')", + }, + "type": "keyword", + }, + "slo._internal.objective.target": Object { + "script": Object { + "source": "emit(0.98)", + }, + "type": "double", + }, + "slo._internal.time_window.duration": Object { + "script": Object { + "source": "emit('7d')", + }, + "type": "keyword", + }, + "slo._internal.time_window.is_rolling": Object { + "script": Object { + "source": "emit(true)", + }, + "type": "boolean", + }, + "slo.id": Object { + "script": Object { + "source": Any, + }, + "type": "keyword", + }, + "slo.revision": Object { + "script": Object { + "source": "emit(1)", + }, + "type": "long", + }, + }, + }, + "sync": Object { + "time": Object { + "delay": "1m", + "field": "@timestamp", + }, + }, + "transform_id": Any, +} +`; + +exports[`KQL Custom Transform Generator returns the expected transform params with every specified indicator params 1`] = ` Object { "_meta": Object { "version": 1, @@ -137,8 +296,8 @@ Object { "group_by": Object { "@timestamp": Object { "date_histogram": Object { - "calendar_interval": "1m", "field": "@timestamp", + "fixed_interval": "1m", }, }, "slo._internal.budgeting_method": Object { diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.test.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.test.ts index a1fb9476d1882d..16a788888cc09f 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.test.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.test.ts @@ -5,13 +5,17 @@ * 2.0. */ -import { createAPMTransactionDurationIndicator, createSLO } from '../fixtures/slo'; +import { + createAPMTransactionDurationIndicator, + createSLO, + createSLOWithTimeslicesBudgetingMethod, +} from '../fixtures/slo'; import { ApmTransactionDurationTransformGenerator } from './apm_transaction_duration'; const generator = new ApmTransactionDurationTransformGenerator(); describe('APM Transaction Duration Transform Generator', () => { - it('returns the correct transform params with every specified indicator params', async () => { + it('returns the expected transform params with every specified indicator params', async () => { const anSLO = createSLO({ indicator: createAPMTransactionDurationIndicator() }); const transform = generator.getTransformParams(anSLO); @@ -28,6 +32,18 @@ describe('APM Transaction Duration Transform Generator', () => { }); }); + it('returns the expected transform params for timeslices slo', async () => { + const anSLO = createSLOWithTimeslicesBudgetingMethod({ + indicator: createAPMTransactionDurationIndicator(), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform).toMatchSnapshot({ + transform_id: expect.any(String), + source: { runtime_mappings: { 'slo.id': { script: { source: expect.any(String) } } } }, + }); + }); + it("does not include the query filter when params are '*'", async () => { const anSLO = createSLO({ indicator: createAPMTransactionDurationIndicator({ diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts index 4f06315c4c2d88..89e8b962d61af9 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts @@ -6,7 +6,11 @@ */ import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; -import { ALL_VALUE, apmTransactionDurationIndicatorSchema } from '@kbn/slo-schema'; +import { + ALL_VALUE, + apmTransactionDurationIndicatorSchema, + timeslicesBudgetingMethodSchema, +} from '@kbn/slo-schema'; import { InvalidTransformError } from '../../../errors'; import { SLO_DESTINATION_INDEX_NAME, @@ -30,7 +34,7 @@ export class ApmTransactionDurationTransformGenerator extends TransformGenerator this.buildSource(slo, slo.indicator), this.buildDestination(), this.buildCommonGroupBy(slo), - this.buildAggregations(slo.indicator), + this.buildAggregations(slo, slo.indicator), this.buildSettings(slo) ); } @@ -106,7 +110,7 @@ export class ApmTransactionDurationTransformGenerator extends TransformGenerator }; } - private buildAggregations(indicator: APMTransactionDurationIndicator) { + private buildAggregations(slo: SLO, indicator: APMTransactionDurationIndicator) { const truncatedThreshold = Math.trunc(indicator.params['threshold.us']); return { @@ -133,6 +137,17 @@ export class ApmTransactionDurationTransformGenerator extends TransformGenerator field: 'transaction.duration.histogram', }, }, + ...(timeslicesBudgetingMethodSchema.is(slo.budgetingMethod) && { + 'slo.isGoodSlice': { + bucket_script: { + buckets_path: { + goodEvents: 'slo.numerator.value', + totalEvents: 'slo.denominator.value', + }, + script: `params.goodEvents / params.totalEvents >= ${slo.objective.timesliceTarget} ? 1 : 0`, + }, + }, + }), }; } } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.test.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.test.ts index 2998c09efe84ec..1763cff5fab6d3 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.test.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.test.ts @@ -5,13 +5,17 @@ * 2.0. */ -import { createAPMTransactionErrorRateIndicator, createSLO } from '../fixtures/slo'; +import { + createAPMTransactionErrorRateIndicator, + createSLO, + createSLOWithTimeslicesBudgetingMethod, +} from '../fixtures/slo'; import { ApmTransactionErrorRateTransformGenerator } from './apm_transaction_error_rate'; const generator = new ApmTransactionErrorRateTransformGenerator(); describe('APM Transaction Error Rate Transform Generator', () => { - it('returns the correct transform params with every specified indicator params', async () => { + it('returns the expected transform params with every specified indicator params', async () => { const anSLO = createSLO({ indicator: createAPMTransactionErrorRateIndicator() }); const transform = generator.getTransformParams(anSLO); @@ -28,6 +32,18 @@ describe('APM Transaction Error Rate Transform Generator', () => { }); }); + it('returns the expected transform params for timeslices slo', async () => { + const anSLO = createSLOWithTimeslicesBudgetingMethod({ + indicator: createAPMTransactionErrorRateIndicator(), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform).toMatchSnapshot({ + transform_id: expect.any(String), + source: { runtime_mappings: { 'slo.id': { script: { source: expect.any(String) } } } }, + }); + }); + it("uses default values when 'good_status_codes' is not specified", async () => { const anSLO = createSLO({ indicator: createAPMTransactionErrorRateIndicator({ goodStatusCodes: [] }), diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts index 18cb0cd60298ae..8adcbcdfc96225 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts @@ -6,7 +6,11 @@ */ import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; -import { ALL_VALUE, apmTransactionErrorRateIndicatorSchema } from '@kbn/slo-schema'; +import { + ALL_VALUE, + apmTransactionErrorRateIndicatorSchema, + timeslicesBudgetingMethodSchema, +} from '@kbn/slo-schema'; import { InvalidTransformError } from '../../../errors'; import { getSLOTransformTemplate } from '../../../assets/transform_templates/slo_transform_template'; @@ -127,6 +131,17 @@ export class ApmTransactionErrorRateTransformGenerator extends TransformGenerato field: 'transaction.duration.histogram', }, }, + ...(timeslicesBudgetingMethodSchema.is(slo.budgetingMethod) && { + 'slo.isGoodSlice': { + bucket_script: { + buckets_path: { + goodEvents: 'slo.numerator>_count', + totalEvents: 'slo.denominator.value', + }, + script: `params.goodEvents / params.totalEvents >= ${slo.objective.timesliceTarget} ? 1 : 0`, + }, + }, + }), }; } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.test.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.test.ts index 5056cd35626576..df27929b5bf6b3 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.test.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { createKQLCustomIndicator, createSLO } from '../fixtures/slo'; +import { + createKQLCustomIndicator, + createSLO, + createSLOWithTimeslicesBudgetingMethod, +} from '../fixtures/slo'; import { KQLCustomTransformGenerator } from './kql_custom'; const generator = new KQLCustomTransformGenerator(); @@ -32,7 +36,7 @@ describe('KQL Custom Transform Generator', () => { }); }); - it('returns the correct transform params with every specified indicator params', async () => { + it('returns the expected transform params with every specified indicator params', async () => { const anSLO = createSLO({ indicator: createKQLCustomIndicator() }); const transform = generator.getTransformParams(anSLO); @@ -49,6 +53,18 @@ describe('KQL Custom Transform Generator', () => { }); }); + it('returns the expected transform params for timeslices slo', async () => { + const anSLO = createSLOWithTimeslicesBudgetingMethod({ + indicator: createKQLCustomIndicator(), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform).toMatchSnapshot({ + transform_id: expect.any(String), + source: { runtime_mappings: { 'slo.id': { script: { source: expect.any(String) } } } }, + }); + }); + it('filters the source using the kql query', async () => { const anSLO = createSLO({ indicator: createKQLCustomIndicator({ filter: 'labels.groupId: group-4' }), diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts index 1b776a552fbe9b..2b69c02e9d2c50 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts @@ -7,7 +7,7 @@ import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; -import { kqlCustomIndicatorSchema } from '@kbn/slo-schema'; +import { kqlCustomIndicatorSchema, timeslicesBudgetingMethodSchema } from '@kbn/slo-schema'; import { InvalidTransformError } from '../../../errors'; import { getSLOTransformTemplate } from '../../../assets/transform_templates/slo_transform_template'; @@ -58,6 +58,7 @@ export class KQLCustomTransformGenerator extends TransformGenerator { private buildAggregations(slo: SLO, indicator: KQLCustomIndicator) { const numerator = getElastichsearchQueryOrThrow(indicator.params.good); const denominator = getElastichsearchQueryOrThrow(indicator.params.total); + return { 'slo.numerator': { filter: numerator, @@ -65,6 +66,17 @@ export class KQLCustomTransformGenerator extends TransformGenerator { 'slo.denominator': { filter: denominator, }, + ...(timeslicesBudgetingMethodSchema.is(slo.budgetingMethod) && { + 'slo.isGoodSlice': { + bucket_script: { + buckets_path: { + goodEvents: 'slo.numerator>_count', + totalEvents: 'slo.denominator>_count', + }, + script: `params.goodEvents / params.totalEvents >= ${slo.objective.timesliceTarget} ? 1 : 0`, + }, + }, + }), }; } } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts index 1e009ea874b357..a62c81b165dbe0 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts @@ -6,11 +6,8 @@ */ import { MappingRuntimeFieldType } from '@elastic/elasticsearch/lib/api/types'; -import { - AggregationsCalendarInterval, - TransformPutTransformRequest, -} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { calendarAlignedTimeWindowSchema } from '@kbn/slo-schema'; +import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { calendarAlignedTimeWindowSchema, timeslicesBudgetingMethodSchema } from '@kbn/slo-schema'; import { TransformSettings } from '../../../assets/transform_templates/slo_transform_template'; import { SLO } from '../../../domain/models'; @@ -66,6 +63,11 @@ export abstract class TransformGenerator { } public buildCommonGroupBy(slo: SLO) { + let fixedInterval = '1m'; + if (timeslicesBudgetingMethodSchema.is(slo.budgetingMethod)) { + fixedInterval = slo.objective.timesliceWindow!.format(); + } + return { 'slo.id': { terms: { @@ -106,7 +108,7 @@ export abstract class TransformGenerator { '@timestamp': { date_histogram: { field: slo.settings.timestampField, - calendar_interval: '1m' as AggregationsCalendarInterval, + fixed_interval: fixedInterval, }, }, }; diff --git a/x-pack/plugins/observability/server/services/slo/update_slo.test.ts b/x-pack/plugins/observability/server/services/slo/update_slo.test.ts index 166ed2a319c77c..a100ece244b193 100644 --- a/x-pack/plugins/observability/server/services/slo/update_slo.test.ts +++ b/x-pack/plugins/observability/server/services/slo/update_slo.test.ts @@ -7,9 +7,15 @@ import { ElasticsearchClient } from '@kbn/core/server'; import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; + import { getSLOTransformId } from '../../assets/constants'; import { SLO } from '../../domain/models'; -import { createAPMTransactionErrorRateIndicator, createSLO } from './fixtures/slo'; +import { fiveMinute, oneMinute } from './fixtures/duration'; +import { + createAPMTransactionErrorRateIndicator, + createSLO, + createSLOWithTimeslicesBudgetingMethod, +} from './fixtures/slo'; import { createSLORepositoryMock, createTransformManagerMock } from './mocks'; import { SLORepository } from './slo_repository'; import { TransformManager } from './transform_manager'; @@ -67,6 +73,55 @@ describe('UpdateSLO', () => { expectInstallationOfNewSLOTransform(); }); + it('consideres a budgeting method change as a breaking change', async () => { + const slo = createSLO({ budgetingMethod: 'occurrences' }); + mockRepository.findById.mockResolvedValueOnce(slo); + + await updateSLO.execute(slo.id, { + budgetingMethod: 'timeslices', + objective: { + target: slo.objective.target, + timesliceTarget: 0.9, + timesliceWindow: oneMinute(), + }, + }); + + expectDeletionOfObsoleteSLOData(slo); + expectInstallationOfNewSLOTransform(); + }); + + it('consideres a timeslice target change as a breaking change', async () => { + const slo = createSLOWithTimeslicesBudgetingMethod(); + mockRepository.findById.mockResolvedValueOnce(slo); + + await updateSLO.execute(slo.id, { + objective: { + target: slo.objective.target, + timesliceTarget: 0.1, + timesliceWindow: slo.objective.timesliceWindow, + }, + }); + + expectDeletionOfObsoleteSLOData(slo); + expectInstallationOfNewSLOTransform(); + }); + + it('consideres a timeslice window change as a breaking change', async () => { + const slo = createSLOWithTimeslicesBudgetingMethod(); + mockRepository.findById.mockResolvedValueOnce(slo); + + await updateSLO.execute(slo.id, { + objective: { + target: slo.objective.target, + timesliceTarget: slo.objective.timesliceTarget, + timesliceWindow: fiveMinute(), + }, + }); + + expectDeletionOfObsoleteSLOData(slo); + expectInstallationOfNewSLOTransform(); + }); + it('removes the obsolete data from the SLO previous revision', async () => { const slo = createSLO({ indicator: createAPMTransactionErrorRateIndicator({ environment: 'development' }), diff --git a/x-pack/plugins/observability/server/services/slo/update_slo.ts b/x-pack/plugins/observability/server/services/slo/update_slo.ts index 02b3055fb0bf1b..9f03b12137ccba 100644 --- a/x-pack/plugins/observability/server/services/slo/update_slo.ts +++ b/x-pack/plugins/observability/server/services/slo/update_slo.ts @@ -49,6 +49,19 @@ export class UpdateSLO { hasBreakingChange = true; } + if (originalSlo.budgetingMethod !== updatedSlo.budgetingMethod) { + hasBreakingChange = true; + } + + if ( + originalSlo.budgetingMethod === 'timeslices' && + updatedSlo.budgetingMethod === 'timeslices' && + (originalSlo.objective.timesliceTarget !== updatedSlo.objective.timesliceTarget || + !deepEqual(originalSlo.objective.timesliceWindow, updatedSlo.objective.timesliceWindow)) + ) { + hasBreakingChange = true; + } + if (!deepEqual(originalSlo.settings, updatedSlo.settings)) { hasBreakingChange = true; } diff --git a/x-pack/plugins/profiling/common/columnar_view_model.ts b/x-pack/plugins/profiling/common/columnar_view_model.ts index cc20bd9ca9a0e0..20bf2b27618550 100644 --- a/x-pack/plugins/profiling/common/columnar_view_model.ts +++ b/x-pack/plugins/profiling/common/columnar_view_model.ts @@ -8,52 +8,7 @@ import { ColumnarViewModel } from '@elastic/charts'; import { ElasticFlameGraph } from './flamegraph'; - -/* - * Helper to calculate the color of a given block to be drawn. The desirable outcomes of this are: - * Each of the following frame types should get a different set of color hues: - * - * 0 = Unsymbolized frame - * 1 = Python - * 2 = PHP - * 3 = Native - * 4 = Kernel - * 5 = JVM/Hotspot - * 6 = Ruby - * 7 = Perl - * 8 = JavaScript - * 9 = PHP JIT - * - * This is most easily achieved by mapping frame types to different color variations, using - * the x-position we can use different colors for adjacent blocks while keeping a similar hue - * - * Taken originally from prodfiler_ui/src/helpers/Pixi/frameTypeToColors.tsx - */ -const frameTypeToColors = [ - [0xfd8484, 0xfd9d9d, 0xfeb5b5, 0xfecece], - [0xfcae6b, 0xfdbe89, 0xfdcea6, 0xfedfc4], - [0xfcdb82, 0xfde29b, 0xfde9b4, 0xfef1cd], - [0x6dd0dc, 0x8ad9e3, 0xa7e3ea, 0xc5ecf1], - [0x7c9eff, 0x96b1ff, 0xb0c5ff, 0xcbd8ff], - [0x65d3ac, 0x84dcbd, 0xa3e5cd, 0xc1edde], - [0xd79ffc, 0xdfb2fd, 0xe7c5fd, 0xefd9fe], - [0xf98bb9, 0xfaa2c7, 0xfbb9d5, 0xfdd1e3], - [0xcbc3e3, 0xd5cfe8, 0xdfdbee, 0xeae7f3], - [0xccfc82, 0xd1fc8e, 0xd6fc9b, 0xdbfca7], -]; - -function frameTypeToRGB(frameType: number, x: number): number { - return frameTypeToColors[frameType][x % 4]; -} - -export function rgbToRGBA(rgb: number): number[] { - return [ - Math.floor(rgb / 65536) / 255, - (Math.floor(rgb / 256) % 256) / 255, - (rgb % 256) / 255, - 1.0, - ]; -} +import { frameTypeToRGB, rgbToRGBA } from './frame_type_colors'; function normalize(n: number, lower: number, upper: number): number { return (n - lower) / (upper - lower); diff --git a/x-pack/plugins/profiling/common/frame_type_colors.ts b/x-pack/plugins/profiling/common/frame_type_colors.ts new file mode 100644 index 00000000000000..11c8cbaca9f306 --- /dev/null +++ b/x-pack/plugins/profiling/common/frame_type_colors.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { FrameType } from './profiling'; + +/* + * Helper to calculate the color of a given block to be drawn. The desirable outcomes of this are: + * Each of the following frame types should get a different set of color hues: + * + * 0 = Unsymbolized frame + * 1 = Python + * 2 = PHP + * 3 = Native + * 4 = Kernel + * 5 = JVM/Hotspot + * 6 = Ruby + * 7 = Perl + * 8 = JavaScript + * 9 = PHP JIT + * + * This is most easily achieved by mapping frame types to different color variations, using + * the x-position we can use different colors for adjacent blocks while keeping a similar hue + * + * Taken originally from prodfiler_ui/src/helpers/Pixi/frameTypeToColors.tsx + */ +export const FRAME_TYPE_COLOR_MAP = { + [FrameType.Unsymbolized]: [0xfd8484, 0xfd9d9d, 0xfeb5b5, 0xfecece], + [FrameType.Python]: [0xfcae6b, 0xfdbe89, 0xfdcea6, 0xfedfc4], + [FrameType.PHP]: [0xfcdb82, 0xfde29b, 0xfde9b4, 0xfef1cd], + [FrameType.Native]: [0x6dd0dc, 0x8ad9e3, 0xa7e3ea, 0xc5ecf1], + [FrameType.Kernel]: [0x7c9eff, 0x96b1ff, 0xb0c5ff, 0xcbd8ff], + [FrameType.JVM]: [0x65d3ac, 0x84dcbd, 0xa3e5cd, 0xc1edde], + [FrameType.Ruby]: [0xd79ffc, 0xdfb2fd, 0xe7c5fd, 0xefd9fe], + [FrameType.Perl]: [0xf98bb9, 0xfaa2c7, 0xfbb9d5, 0xfdd1e3], + [FrameType.JavaScript]: [0xcbc3e3, 0xd5cfe8, 0xdfdbee, 0xeae7f3], + [FrameType.PHPJIT]: [0xccfc82, 0xd1fc8e, 0xd6fc9b, 0xdbfca7], +}; + +export function frameTypeToRGB(frameType: FrameType, x: number): number { + return FRAME_TYPE_COLOR_MAP[frameType][x % 4]; +} + +export function rgbToRGBA(rgb: number): number[] { + return [ + Math.floor(rgb / 65536) / 255, + (Math.floor(rgb / 256) % 256) / 255, + (rgb % 256) / 255, + 1.0, + ]; +} diff --git a/x-pack/plugins/profiling/common/profiling.ts b/x-pack/plugins/profiling/common/profiling.ts index a7a5a890c6b5b4..aa0c114e51210c 100644 --- a/x-pack/plugins/profiling/common/profiling.ts +++ b/x-pack/plugins/profiling/common/profiling.ts @@ -59,6 +59,7 @@ export enum FrameType { Ruby, Perl, JavaScript, + PHPJIT, } const frameTypeDescriptions = { @@ -71,6 +72,7 @@ const frameTypeDescriptions = { [FrameType.Ruby]: 'Ruby', [FrameType.Perl]: 'Perl', [FrameType.JavaScript]: 'JavaScript', + [FrameType.PHPJIT]: 'PHP JIT', }; export function describeFrameType(ft: FrameType): string { diff --git a/x-pack/plugins/profiling/public/components/flame_graphs_view/flame_graph_legend.tsx b/x-pack/plugins/profiling/public/components/flame_graphs_view/flame_graph_legend.tsx new file mode 100644 index 00000000000000..7f63ecb9337f9b --- /dev/null +++ b/x-pack/plugins/profiling/public/components/flame_graphs_view/flame_graph_legend.tsx @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { asPercentage } from '../../utils/formatters/as_percentage'; +import { Legend, LegendItem } from '../legend'; + +export function FlameGraphLegend({ + legendItems, + asScale, +}: { + legendItems: LegendItem[]; + asScale: boolean; +}) { + if (asScale) { + return ( + + + + + + + + {i18n.translate('xpack.profiling.flameGraphLegend.improvement', { + defaultMessage: 'Improvement', + })} + + + + + {i18n.translate('xpack.profiling.flameGraphLegend.regression', { + defaultMessage: 'Regression', + })} + + + + + + + + + + +{asPercentage(1)} + + + + {legendItems.map(({ color, label }) => { + return ( + + {label ? ( + + {label} + + ) : ( + '' + )} + + ); + })} + + + + {asPercentage(-1)} + + + + + + + + + ); + } + + return ; +} diff --git a/x-pack/plugins/profiling/public/components/flamegraph.tsx b/x-pack/plugins/profiling/public/components/flamegraph.tsx index 09eba11eb6cd2f..82eded53e62b12 100644 --- a/x-pack/plugins/profiling/public/components/flamegraph.tsx +++ b/x-pack/plugins/profiling/public/components/flamegraph.tsx @@ -24,6 +24,7 @@ import { ElasticFlameGraph, FlameGraphComparisonMode } from '../../common/flameg import { asPercentage } from '../utils/formatters/as_percentage'; import { getFlamegraphModel } from '../utils/get_flamegraph_model'; import { FlamegraphInformationWindow } from './flame_graphs_view/flamegraph_information_window'; +import { FlameGraphLegend } from './flame_graphs_view/flame_graph_legend'; function TooltipRow({ value, @@ -321,6 +322,9 @@ export const FlameGraph: React.FC = ({ ) : undefined} + + + ); }; diff --git a/x-pack/plugins/profiling/public/components/legend.tsx b/x-pack/plugins/profiling/public/components/legend.tsx new file mode 100644 index 00000000000000..c69f84ee7031be --- /dev/null +++ b/x-pack/plugins/profiling/public/components/legend.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText } from '@elastic/eui'; +import React from 'react'; + +export interface LegendItem { + color: string; + label: string; +} + +export function Legend({ legendItems }: { legendItems: LegendItem[] }) { + return ( + + {legendItems.map(({ color, label }) => { + return ( + + + + + + + {label} + + + + ); + })} + + ); +} diff --git a/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts b/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts index 4cda7befe44c9d..7609b724e05475 100644 --- a/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts +++ b/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts @@ -4,10 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { ColumnarViewModel } from '@elastic/charts'; import d3 from 'd3'; -import { sum, uniqueId } from 'lodash'; -import { createColumnarViewModel, rgbToRGBA } from '../../../common/columnar_view_model'; +import { compact, sum, uniqueId, range } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { createColumnarViewModel } from '../../../common/columnar_view_model'; import { ElasticFlameGraph, FlameGraphComparisonMode } from '../../../common/flamegraph'; +import { FRAME_TYPE_COLOR_MAP, rgbToRGBA } from '../../../common/frame_type_colors'; +import { describeFrameType, FrameType } from '../../../common/profiling'; import { getInterpolationValue } from './get_interpolation_value'; const nullColumnarViewModel = { @@ -34,17 +38,72 @@ export function getFlamegraphModel({ colorDanger: string; colorNeutral: string; comparisonMode: FlameGraphComparisonMode; -}) { +}): { + key: string; + viewModel: ColumnarViewModel; + comparisonNodesById: Record; + legendItems: Array<{ label: string; color: string }>; +} { const comparisonNodesById: Record = {}; if (!primaryFlamegraph || !primaryFlamegraph.Label || primaryFlamegraph.Label.length === 0) { - return { key: uniqueId(), viewModel: nullColumnarViewModel, comparisonNodesById }; + return { + key: uniqueId(), + viewModel: nullColumnarViewModel, + comparisonNodesById, + legendItems: [], + }; } const viewModel = createColumnarViewModel(primaryFlamegraph, comparisonFlamegraph === undefined); - if (comparisonFlamegraph) { + let legendItems: Array<{ label: string; color: string }>; + + if (!comparisonFlamegraph) { + const usedFrameTypes = new Set([...primaryFlamegraph.FrameType]); + legendItems = compact( + Object.entries(FRAME_TYPE_COLOR_MAP).map(([frameTypeKey, colors]) => { + const frameType = Number(frameTypeKey) as FrameType; + + return usedFrameTypes.has(frameType) + ? { + color: `#${colors[0].toString(16)}`, + label: describeFrameType(frameType), + } + : undefined; + }) + ); + } else { + const positiveChangeInterpolator = d3.interpolateRgb(colorNeutral, colorSuccess); + + const negativeChangeInterpolator = d3.interpolateRgb(colorNeutral, colorDanger); + + function getColor(interpolationValue: number) { + const nodeColor = + interpolationValue >= 0 + ? positiveChangeInterpolator(interpolationValue) + : negativeChangeInterpolator(Math.abs(interpolationValue)); + + return nodeColor; + } + + legendItems = range(1, -1, -0.2) + .concat(-1) + .map((value) => { + const rounded = Math.round(value * 100) / 100; + const color = getColor(rounded); + return { + color, + label: + rounded === 0 + ? i18n.translate('xpack.profiling.flamegraphModel.noChange', { + defaultMessage: 'No change', + }) + : '', + }; + }); + comparisonFlamegraph.ID.forEach((nodeID, index) => { comparisonNodesById[nodeID] = { CountInclusive: comparisonFlamegraph.CountInclusive[index], @@ -52,10 +111,6 @@ export function getFlamegraphModel({ }; }); - const positiveChangeInterpolator = d3.interpolateRgb(colorNeutral, colorSuccess); - - const negativeChangeInterpolator = d3.interpolateRgb(colorNeutral, colorDanger); - // per @thomasdullien: // In "relative" mode: Take the percentage of CPU time consumed by block A and subtract // the percentage of CPU time consumed by block B. If the number is positive, linearly @@ -100,10 +155,7 @@ export function getFlamegraphModel({ denominator ); - const nodeColor = - interpolationValue >= 0 - ? positiveChangeInterpolator(interpolationValue) - : negativeChangeInterpolator(Math.abs(interpolationValue)); + const nodeColor = getColor(interpolationValue); const rgba = rgbToRGBA(Number(nodeColor.replace('#', '0x'))); viewModel.color.set(rgba, 4 * index); @@ -114,5 +166,6 @@ export function getFlamegraphModel({ key: uniqueId(), viewModel, comparisonNodesById, + legendItems, }; } 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 ca3ba4445f940a..abebdef58fe330 100644 --- a/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts +++ b/x-pack/plugins/reporting/server/lib/tasks/execute_report.ts @@ -10,8 +10,9 @@ import type { Logger } from '@kbn/core/server'; import moment from 'moment'; import * as Rx from 'rxjs'; import { timeout } from 'rxjs/operators'; -import { finished, Writable } from 'stream'; -import { promisify } from 'util'; +import { Writable } from 'stream'; +import { finished } from 'stream/promises'; +import { setTimeout } from 'timers/promises'; import type { RunContext, TaskManagerStartContract, @@ -59,6 +60,22 @@ function reportFromTask(task: ReportTaskParams) { return new Report({ ...task, _id: task.id, _index: task.index }); } +async function finishedWithNoPendingCallbacks(stream: Writable) { + await finished(stream, { readable: false }); + + // Race condition workaround: + // `finished(...)` will resolve while there's still pending callbacks in the writable part of the `stream`. + // This introduces a race condition where the code continues before the writable part has completely finished. + // The `pendingCallbacks` function is a hack to ensure that all pending callbacks have been called before continuing. + // For more information, see: https://github.com/nodejs/node/issues/46170 + await (async function pendingCallbacks(delay = 1) { + if ((stream as any)._writableState.pendingcb > 0) { + await setTimeout(delay); + await pendingCallbacks(delay < 32 ? delay * 2 : delay); + } + })(); +} + export class ExecuteReportTask implements ReportingTask { public TYPE = REPORTING_EXECUTE_TYPE; @@ -377,7 +394,7 @@ export class ExecuteReportTask implements ReportingTask { stream.end(); - await promisify(finished)(stream, { readable: false }); + await finishedWithNoPendingCallbacks(stream); report._seq_no = stream.getSeqNo()!; report._primary_term = stream.getPrimaryTerm()!; diff --git a/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts b/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts index f33b8659fb27f6..b69e09aa7bff77 100644 --- a/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts +++ b/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_features.ts @@ -11,7 +11,7 @@ import { KibanaFeature } from '@kbn/features-plugin/public'; export const createFeature = ( config: Pick< KibanaFeatureConfig, - 'id' | 'name' | 'subFeatures' | 'reserved' | 'privilegesTooltip' + 'id' | 'name' | 'subFeatures' | 'reserved' | 'privilegesTooltip' | 'description' > & { excludeFromBaseAll?: boolean; excludeFromBaseRead?: boolean; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss index e5c026d317034e..f03a4582598ee7 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.scss @@ -1,5 +1,11 @@ -.subFeaturePrivilegeExpandedRegion { - background-color: $euiColorLightestShade; - padding-left: $euiSizeXXL; - padding-top: $euiSizeS; -} \ No newline at end of file +.euiAccordionWithDescription:hover, .euiAccordionWithDescription:focus { + text-decoration: none; +} + +.subFeaturePanel { + margin-left: $euiSizeL + $euiSizeXS; +} + +.noSubFeaturePrivileges { + margin-left: $euiSizeL + $euiSizeXS; +} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx index 7f5ac97e41edff..0383e857adda4e 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.test.tsx @@ -837,6 +837,63 @@ describe('FeatureTable', () => { expect(findTestSubject(wrapper, 'primaryFeaturePrivilegeControl')).toHaveLength(0); }); + it('renders subtext for features that define an optional description', () => { + const role = createRole([ + { + spaces: ['foo'], + base: [], + feature: { + my_feature: ['all'], + }, + }, + ]); + const featureWithDescription = createFeature({ + id: 'my_feature', + name: 'Some Feature', + description: 'a description of my feature', + }); + + const { wrapper } = setup({ + role, + features: [featureWithDescription], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: false, + }); + + expect(findTestSubject(wrapper, 'featurePrivilegeDescriptionText').exists()).toEqual(true); + + expect( + findTestSubject(wrapper, 'featurePrivilegeDescriptionText').text() + ).toMatchInlineSnapshot(`"a description of my feature"`); + }); + + it('does not render subtext for features without a description', () => { + const role = createRole([ + { + spaces: ['foo'], + base: [], + feature: { + my_feature: ['all'], + }, + }, + ]); + const featureWithDescription = createFeature({ + id: 'my_feature', + name: 'Some Feature', + }); + + const { wrapper } = setup({ + role, + features: [featureWithDescription], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: false, + }); + + expect(findTestSubject(wrapper, 'featurePrivilegeDescriptionText').exists()).toEqual(false); + }); + it('renders renders the primary feature controls when both primary and reserved privileges are specified', () => { const role = createRole([ { @@ -1315,4 +1372,100 @@ describe('FeatureTable', () => { expect(type).toBe('empty'); }); }); + describe('Optional description for sub-features', () => { + const role = createRole([ + { + spaces: ['foo'], + base: [], + feature: { + unit_test: ['minimal_read', 'sub-toggle-1', 'sub-toggle-2'], + }, + }, + ]); + + it('renders description subtext if defined', () => { + const feature = createFeature({ + id: 'unit_test', + name: 'Unit Test Feature', + subFeatures: [ + { + name: 'Some Sub Feature', + description: 'some sub feature description', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'sub-toggle-1', + name: 'Sub Toggle 1', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: ['sub-toggle-1'], + }, + ], + }, + ], + }, + ] as SubFeatureConfig[], + }); + const { wrapper } = setup({ + role, + features: [feature], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: true, + }); + + const categoryExpander = findTestSubject(wrapper, 'featureCategoryButton_foo'); + categoryExpander.simulate('click'); + + const featureExpander = findTestSubject(wrapper, 'featureTableCell'); + featureExpander.simulate('click'); + + expect(findTestSubject(wrapper, 'subFeatureDescription').exists()).toEqual(true); + expect(findTestSubject(wrapper, 'subFeatureDescription').text()).toMatchInlineSnapshot( + `"some sub feature description"` + ); + }); + it('should not render description subtext if undefined', () => { + const feature = createFeature({ + id: 'unit_test', + name: 'Unit Test Feature', + subFeatures: [ + { + name: 'Some Sub Feature', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'sub-toggle-1', + name: 'Sub Toggle 1', + includeIn: 'all', + savedObject: { all: [], read: [] }, + ui: ['sub-toggle-1'], + }, + ], + }, + ], + }, + ] as SubFeatureConfig[], + }); + const { wrapper } = setup({ + role, + features: [feature], + privilegeIndex: 0, + calculateDisplayedPrivileges: false, + canCustomizeSubFeaturePrivileges: true, + }); + + const categoryExpander = findTestSubject(wrapper, 'featureCategoryButton_foo'); + categoryExpander.simulate('click'); + + const featureExpander = findTestSubject(wrapper, 'featureTableCell'); + featureExpander.simulate('click'); + + expect(findTestSubject(wrapper, 'subFeatureDescription').exists()).toEqual(false); + }); + }); }); diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx index 33f9f2879b4f78..d2a5625b724a6b 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx @@ -17,10 +17,12 @@ import { EuiHorizontalRule, EuiIcon, EuiIconTip, + EuiPanel, EuiSpacer, EuiText, EuiTitle, } from '@elastic/eui'; +import classNames from 'classnames'; import type { ReactElement } from 'react'; import React, { Component } from 'react'; @@ -221,11 +223,12 @@ export class FeatureTable extends Component { return ( {infoIcon} - + { }); }} > -
    + + { this.props.canCustomizeSubFeaturePrivileges } /> -
    +
    @@ -267,9 +271,7 @@ export class FeatureTable extends Component { if (feature.reserved && primaryFeaturePrivileges.length === 0) { const buttonContent = ( - <> - {} - + ); const extraAction = ( @@ -336,10 +338,10 @@ export class FeatureTable extends Component { const hasSubFeaturePrivileges = feature.getSubFeaturePrivileges().length > 0; const buttonContent = ( - <> - {!hasSubFeaturePrivileges && }{' '} - - + ); const extraAction = ( diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx index e5e28c45473743..e89102e62ca8da 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table_expanded_row.tsx @@ -70,7 +70,7 @@ export const FeatureTableExpandedRow = ({ }; return ( - +
    { if (groupsWithPrivileges.length === 0) { return null; } - return ( - - - - {props.subFeature.name} {getTooltip()} - + + + + + + {props.subFeature.name} {getTooltip()} + + + {props.subFeature.description && ( + + + {props.subFeature.description} + + + )} + - {groupsWithPrivileges.map(renderPrivilegeGroup)} + {groupsWithPrivileges.map(renderPrivilegeGroup)} ); @@ -157,6 +172,7 @@ export const SubFeatureForm = (props: Props) => { key={index} buttonSize="compressed" data-test-subj="mutexSubFeaturePrivilegeControl" + isFullWidth options={options} idSelected={firstSelectedPrivilege?.id ?? NO_PRIVILEGE_VALUE} isDisabled={props.disabled} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss new file mode 100644 index 00000000000000..8a002996b67edb --- /dev/null +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss @@ -0,0 +1,3 @@ +.featurePrivilegeName:hover, .featurePrivilegeName:focus { + text-decoration: underline; +} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx index 006ae053940d8d..c503ef35ae06c9 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.test.tsx @@ -25,7 +25,7 @@ describe('FeatureTableCell', () => { ); - expect(wrapper.text()).toMatchInlineSnapshot(`"Test Feature "`); + expect(wrapper.text()).toMatchInlineSnapshot(`"Test Feature"`); expect(wrapper.find(EuiIconTip)).toHaveLength(0); }); @@ -40,7 +40,7 @@ describe('FeatureTableCell', () => { ); - expect(wrapper.text()).toMatchInlineSnapshot(`"Test Feature Info"`); + expect(wrapper.text()).toMatchInlineSnapshot(`"Test FeatureInfo"`); expect(wrapper.find(EuiIconTip).props().content).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx index 507416b51f9b6f..062597ce46ad2b 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx @@ -5,16 +5,19 @@ * 2.0. */ -import { EuiIconTip, EuiText } from '@elastic/eui'; +import './feature_table_cell.scss'; + +import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiText } from '@elastic/eui'; import React from 'react'; import type { SecuredFeature } from '../../../../model'; interface Props { feature: SecuredFeature; + className?: string; } -export const FeatureTableCell = ({ feature }: Props) => { +export const FeatureTableCell = ({ feature, className }: Props) => { let tooltipElement = null; if (feature.getPrivilegesTooltip()) { const tooltipContent = ( @@ -35,8 +38,27 @@ export const FeatureTableCell = ({ feature }: Props) => { } return ( - - {feature.name} {tooltipElement} - + + + + + {feature.name} + + {tooltipElement} + + + {feature.description && ( + + + {feature.description} + + + )} + ); }; diff --git a/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts b/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts index 8c312ee7ea7721..79e98625cb06f1 100644 --- a/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts +++ b/x-pack/plugins/security/public/management/roles/model/secured_sub_feature.ts @@ -44,4 +44,8 @@ export class SecuredSubFeature extends SubFeature { .filter((privilege) => predicate(privilege, this)); } } + + public getDescription() { + return this.description; + } } diff --git a/x-pack/plugins/security/server/audit/audit_events.test.ts b/x-pack/plugins/security/server/audit/audit_events.test.ts index fb246569fcf816..8edd22e915c7c1 100644 --- a/x-pack/plugins/security/server/audit/audit_events.test.ts +++ b/x-pack/plugins/security/server/audit/audit_events.test.ts @@ -15,11 +15,13 @@ import { AuthenticationResult } from '../authentication'; import { httpRequestEvent, savedObjectEvent, + sessionCleanupConcurrentLimitEvent, sessionCleanupEvent, SpaceAuditAction, spaceAuditEvent, userLoginEvent, userLogoutEvent, + userSessionConcurrentLimitLogoutEvent, } from './audit_events'; describe('#savedObjectEvent', () => { @@ -360,6 +362,63 @@ describe('#userLogoutEvent', () => { }); }); +describe('#userSessionConcurrentLimitLogoutEvent', () => { + test('creates event with `unknown` outcome', () => { + expect( + userSessionConcurrentLimitLogoutEvent({ + username: 'elastic', + provider: { name: 'basic1', type: 'basic' }, + userProfileId: 'uid', + }) + ).toMatchInlineSnapshot(` + Object { + "event": Object { + "action": "user_logout", + "category": Array [ + "authentication", + ], + "outcome": "unknown", + }, + "kibana": Object { + "authentication_provider": "basic1", + "authentication_type": "basic", + }, + "message": "User [elastic] is logging out due to exceeded concurrent sessions limit for basic provider [name=basic1]", + "user": Object { + "id": "uid", + "name": "elastic", + }, + } + `); + + expect( + userSessionConcurrentLimitLogoutEvent({ + username: 'elastic', + provider: { name: 'basic1', type: 'basic' }, + }) + ).toMatchInlineSnapshot(` + Object { + "event": Object { + "action": "user_logout", + "category": Array [ + "authentication", + ], + "outcome": "unknown", + }, + "kibana": Object { + "authentication_provider": "basic1", + "authentication_type": "basic", + }, + "message": "User [elastic] is logging out due to exceeded concurrent sessions limit for basic provider [name=basic1]", + "user": Object { + "id": undefined, + "name": "elastic", + }, + } + `); + }); +}); + describe('#sessionCleanupEvent', () => { test('creates event with `unknown` outcome', () => { expect( @@ -391,6 +450,37 @@ describe('#sessionCleanupEvent', () => { }); }); +describe('#sessionCleanupConcurrentLimitEvent', () => { + test('creates event with `unknown` outcome', () => { + expect( + sessionCleanupConcurrentLimitEvent({ + usernameHash: 'abcdef', + sessionId: 'sid', + provider: { name: 'basic1', type: 'basic' }, + }) + ).toMatchInlineSnapshot(` + Object { + "event": Object { + "action": "session_cleanup", + "category": Array [ + "authentication", + ], + "outcome": "unknown", + }, + "kibana": Object { + "authentication_provider": "basic1", + "authentication_type": "basic", + "session_id": "sid", + }, + "message": "Removing session for user [hash=abcdef] due to exceeded concurrent sessions limit", + "user": Object { + "hash": "abcdef", + }, + } + `); + }); +}); + describe('#httpRequestEvent', () => { test('creates event with `unknown` outcome', () => { expect( diff --git a/x-pack/plugins/security/server/audit/audit_events.ts b/x-pack/plugins/security/server/audit/audit_events.ts index 0ba0530b045858..26cfec1a6c4207 100644 --- a/x-pack/plugins/security/server/audit/audit_events.ts +++ b/x-pack/plugins/security/server/audit/audit_events.ts @@ -215,6 +215,32 @@ export function userLogoutEvent({ }; } +export function userSessionConcurrentLimitLogoutEvent({ + username, + provider, + userProfileId, +}: UserLogoutParams): AuditEvent { + return { + message: `User [${username}] is logging out due to exceeded concurrent sessions limit for ${provider.type} provider [name=${provider.name}]`, + event: { + action: 'user_logout', + category: ['authentication'], + outcome: 'unknown', + }, + user: + userProfileId || username + ? { + id: userProfileId, + name: username, + } + : undefined, + kibana: { + authentication_provider: provider.name, + authentication_type: provider.type, + }, + }; +} + export interface SessionCleanupParams { sessionId: string; usernameHash?: string; @@ -244,6 +270,29 @@ export function sessionCleanupEvent({ }; } +export function sessionCleanupConcurrentLimitEvent({ + usernameHash, + sessionId, + provider, +}: SessionCleanupParams): AuditEvent { + return { + message: `Removing session for user [hash=${usernameHash}] due to exceeded concurrent sessions limit`, + event: { + action: 'session_cleanup', + category: ['authentication'], + outcome: 'unknown', + }, + user: { + hash: usernameHash, + }, + kibana: { + session_id: sessionId, + authentication_provider: provider.name, + authentication_type: provider.type, + }, + }; +} + export interface AccessAgreementAcknowledgedParams { username: string; provider: AuthenticationProvider; diff --git a/x-pack/plugins/security/server/audit/index.ts b/x-pack/plugins/security/server/audit/index.ts index 15d91168c6aca0..c21a9625ca6cf3 100644 --- a/x-pack/plugins/security/server/audit/index.ts +++ b/x-pack/plugins/security/server/audit/index.ts @@ -11,7 +11,9 @@ export type { AuditEvent, AuditHttp, AuditKibana, AuditRequest } from './audit_e export { userLoginEvent, userLogoutEvent, + userSessionConcurrentLimitLogoutEvent, sessionCleanupEvent, + sessionCleanupConcurrentLimitEvent, accessAgreementAcknowledgedEvent, httpRequestEvent, savedObjectEvent, diff --git a/x-pack/plugins/security/server/authentication/authenticator.ts b/x-pack/plugins/security/server/authentication/authenticator.ts index 0ebc418fdd7d47..d984783df4c02c 100644 --- a/x-pack/plugins/security/server/authentication/authenticator.ts +++ b/x-pack/plugins/security/server/authentication/authenticator.ts @@ -800,7 +800,7 @@ export class Authenticator { await this.invalidateSessionValue({ request, sessionValue: existingSessionValue, - skipAuditEvent: true, // Skip writing an audit event when we are replacing an intermediate session with a fullly authenticated session + skipAuditEvent: true, // Skip writing an audit event when we are replacing an intermediate session with a fully authenticated session }); existingSessionValue = null; } else if (usernameHasChanged) { diff --git a/x-pack/plugins/security/server/config.test.ts b/x-pack/plugins/security/server/config.test.ts index 1c50c82d3a0f6c..8b7324e70d6462 100644 --- a/x-pack/plugins/security/server/config.test.ts +++ b/x-pack/plugins/security/server/config.test.ts @@ -1412,6 +1412,40 @@ describe('config schema', () => { '[session.cleanupInterval]: the value must be greater or equal to 10 seconds.' ); }); + + it('should throw error if xpack.security.session.concurrentSessions.maxSessions is less than 1 or greater than 1000', () => { + expect(() => + ConfigSchema.validate({ session: { concurrentSessions: { maxSessions: -1 } } }) + ).toThrow( + '[session.concurrentSessions.maxSessions]: Value must be equal to or greater than [1].' + ); + + expect(() => + ConfigSchema.validate({ session: { concurrentSessions: { maxSessions: 0 } } }) + ).toThrow( + '[session.concurrentSessions.maxSessions]: Value must be equal to or greater than [1].' + ); + + expect(() => + ConfigSchema.validate({ session: { concurrentSessions: { maxSessions: 1001 } } }) + ).toThrow( + '[session.concurrentSessions.maxSessions]: Value must be equal to or lower than [1000].' + ); + }); + + it('can be successfully validate valid xpack.security.session.concurrentSessions.maxSessions', () => { + expect(ConfigSchema.validate({ session: { concurrentSessions: { maxSessions: 3 } } }).session) + .toMatchInlineSnapshot(` + Object { + "cleanupInterval": "PT1H", + "concurrentSessions": Object { + "maxSessions": 3, + }, + "idleTimeout": "PT8H", + "lifespan": "P30D", + } + `); + }); }); }); @@ -1465,6 +1499,40 @@ describe('createConfig()', () => { `); }); + it('should log a warning if both concurrent sessions limit and HTTP authentication are configured', async () => { + const logger = loggingSystemMock.create(); + const config = createConfig( + ConfigSchema.validate({ session: { concurrentSessions: { maxSessions: 3 } } }), + logger.get(), + { isTLSEnabled: true } + ); + expect(config.session.concurrentSessions?.maxSessions).toBe(3); + expect(config.authc.http.enabled).toBe(true); + + expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(` + Array [ + Array [ + "Both concurrent user sessions limit and HTTP authentication are configured. The limit does not apply to HTTP authentication.", + ], + ] + `); + + loggingSystemMock.clear(logger); + + const configWithoutHTTPAuth = createConfig( + ConfigSchema.validate({ + session: { concurrentSessions: { maxSessions: 3 } }, + authc: { http: { enabled: false } }, + }), + logger.get(), + { isTLSEnabled: true } + ); + expect(configWithoutHTTPAuth.session.concurrentSessions?.maxSessions).toBe(3); + expect(configWithoutHTTPAuth.authc.http.enabled).toBe(false); + + expect(loggingSystemMock.collect(logger).warn).toHaveLength(0); + }); + it('should set xpack.security.secureCookies if SSL is configured', async () => { const logger = loggingSystemMock.create().get(); const config = createConfig(ConfigSchema.validate({}), logger, { isTLSEnabled: true }); diff --git a/x-pack/plugins/security/server/config.ts b/x-pack/plugins/security/server/config.ts index aa7e3c0964ba8a..e3584427964f35 100644 --- a/x-pack/plugins/security/server/config.ts +++ b/x-pack/plugins/security/server/config.ts @@ -226,6 +226,11 @@ export const ConfigSchema = schema.object({ } }, }), + concurrentSessions: schema.maybe( + schema.object({ + maxSessions: schema.number({ min: 1, max: 1000 }), + }) + ), }), secureCookies: schema.boolean({ defaultValue: false }), sameSiteCookies: schema.maybe( @@ -400,6 +405,13 @@ export function createConfig( }, } as AppenderConfigType); + const session = getSessionConfig(config.session, providers); + if (session.concurrentSessions?.maxSessions != null && config.authc.http.enabled) { + logger.warn( + 'Both concurrent user sessions limit and HTTP authentication are configured. The limit does not apply to HTTP authentication.' + ); + } + return { ...config, audit: { @@ -412,7 +424,7 @@ export function createConfig( sortedProviders: Object.freeze(sortedProviders), http: config.authc.http, }, - session: getSessionConfig(config.session, providers), + session, encryptionKey, secureCookies, }; @@ -420,6 +432,7 @@ export function createConfig( function getSessionConfig(session: RawConfigType['session'], providers: ProvidersConfigType) { return { + concurrentSessions: session.concurrentSessions, cleanupInterval: session.cleanupInterval, getExpirationTimeouts(provider: AuthenticationProvider | undefined) { // Both idle timeout and lifespan from the provider specific session config can have three diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 573af8dbb7b670..db9e7555503ce4 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -370,7 +370,7 @@ export class SecurityPlugin const clusterClient = core.elasticsearch.client; const { watchOnlineStatus$ } = this.elasticsearchService.start(); const { session } = this.sessionManagementService.start({ - auditLogger: this.auditSetup!.withoutRequest, + audit: this.auditSetup!, elasticsearchClient: clusterClient.asInternalUser, kibanaIndexName: this.getKibanaIndexName(), online$: watchOnlineStatus$(), diff --git a/x-pack/plugins/security/server/session_management/session.test.ts b/x-pack/plugins/security/server/session_management/session.test.ts index 29e63141aaad8f..d5ad9ce3b31d46 100644 --- a/x-pack/plugins/security/server/session_management/session.test.ts +++ b/x-pack/plugins/security/server/session_management/session.test.ts @@ -11,7 +11,10 @@ import crypto from 'crypto'; import { httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks'; import type { PublicMethodsOf } from '@kbn/utility-types'; +import type { AuditLogger } from '..'; import { mockAuthenticatedUser } from '../../common/model/authenticated_user.mock'; +import { userSessionConcurrentLimitLogoutEvent } from '../audit'; +import { auditLoggerMock, auditServiceMock } from '../audit/mocks'; import { ConfigSchema, createConfig } from '../config'; import { sessionCookieMock, sessionIndexMock, sessionMock } from './index.mock'; import { getPrintableSessionId, Session, type SessionValueContentToEncrypt } from './session'; @@ -27,6 +30,7 @@ describe('Session', () => { let mockSessionIndex: jest.Mocked>; let mockSessionCookie: jest.Mocked>; + let mockScopedAuditLogger: jest.Mocked; let session: Session; beforeEach(() => { jest.spyOn(Date, 'now').mockImplementation(() => now); @@ -43,6 +47,10 @@ describe('Session', () => { mockSessionCookie = sessionCookieMock.create(); mockSessionIndex = sessionIndexMock.create(); + mockScopedAuditLogger = auditLoggerMock.create(); + + const mockAuditServiceSetup = auditServiceMock.create(); + mockAuditServiceSetup.asScoped.mockReturnValue(mockScopedAuditLogger); session = new Session({ logger: loggingSystemMock.createLogger(), @@ -56,6 +64,7 @@ describe('Session', () => { ), sessionCookie: mockSessionCookie, sessionIndex: mockSessionIndex, + audit: mockAuditServiceSetup, }); }); @@ -205,6 +214,40 @@ describe('Session', () => { expect(mockSessionIndex.invalidate).toHaveBeenCalledTimes(1); }); + it('clears session value if the session is outside the concurrent session limit', async () => { + mockSessionCookie.get.mockResolvedValue( + sessionCookieMock.createValue({ + aad: mockAAD, + idleTimeoutExpiration: now + 1, + lifespanExpiration: now + 1, + }) + ); + mockSessionIndex.get.mockResolvedValue( + sessionIndexMock.createValue({ + content: await encryptContent( + { username: 'some-user', state: 'some-state', userProfileId: 'uid' }, + mockAAD + ), + }) + ); + mockSessionIndex.isWithinConcurrentSessionLimit.mockResolvedValue(false); + + await expect(session.get(httpServerMock.createKibanaRequest())).resolves.toEqual({ + error: expect.any(SessionUnexpectedError), + value: null, + }); + expect(mockSessionCookie.clear).toHaveBeenCalledTimes(1); + expect(mockSessionIndex.invalidate).toHaveBeenCalledTimes(1); + expect(mockScopedAuditLogger.log).toHaveBeenCalledTimes(1); + expect(mockScopedAuditLogger.log).toHaveBeenCalledWith( + userSessionConcurrentLimitLogoutEvent({ + username: 'some-user', + userProfileId: 'uid', + provider: { name: 'basic1', type: 'basic' }, + }) + ); + }); + it('returns session value with decrypted content', async () => { mockSessionCookie.get.mockResolvedValue( sessionCookieMock.createValue({ @@ -596,6 +639,7 @@ describe('Session', () => { ), sessionCookie: mockSessionCookie, sessionIndex: mockSessionIndex, + audit: auditServiceMock.create(), }); const mockRequest = httpServerMock.createKibanaRequest(); @@ -636,6 +680,7 @@ describe('Session', () => { ), sessionCookie: mockSessionCookie, sessionIndex: mockSessionIndex, + audit: auditServiceMock.create(), }); const mockRequest = httpServerMock.createKibanaRequest(); @@ -711,6 +756,7 @@ describe('Session', () => { ), sessionCookie: mockSessionCookie, sessionIndex: mockSessionIndex, + audit: auditServiceMock.create(), }); const mockRequest = httpServerMock.createKibanaRequest(); @@ -767,6 +813,7 @@ describe('Session', () => { ), sessionCookie: mockSessionCookie, sessionIndex: mockSessionIndex, + audit: auditServiceMock.create(), }); }); @@ -912,6 +959,7 @@ describe('Session', () => { ), sessionCookie: mockSessionCookie, sessionIndex: mockSessionIndex, + audit: auditServiceMock.create(), }); const mockRequest = httpServerMock.createKibanaRequest(); @@ -958,6 +1006,7 @@ describe('Session', () => { ), sessionCookie: mockSessionCookie, sessionIndex: mockSessionIndex, + audit: auditServiceMock.create(), }); const mockRequest = httpServerMock.createKibanaRequest(); diff --git a/x-pack/plugins/security/server/session_management/session.ts b/x-pack/plugins/security/server/session_management/session.ts index f805ff9517ba2d..8969cc59390824 100644 --- a/x-pack/plugins/security/server/session_management/session.ts +++ b/x-pack/plugins/security/server/session_management/session.ts @@ -13,7 +13,9 @@ import { promisify } from 'util'; import type { KibanaRequest, Logger } from '@kbn/core/server'; import type { PublicMethodsOf } from '@kbn/utility-types'; +import type { AuditServiceSetup } from '..'; import type { AuthenticationProvider } from '../../common'; +import { userSessionConcurrentLimitLogoutEvent } from '../audit'; import type { ConfigType } from '../config'; import type { SessionCookie } from './session_cookie'; import { SessionExpiredError, SessionMissingError, SessionUnexpectedError } from './session_errors'; @@ -85,6 +87,7 @@ export interface SessionOptions { readonly sessionIndex: PublicMethodsOf; readonly sessionCookie: PublicMethodsOf; readonly config: Pick; + readonly audit: AuditServiceSetup; } export interface SessionValueContentToEncrypt { @@ -194,6 +197,26 @@ export class Session { return { error: new SessionUnexpectedError(), value: null }; } + // The only reason why we check if the session is within the concurrent session limit _after_ decryption + // is to record decrypted username and profile id in the audit logs. + const isSessionWithinConcurrentSessionLimit = + await this.options.sessionIndex.isWithinConcurrentSessionLimit(sessionIndexValue); + if (!isSessionWithinConcurrentSessionLimit) { + this.options.audit.asScoped(request).log( + userSessionConcurrentLimitLogoutEvent({ + username: decryptedContent.username, + userProfileId: decryptedContent.userProfileId, + provider: sessionIndexValue.provider, + }) + ); + + sessionLogger.warn( + 'Session is outside the concurrent session limit and will be invalidated.' + ); + await this.invalidate(request, { match: 'current' }); + return { error: new SessionUnexpectedError(), value: null }; + } + return { error: null, value: { diff --git a/x-pack/plugins/security/server/session_management/session_index.mock.ts b/x-pack/plugins/security/server/session_management/session_index.mock.ts index 41aa0d3ee60f98..6389bc67eac009 100644 --- a/x-pack/plugins/security/server/session_management/session_index.mock.ts +++ b/x-pack/plugins/security/server/session_management/session_index.mock.ts @@ -17,6 +17,7 @@ export const sessionIndexMock = { invalidate: jest.fn(), initialize: jest.fn(), cleanUp: jest.fn(), + isWithinConcurrentSessionLimit: jest.fn().mockResolvedValue(true), }), createValue: (sessionValue: Partial = {}): SessionIndexValue => ({ diff --git a/x-pack/plugins/security/server/session_management/session_index.test.ts b/x-pack/plugins/security/server/session_management/session_index.test.ts index 3b8005bcde21f1..2178abc064179d 100644 --- a/x-pack/plugins/security/server/session_management/session_index.test.ts +++ b/x-pack/plugins/security/server/session_management/session_index.test.ts @@ -10,6 +10,7 @@ import type { BulkResponse, ClosePointInTimeResponse, DeleteByQueryResponse, + MsearchMultiSearchResult, OpenPointInTimeResponse, SearchResponse, } from '@elastic/elasticsearch/lib/api/types'; @@ -18,6 +19,7 @@ import { elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mo import type { AuditLogger } from '../audit'; import { auditLoggerMock } from '../audit/mocks'; +import { AnonymousAuthenticationProvider } from '../authentication'; import { ConfigSchema, createConfig } from '../config'; import { securityMock } from '../mocks'; import { @@ -36,20 +38,23 @@ describe('Session index', () => { const indexName = '.kibana_some_tenant_security_session_1'; const aliasName = '.kibana_some_tenant_security_session'; const indexTemplateName = '.kibana_some_tenant_security_session_index_template_1'; + + const createSessionIndexOptions = ( + config: Record = { session: { idleTimeout: null, lifespan: null } } + ) => ({ + logger: loggingSystemMock.createLogger(), + kibanaIndexName: '.kibana_some_tenant', + config: createConfig(ConfigSchema.validate(config), loggingSystemMock.createLogger(), { + isTLSEnabled: false, + }), + elasticsearchClient: mockElasticsearchClient, + auditLogger, + }); + beforeEach(() => { mockElasticsearchClient = elasticsearchServiceMock.createElasticsearchClient(); auditLogger = auditLoggerMock.create(); - sessionIndex = new SessionIndex({ - logger: loggingSystemMock.createLogger(), - kibanaIndexName: '.kibana_some_tenant', - config: createConfig( - ConfigSchema.validate({ session: { idleTimeout: null, lifespan: null } }), - loggingSystemMock.createLogger(), - { isTLSEnabled: false } - ), - elasticsearchClient: mockElasticsearchClient, - auditLogger, - }); + sessionIndex = new SessionIndex(createSessionIndexOptions()); }); describe('#initialize', () => { @@ -947,6 +952,318 @@ describe('Session index', () => { }) ); }); + + describe('concurrent session limit', () => { + const expectedSearchParameters = () => ({ + index: '.kibana_some_tenant_security_session', + query: { + bool: { + filter: [ + { exists: { field: 'usernameHash' } }, + { + bool: { + must_not: [{ term: { 'provider.type': AnonymousAuthenticationProvider.type } }], + }, + }, + ], + }, + }, + aggs: { + sessions_grouped_by_user: { + multi_terms: { + size: 10000, + terms: [ + { field: 'usernameHash' }, + { field: 'provider.type' }, + { field: 'provider.name' }, + ], + min_doc_count: 3, + }, + }, + }, + size: 0, + filter_path: [ + 'aggregations.sessions_grouped_by_user.sum_other_doc_count', + 'aggregations.sessions_grouped_by_user.buckets.key', + 'aggregations.sessions_grouped_by_user.buckets.doc_count', + ], + track_total_hits: false, + }); + + const expectedMultiSearchParameters = ( + usernameHash: string, + providerType: string, + providerName: string + ) => ({ + query: { + bool: { + must: [ + { term: { usernameHash } }, + { term: { 'provider.type': providerType } }, + { term: { 'provider.name': providerName } }, + ], + }, + }, + sort: [{ createdAt: { order: 'desc' } }], + from: 2, + size: 9998, + _source: false, + track_total_hits: false, + }); + + beforeEach(() => { + // The first search call is used by the invalid/expired sessions cleanup routine. + mockElasticsearchClient.search.mockResolvedValueOnce({ + hits: { hits: [] }, + } as unknown as SearchResponse); + + sessionIndex = new SessionIndex( + createSessionIndexOptions({ + session: { idleTimeout: null, lifespan: null, concurrentSessions: { maxSessions: 2 } }, + }) + ); + }); + + it('when concurrent session limit is not configured', async () => { + sessionIndex = new SessionIndex(createSessionIndexOptions()); + + await sessionIndex.cleanUp(); + + // Only search call for the invalid sessions (use `pit` as marker, since concurrent session limit cleanup + // routine doesn't rely on PIT). + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith( + expect.objectContaining({ pit: { id: 'PIT_ID', keep_alive: '5m' } }) + ); + expect(mockElasticsearchClient.msearch).not.toHaveBeenCalled(); + expect(mockElasticsearchClient.bulk).not.toHaveBeenCalled(); + expect(mockElasticsearchClient.indices.refresh).not.toHaveBeenCalled(); + }); + + it('when the concurrent session limit is not exceeded', async () => { + mockElasticsearchClient.search.mockResolvedValueOnce({ + aggregations: { sessions_grouped_by_user: { sum_other_doc_count: 1 } }, + } as unknown as SearchResponse); + + await sessionIndex.cleanUp(); + + // Only search call for the invalid sessions (use `pit` as marker, since concurrent session limit cleanup + // routine doesn't rely on PIT). + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(2); + expect(mockElasticsearchClient.search).toHaveBeenNthCalledWith( + 2, + expectedSearchParameters() + ); + expect(mockElasticsearchClient.msearch).not.toHaveBeenCalled(); + expect(mockElasticsearchClient.bulk).not.toHaveBeenCalled(); + expect(mockElasticsearchClient.indices.refresh).not.toHaveBeenCalled(); + }); + + it('when the concurrent session limit is exceeded', async () => { + mockElasticsearchClient.search.mockResolvedValueOnce({ + aggregations: { + sessions_grouped_by_user: { + sum_other_doc_count: 1, + buckets: [{ key: ['user-hash-name', 'basic', 'basic1'], doc_count: 10 }], + }, + }, + } as unknown as SearchResponse); + mockElasticsearchClient.msearch.mockResolvedValue({ + responses: [{ status: 200, hits: { hits: [{ _id: 'some-id' }, { _id: 'some-id-2' }] } }], + } as MsearchMultiSearchResult); + + await sessionIndex.cleanUp(); + + // Only search call for the invalid sessions (use `pit` as marker, since concurrent session limit cleanup + // routine doesn't rely on PIT). + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(2); + expect(mockElasticsearchClient.search).toHaveBeenNthCalledWith( + 2, + expectedSearchParameters() + ); + + expect(mockElasticsearchClient.msearch).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.msearch).toHaveBeenCalledWith({ + index: '.kibana_some_tenant_security_session', + searches: [{}, expectedMultiSearchParameters('user-hash-name', 'basic', 'basic1')], + filter_path: ['responses.status', 'responses.hits.hits._id'], + }); + expect(mockElasticsearchClient.bulk).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.bulk).toHaveBeenCalledWith( + { + index: '.kibana_some_tenant_security_session', + operations: [{ delete: { _id: 'some-id' } }, { delete: { _id: 'some-id-2' } }], + refresh: false, + require_alias: true, + }, + { ignore: [409, 404] } + ); + expect(mockElasticsearchClient.indices.refresh).toHaveBeenCalledTimes(1); + }); + + it('when the concurrent session limit is exceeded for multiple providers', async () => { + mockElasticsearchClient.search.mockResolvedValueOnce({ + aggregations: { + sessions_grouped_by_user: { + sum_other_doc_count: 1, + buckets: [ + { key: ['user-hash-name', 'basic', 'basic1'], doc_count: 10 }, + // For this we simulate a race condition, when the limit is exceeded during aggregation, but not during + // `msearch` query. + { key: ['user-hash-name-2', 'basic', 'basic1'], doc_count: 1 }, + { key: ['user-hash-name-3', 'saml', 'saml1'], doc_count: 10 }, + ], + }, + }, + } as unknown as SearchResponse); + mockElasticsearchClient.msearch.mockResolvedValue({ + responses: [ + { status: 200, hits: { hits: [{ _id: 'some-id' }, { _id: 'some-id-2' }] } }, + { status: 200 }, + { status: 200, hits: { hits: [{ _id: 'some-id-3' }] } }, + ], + } as MsearchMultiSearchResult); + + await sessionIndex.cleanUp(); + + // Only search call for the invalid sessions (use `pit` as marker, since concurrent session limit cleanup + // routine doesn't rely on PIT). + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(2); + expect(mockElasticsearchClient.search).toHaveBeenNthCalledWith( + 2, + expectedSearchParameters() + ); + + expect(mockElasticsearchClient.msearch).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.msearch).toHaveBeenCalledWith({ + index: '.kibana_some_tenant_security_session', + searches: [ + {}, + expectedMultiSearchParameters('user-hash-name', 'basic', 'basic1'), + {}, + expectedMultiSearchParameters('user-hash-name-2', 'basic', 'basic1'), + {}, + expectedMultiSearchParameters('user-hash-name-3', 'saml', 'saml1'), + ], + filter_path: ['responses.status', 'responses.hits.hits._id'], + }); + expect(mockElasticsearchClient.bulk).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.bulk).toHaveBeenCalledWith( + { + index: '.kibana_some_tenant_security_session', + operations: [ + { delete: { _id: 'some-id' } }, + { delete: { _id: 'some-id-2' } }, + { delete: { _id: 'some-id-3' } }, + ], + refresh: false, + require_alias: true, + }, + { ignore: [409, 404] } + ); + expect(mockElasticsearchClient.indices.refresh).toHaveBeenCalledTimes(1); + }); + + it('should call bulk_delete in multiple chunks if total number of session to delete exceeds 10_000', async () => { + mockElasticsearchClient.search.mockResolvedValueOnce({ + aggregations: { + sessions_grouped_by_user: { + sum_other_doc_count: 1, + buckets: [{ key: ['user-hash-name', 'basic', 'basic1'], doc_count: 10 }], + }, + }, + } as unknown as SearchResponse); + mockElasticsearchClient.msearch.mockResolvedValue({ + responses: [ + { + status: 200, + hits: { + hits: Array.from({ length: 10002 }).map((_, index) => ({ + _id: `some-id-${index}`, + })), + }, + }, + ], + } as MsearchMultiSearchResult); + + await sessionIndex.cleanUp(); + + expect(mockElasticsearchClient.bulk).toHaveBeenCalledTimes(2); + expect(mockElasticsearchClient.bulk).toHaveBeenNthCalledWith( + 1, + { + index: '.kibana_some_tenant_security_session', + operations: expect.arrayContaining([ + { delete: { _id: 'some-id-0' } }, + { delete: { _id: 'some-id-9999' } }, + ]), + refresh: false, + require_alias: true, + }, + { ignore: [409, 404] } + ); + expect(mockElasticsearchClient.bulk).toHaveBeenNthCalledWith( + 2, + { + index: '.kibana_some_tenant_security_session', + operations: [ + { delete: { _id: 'some-id-10000' } }, + { delete: { _id: 'some-id-10001' } }, + ], + refresh: false, + require_alias: true, + }, + { ignore: [409, 404] } + ); + expect(mockElasticsearchClient.indices.refresh).toHaveBeenCalledTimes(1); + }); + + it('should log audit event', async () => { + mockElasticsearchClient.search.mockResolvedValueOnce({ + aggregations: { + sessions_grouped_by_user: { + sum_other_doc_count: 1, + buckets: [ + { key: ['user-hash-name', 'basic', 'basic1'], doc_count: 3 }, + { key: ['user-hash-name-2', 'saml', 'saml1'], doc_count: 3 }, + ], + }, + }, + } as unknown as SearchResponse); + mockElasticsearchClient.msearch.mockResolvedValue({ + responses: [ + { status: 200, hits: { hits: [{ _id: 'some-id' }] } }, + { status: 200, hits: { hits: [{ _id: 'some-id-2' }] } }, + ], + } as MsearchMultiSearchResult); + + await sessionIndex.cleanUp(); + + expect(auditLogger.log).toHaveBeenCalledTimes(2); + expect(auditLogger.log).toHaveBeenCalledWith( + expect.objectContaining({ + event: { action: 'session_cleanup', category: ['authentication'], outcome: 'unknown' }, + user: { hash: 'user-hash-name' }, + kibana: { + session_id: 'some-id', + authentication_provider: 'basic1', + authentication_type: 'basic', + }, + }) + ); + expect(auditLogger.log).toHaveBeenCalledWith( + expect.objectContaining({ + event: { action: 'session_cleanup', category: ['authentication'], outcome: 'unknown' }, + user: { hash: 'user-hash-name-2' }, + kibana: { + session_id: 'some-id-2', + authentication_provider: 'saml1', + authentication_type: 'saml', + }, + }) + ); + }); + }); }); describe('#get', () => { @@ -1480,4 +1797,167 @@ describe('Session index', () => { }); }); }); + + describe('#isWithinConcurrentSessionLimit', () => { + const expectedSearchParameters = () => ({ + index: '.kibana_some_tenant_security_session', + query: { + bool: { + filter: [ + { term: { usernameHash: 'some-username-hash' } }, + { term: { 'provider.type': 'basic' } }, + { term: { 'provider.name': 'basic1' } }, + ], + }, + }, + sort: [{ createdAt: { order: 'desc' } }], + _source_includes: 'createdAt', + filter_path: 'hits.hits._source', + from: 2, + size: 1, + track_total_hits: false, + }); + + beforeEach(() => { + sessionIndex = new SessionIndex( + createSessionIndexOptions({ + session: { idleTimeout: null, lifespan: null, concurrentSessions: { maxSessions: 2 } }, + }) + ); + }); + + it('throws if call to Elasticsearch fails', async () => { + const failureReason = new errors.ResponseError( + securityMock.createApiResponse(securityMock.createApiResponse({ body: { type: 'Uh oh.' } })) + ); + mockElasticsearchClient.search.mockRejectedValue(failureReason); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit(sessionIndexMock.createValue()) + ).rejects.toBe(failureReason); + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith(expectedSearchParameters()); + }); + + it('returns `true` if concurrent session limit is not configured', async () => { + sessionIndex = new SessionIndex(createSessionIndexOptions()); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit(sessionIndexMock.createValue()) + ).resolves.toBe(true); + expect(mockElasticsearchClient.search).not.toHaveBeenCalled(); + }); + + it('returns `true` for unauthenticated sessions', async () => { + await expect( + sessionIndex.isWithinConcurrentSessionLimit( + sessionIndexMock.createValue({ usernameHash: undefined }) + ) + ).resolves.toBe(true); + expect(mockElasticsearchClient.search).not.toHaveBeenCalled(); + }); + + it('returns `true` if session belongs to the anonymous user', async () => { + await expect( + sessionIndex.isWithinConcurrentSessionLimit( + sessionIndexMock.createValue({ + createdAt: 100, + provider: { type: AnonymousAuthenticationProvider.type, name: 'anonymous1' }, + }) + ) + ).resolves.toBe(true); + expect(mockElasticsearchClient.search).not.toHaveBeenCalled(); + }); + + it('returns `true` if session is within limit', async () => { + for (const value of [ + {} as SearchResponse, + { hits: { hits: [] } } as unknown as SearchResponse, + ]) { + mockElasticsearchClient.search.mockResolvedValue(value); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit(sessionIndexMock.createValue()) + ).resolves.toBe(true); + + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith(expectedSearchParameters()); + + mockElasticsearchClient.search.mockClear(); + } + }); + + it('returns `true` if the specified session is not a legacy session, but the first session that is outside the limit is a legacy one', async () => { + mockElasticsearchClient.search.mockResolvedValue({ + hits: { hits: [{ _source: {} }] }, + } as SearchResponse); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit(sessionIndexMock.createValue()) + ).resolves.toBe(true); + + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith(expectedSearchParameters()); + }); + + it('returns `true` if the first session that is outside the limit is older than the specified session', async () => { + mockElasticsearchClient.search.mockResolvedValue({ + hits: { hits: [{ _source: { createdAt: 100 } }] }, + } as SearchResponse); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit( + sessionIndexMock.createValue({ createdAt: 200 }) + ) + ).resolves.toBe(true); + + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith(expectedSearchParameters()); + }); + + it('returns `false` if the limit is exceeded and specified session is a legacy session', async () => { + mockElasticsearchClient.search.mockResolvedValue({ + hits: { hits: [{ _source: { createdAt: 100 } }] }, + } as SearchResponse); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit( + sessionIndexMock.createValue({ createdAt: undefined }) + ) + ).resolves.toBe(false); + + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith(expectedSearchParameters()); + }); + + it('returns `false` if the first session that is outside the limit was created at the same time as the specified session', async () => { + mockElasticsearchClient.search.mockResolvedValue({ + hits: { hits: [{ _source: { createdAt: 100 } }] }, + } as SearchResponse); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit( + sessionIndexMock.createValue({ createdAt: 100 }) + ) + ).resolves.toBe(false); + + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith(expectedSearchParameters()); + }); + + it('returns `false` if the specified session is older than the first session that is outside the limit', async () => { + mockElasticsearchClient.search.mockResolvedValue({ + hits: { hits: [{ _source: { createdAt: 200 } }] }, + } as SearchResponse); + + await expect( + sessionIndex.isWithinConcurrentSessionLimit( + sessionIndexMock.createValue({ createdAt: 100 }) + ) + ).resolves.toBe(false); + + expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1); + expect(mockElasticsearchClient.search).toHaveBeenCalledWith(expectedSearchParameters()); + }); + }); }); diff --git a/x-pack/plugins/security/server/session_management/session_index.ts b/x-pack/plugins/security/server/session_management/session_index.ts index ab8882cbc4b0d1..9041745c7d6253 100644 --- a/x-pack/plugins/security/server/session_management/session_index.ts +++ b/x-pack/plugins/security/server/session_management/session_index.ts @@ -5,7 +5,14 @@ * 2.0. */ -import type { CreateRequest, IndicesCreateRequest } from '@elastic/elasticsearch/lib/api/types'; +import type { + AggregateName, + AggregationsMultiTermsAggregate, + CreateRequest, + IndicesCreateRequest, + MsearchRequestItem, + SearchHit, +} from '@elastic/elasticsearch/lib/api/types'; import type { BulkOperationContainer, SortResults, @@ -16,8 +23,10 @@ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import type { AuthenticationProvider } from '../../common/model'; import type { AuditLogger } from '../audit'; -import { sessionCleanupEvent } from '../audit'; +import { sessionCleanupConcurrentLimitEvent, sessionCleanupEvent } from '../audit'; +import { AnonymousAuthenticationProvider } from '../authentication'; import type { ConfigType } from '../config'; +import { getDetailedErrorMessage } from '../errors'; export interface SessionIndexOptions { readonly elasticsearchClient: ElasticsearchClient; @@ -166,6 +175,11 @@ export interface SessionIndexValue { metadata: SessionIndexValueMetadata; } +/** + * Subset of the `SessionIndexValue` fields required for session cleanup. + */ +type SessionIndexValueDescriptor = Pick; + /** * Additional index specific information about the session value. */ @@ -453,71 +467,153 @@ export class SessionIndex { * Trigger a removal of any outdated session values. */ async cleanUp() { - const { auditLogger, elasticsearchClient, logger } = this.options; - logger.debug(`Running cleanup routine.`); + const { auditLogger, logger } = this.options; + logger.debug('Running cleanup routine.'); let error: Error | undefined; let indexNeedsRefresh = false; try { for await (const sessionValues of this.getSessionValuesInBatches()) { - const operations: Array>> = []; - sessionValues.forEach(({ _id, _source }) => { + const operations = sessionValues.map(({ _id, _source }) => { const { usernameHash, provider } = _source!; auditLogger.log(sessionCleanupEvent({ sessionId: _id, usernameHash, provider })); - operations.push({ delete: { _id } }); + return { delete: { _id } }; }); - if (operations.length > 0) { - const bulkResponse = await elasticsearchClient.bulk( - { - index: this.aliasName, - operations, - refresh: false, - // delete operations do not respect `require_alias`, but we include it here for consistency. - require_alias: true, - }, - { ignore: [409, 404] } - ); - if (bulkResponse.errors) { - const errorCount = bulkResponse.items.reduce( - (count, item) => (item.delete!.error ? count + 1 : count), - 0 - ); - if (errorCount < bulkResponse.items.length) { - logger.warn( - `Failed to clean up ${errorCount} of ${bulkResponse.items.length} invalid or expired sessions. The remaining sessions were cleaned up successfully.` - ); - indexNeedsRefresh = true; - } else { - logger.error( - `Failed to clean up ${bulkResponse.items.length} invalid or expired sessions.` - ); - } - } else { - logger.debug(`Cleaned up ${bulkResponse.items.length} invalid or expired sessions.`); - indexNeedsRefresh = true; - } - } + + indexNeedsRefresh = (await this.bulkDeleteSessions(operations)) || indexNeedsRefresh; } } catch (err) { logger.error(`Failed to clean up sessions: ${err.message}`); error = err; } + // Only refresh the index if we have actually deleted one or more sessions. The index will auto-refresh eventually anyway, this just + // ensures that searches after the cleanup process are accurate, and this only impacts integration tests. if (indexNeedsRefresh) { - // Only refresh the index if we have actually deleted one or more sessions. The index will auto-refresh eventually anyway, this just - // ensures that searches after the cleanup process are accurate, and this only impacts integration tests. - try { - await elasticsearchClient.indices.refresh({ index: this.aliasName }); - logger.debug(`Refreshed session index.`); - } catch (err) { - logger.error(`Failed to refresh session index: ${err.message}`); + await this.refreshSessionIndex(); + } + + // Once index refresh is complete we can check if there are sessions left that exceed concurrent sessions limit. + try { + indexNeedsRefresh = false; + + const operations = (await this.getSessionsOutsideConcurrentSessionLimit()).map((session) => { + auditLogger.log( + sessionCleanupConcurrentLimitEvent({ + sessionId: session.sid, + usernameHash: session.usernameHash, + provider: session.provider, + }) + ); + return { delete: { _id: session.sid } }; + }); + + if (operations.length > 0) { + // Limit max number of documents to delete to 10_000 to avoid massively large delete request payloads (10k batch + // delete request payload is about 700kb). + const batchSize = SESSION_INDEX_CLEANUP_BATCH_SIZE; + for (let i = 0; i < operations.length; i += batchSize) { + indexNeedsRefresh = + (await this.bulkDeleteSessions(operations.slice(i, i + batchSize))) || + indexNeedsRefresh; + } } + } catch (err) { + logger.error( + `Failed to clean up sessions that exceeded concurrent sessions limit: ${err.message}` + ); + error = err; + } + + if (indexNeedsRefresh) { + await this.refreshSessionIndex(); } if (error) { + logger.error(`Cleanup routine failed: ${getDetailedErrorMessage(error)}.`); // If we couldn't fetch or delete sessions, throw an error so the task will be retried. throw error; } + + logger.debug('Cleanup routine successfully completed.'); + } + + /** + * Checks whether specific session is within a concurrent sessions limit. + * @param sessionValue Session index value to check against concurrent sessions limit. + */ + async isWithinConcurrentSessionLimit(sessionValue: Readonly) { + // Concurrent user sessions limit doesn't apply if it's not configured, or session isn't authenticated, or session + // belongs to the anonymous user. + const maxConcurrentSessions = this.options.config.session.concurrentSessions?.maxSessions; + if ( + maxConcurrentSessions == null || + !sessionValue.usernameHash || + sessionValue.provider.type === AnonymousAuthenticationProvider.type + ) { + return true; + } + + let sessionsOutsideLimit: Array>; + try { + const searchResponse = await this.options.elasticsearchClient.search({ + index: this.aliasName, + + // Find all sessions created for the same user by the same authentication provider. + query: { + bool: { + filter: [ + { term: { usernameHash: sessionValue.usernameHash } }, + { term: { 'provider.type': sessionValue.provider.type } }, + { term: { 'provider.name': sessionValue.provider.name } }, + ], + }, + }, + + // Sort sessions by creation date in descending order to get the most recent session that's also outside the + // limit. This query relies on a default value for `missing` sort parameter which is `_last`, meaning that + // sessions without `createdAt` field ("legacy" sessions) are always considered older than the ones that have + // this field populated. For example, if the limit is 2 the resulting set might look like this: + // { createdAt: 3 } <-- the most recent session (within the limit, not returned because of `from`) + // { createdAt: 2 } <-- the second most recent session (within the limit, not returned because of `from`) + // { createdAt: 1 } <-- the third most recent session (outside the limit, *returned*) + // { createdAt: undefined } <--- the oldest "legacy" session (outside the limit, not returned because of `size`) + sort: [{ createdAt: { order: 'desc' } }], + + // Improve performance by fetching just one field of one outside-the-limit session and not tracking total hits. + _source_includes: 'createdAt', + filter_path: 'hits.hits._source', + from: maxConcurrentSessions, + size: 1, + track_total_hits: false, + }); + sessionsOutsideLimit = searchResponse.hits?.hits ?? []; + } catch (err) { + this.options.logger.error( + `Failed to fetch user sessions to check concurrent sessions limit: ${err.message}.` + ); + throw err; + } + + // If all sessions are within the limit, then the provided one should be within the limit as well. + if (sessionsOutsideLimit.length === 0) { + return true; + } + + // If there is any session that is outside the limit and the provided session is "legacy" session (doesn't have a + // `createdAt` field populated), then we can safely treat it as outside-the-limit session (all "legacy" sessions are + // treated equally). + if (!sessionValue.createdAt) { + return false; + } + + // If the first outside-the-limit session doesn't have `createdAt` then all other sessions with `createdAt` are + // within the limit, otherwise the specified session is outside the limit only if it was created before or at the + // same time as the first outside-the-limit session. + const [{ _source: sessionOutsideLimit }] = sessionsOutsideLimit; + return ( + !sessionOutsideLimit?.createdAt || sessionValue.createdAt > sessionOutsideLimit.createdAt + ); } /** @@ -766,4 +862,231 @@ export class SessionIndex { }); } } + + private async getSessionsOutsideConcurrentSessionLimit(): Promise { + const maxConcurrentSessions = this.options.config.session.concurrentSessions?.maxSessions; + if (maxConcurrentSessions == null) { + return []; + } + + // 1. We need to figure out what users have sessions that exceed the concurrent session limit. For that, we group + // existing sessions by username and authentication provider. + const aggResponse = await this.options.elasticsearchClient.search< + unknown, + Record + >({ + index: this.aliasName, + + // Exclude unauthenticated sessions and sessions of the anonymous users that shouldn't be affected by the + // concurrent user sessions limit. + query: { + bool: { + filter: [ + { exists: { field: 'usernameHash' } }, + { + bool: { + must_not: [{ term: { 'provider.type': AnonymousAuthenticationProvider.type } }], + }, + }, + ], + }, + }, + + aggs: { + sessions_grouped_by_user: { + multi_terms: { + // If we have more than 10_000 users that all exceeded the limit (highly unlikely), then the rest of the + // sessions will be cleaned up during the next run. It doesn't expose Kibana to any security risks since the + // concurrent sessions limits is enforced on fetch. The `size` is limited by `search.max_buckets` setting + // which is 65,536 by default, but we don't want to load Elasticsearch too much (response size for 10000 + // buckets is around 1mb). + size: SESSION_INDEX_CLEANUP_BATCH_SIZE, + terms: [ + { field: 'usernameHash' }, + { field: 'provider.type' }, + { field: 'provider.name' }, + ], + // Return only those groups that exceed the limit. + min_doc_count: maxConcurrentSessions + 1, + }, + }, + }, + + // Improve performance by not tracking total hits, not returning hits themselves (size=0), and fetching only buckets keys. + size: 0, + filter_path: [ + 'aggregations.sessions_grouped_by_user.sum_other_doc_count', + 'aggregations.sessions_grouped_by_user.buckets.key', + 'aggregations.sessions_grouped_by_user.buckets.doc_count', + ], + track_total_hits: false, + }); + + // The reason we check if buckets is an array is to narrow down the type of the response since ES can return buckets as + // either an array OR a dictionary (aggregation has keys configured for the different buckets, that's not the case here). + const sessionsGroupedByUser = aggResponse.aggregations?.sessions_grouped_by_user; + const sessionBuckets = sessionsGroupedByUser?.buckets ?? []; + if (sessionBuckets.length === 0 || !Array.isArray(sessionBuckets)) { + return []; + } + + // Log a warning if we didn't fetch buckets for all users that exceeded the limit. + const ungroupedSessions = sessionsGroupedByUser?.sum_other_doc_count ?? 0; + if (ungroupedSessions > 0) { + this.options.logger.warn( + `Unable to check if remaining ${ungroupedSessions} sessions exceed the concurrent session limit. Sessions will be checked during the next cleanup job run.` + ); + } + + // 2. Once we know what users within what authentication providers exceed the concurrent sessions limit, we can + // fetch specific sessions documents that are outside the limit. + const { sessionGroups, sessionQueries, skippedSessions } = sessionBuckets.reduce( + (result, sessionGroup) => { + // The keys are arrays of values ordered the same ways as expression in the terms parameter of the aggregation. + const [usernameHash, providerType, providerName] = sessionGroup.key as string[]; + + // Record a number of session documents that won't be included in the batch during this run. + if (sessionGroup.doc_count > SESSION_INDEX_CLEANUP_BATCH_SIZE) { + result.skippedSessions += sessionGroup.doc_count - SESSION_INDEX_CLEANUP_BATCH_SIZE; + } + + result.sessionGroups.push({ + usernameHash, + provider: { type: providerType, name: providerName }, + }); + + result.sessionQueries.push( + {}, + { + query: { + bool: { + must: [ + { term: { usernameHash } }, + { term: { 'provider.type': providerType } }, + { term: { 'provider.name': providerName } }, + ], + }, + }, + + // Sort sessions by creation date in descending order to get the most recent session that's also outside the + // limit. Refer to comment in `isWithinConcurrentSessionLimit` for the explanation and example. + sort: [{ createdAt: { order: 'desc' } }], + + // We only need to fetch sessions that exceed the limit. + from: maxConcurrentSessions, + size: SESSION_INDEX_CLEANUP_BATCH_SIZE - maxConcurrentSessions, + + // Improve performance by not tracking total hits and not fetching _source since we already have all necessary + // data returned within aggregation buckets (`usernameHash` and `provider`). + _source: false, + track_total_hits: false, + } + ); + + return result; + }, + { sessionGroups: [], sessionQueries: [], skippedSessions: 0 } as { + sessionGroups: Array>; + sessionQueries: MsearchRequestItem[]; + skippedSessions: number; + } + ); + + // Log a warning if we didn't fetch all sessions that exceeded the limit. + if (skippedSessions > 0) { + this.options.logger.warn( + `Unable to fetch ${skippedSessions} sessions that exceed the concurrent session limit. Sessions will be fetched and invalidated during the next cleanup job run.` + ); + } + + const { responses } = await this.options.elasticsearchClient.msearch({ + index: this.aliasName, + searches: sessionQueries, + filter_path: ['responses.status', 'responses.hits.hits._id'], + }); + + const sessionValueDescriptors = responses.flatMap( + (response, index) => { + if ('error' in response) { + this.options.logger.error( + `Failed to fetch sessions that exceed the concurrent session limit: ${ + getDetailedErrorMessage(response.error) ?? + response.error.reason ?? + response.error.type + }.` + ); + return []; + } + + return response.hits?.hits?.map((hit) => ({ sid: hit._id, ...sessionGroups[index] })) ?? []; + } + ); + + this.options.logger.debug( + `Preparing to delete ${sessionValueDescriptors.length} sessions of ${sessionBuckets.length} unique users due to exceeded concurrent sessions limit.` + ); + + return sessionValueDescriptors; + } + + /** + * Performs a bulk delete operation on the Kibana session index. + * @param deleteOperations Bulk delete operations. + * @returns Returns `true` if the bulk delete affected any session document. + */ + private async bulkDeleteSessions( + deleteOperations: Array>> + ) { + if (deleteOperations.length === 0) { + return false; + } + + const bulkResponse = await this.options.elasticsearchClient.bulk( + { + index: this.aliasName, + operations: deleteOperations, + refresh: false, + // delete operations do not respect `require_alias`, but we include it here for consistency. + require_alias: true, + }, + { ignore: [409, 404] } + ); + + if (!bulkResponse.errors) { + this.options.logger.debug( + `Cleaned up ${bulkResponse.items.length} invalid or expired sessions.` + ); + return true; + } + + const errorCount = bulkResponse.items.reduce( + (count, item) => (item.delete!.error ? count + 1 : count), + 0 + ); + if (errorCount < bulkResponse.items.length) { + this.options.logger.warn( + `Failed to clean up ${errorCount} of ${bulkResponse.items.length} invalid or expired sessions. The remaining sessions were cleaned up successfully.` + ); + return true; + } + + this.options.logger.error( + `Failed to clean up ${bulkResponse.items.length} invalid or expired sessions.` + ); + + return false; + } + + /** + * Refreshes Kibana session index. This is used as a part of the session index cleanup job only and hence doesn't + * throw even if the operation fails. + */ + private async refreshSessionIndex() { + try { + await this.options.elasticsearchClient.indices.refresh({ index: this.aliasName }); + this.options.logger.debug(`Refreshed session index.`); + } catch (err) { + this.options.logger.error(`Failed to refresh session index: ${err.message}`); + } + } } diff --git a/x-pack/plugins/security/server/session_management/session_management_service.test.ts b/x-pack/plugins/security/server/session_management/session_management_service.test.ts index 000d9151d9fdc5..267f99b3761c4f 100644 --- a/x-pack/plugins/security/server/session_management/session_management_service.test.ts +++ b/x-pack/plugins/security/server/session_management/session_management_service.test.ts @@ -15,8 +15,8 @@ import type { import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; import { nextTick } from '@kbn/test-jest-helpers'; -import type { AuditLogger } from '../audit'; -import { auditLoggerMock } from '../audit/mocks'; +import type { AuditServiceSetup } from '../audit'; +import { auditServiceMock } from '../audit/mocks'; import { ConfigSchema, createConfig } from '../config'; import type { OnlineStatusRetryScheduler } from '../elasticsearch'; import { Session } from './session'; @@ -34,10 +34,10 @@ mockSessionIndexCleanUp.mockResolvedValue(); describe('SessionManagementService', () => { let service: SessionManagementService; - let auditLogger: AuditLogger; + let auditSetupMock: AuditServiceSetup; beforeEach(() => { service = new SessionManagementService(loggingSystemMock.createLogger()); - auditLogger = auditLoggerMock.create(); + auditSetupMock = auditServiceMock.create(); }); afterEach(() => { @@ -100,7 +100,7 @@ describe('SessionManagementService', () => { const mockStatusSubject = new Subject(); expect( service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), @@ -112,7 +112,7 @@ describe('SessionManagementService', () => { it('registers proper session index cleanup task runner', async () => { const mockStatusSubject = new Subject(); service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), @@ -132,7 +132,7 @@ describe('SessionManagementService', () => { it('initializes session index and schedules session index cleanup task when Elasticsearch goes online', async () => { const mockStatusSubject = new Subject(); service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), @@ -170,7 +170,7 @@ describe('SessionManagementService', () => { it('removes old cleanup task if cleanup interval changes', async () => { const mockStatusSubject = new Subject(); service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), @@ -206,7 +206,7 @@ describe('SessionManagementService', () => { it('does not remove old cleanup task if cleanup interval does not change', async () => { const mockStatusSubject = new Subject(); service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), @@ -233,7 +233,7 @@ describe('SessionManagementService', () => { it('schedules retry if index initialization fails', async () => { const mockStatusSubject = new Subject(); service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), @@ -270,7 +270,7 @@ describe('SessionManagementService', () => { it('schedules retry if cleanup task registration fails', async () => { const mockStatusSubject = new Subject(); service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), @@ -323,7 +323,7 @@ describe('SessionManagementService', () => { it('properly unsubscribes from status updates', () => { const mockStatusSubject = new Subject(); service.start({ - auditLogger, + audit: auditSetupMock, elasticsearchClient: elasticsearchServiceMock.createElasticsearchClient(), kibanaIndexName: '.kibana', online$: mockStatusSubject.asObservable(), diff --git a/x-pack/plugins/security/server/session_management/session_management_service.ts b/x-pack/plugins/security/server/session_management/session_management_service.ts index ee79e2eb0f1d3c..289f60aa973c08 100644 --- a/x-pack/plugins/security/server/session_management/session_management_service.ts +++ b/x-pack/plugins/security/server/session_management/session_management_service.ts @@ -14,7 +14,7 @@ import type { TaskManagerStartContract, } from '@kbn/task-manager-plugin/server'; -import type { AuditLogger } from '../audit'; +import type { AuditServiceSetup } from '../audit'; import type { ConfigType } from '../config'; import type { OnlineStatusRetryScheduler } from '../elasticsearch'; import { Session } from './session'; @@ -32,7 +32,7 @@ export interface SessionManagementServiceStartParams { readonly kibanaIndexName: string; readonly online$: Observable; readonly taskManager: TaskManagerStartContract; - readonly auditLogger: AuditLogger; + readonly audit: AuditServiceSetup; } export interface SessionManagementServiceStart { @@ -80,14 +80,14 @@ export class SessionManagementService { kibanaIndexName, online$, taskManager, - auditLogger, + audit, }: SessionManagementServiceStartParams): SessionManagementServiceStart { this.sessionIndex = new SessionIndex({ config: this.config, elasticsearchClient, kibanaIndexName, logger: this.logger.get('index'), - auditLogger, + auditLogger: audit.withoutRequest, }); this.statusSubscription = online$.subscribe(async ({ scheduleRetry }) => { @@ -104,6 +104,7 @@ export class SessionManagementService { sessionCookie: this.sessionCookie, sessionIndex: this.sessionIndex, config: this.config, + audit, }), }; } diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts index 286aed84527af4..8f74d62b64c68c 100644 --- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts @@ -49,6 +49,7 @@ describe('Security UsageCollector', () => { sessionIdleTimeoutInMinutes: 480, sessionLifespanInMinutes: 43200, sessionCleanupInMinutes: 60, + sessionConcurrentSessionsMaxSessions: 0, anonymousCredentialType: undefined, }; @@ -110,6 +111,7 @@ describe('Security UsageCollector', () => { sessionIdleTimeoutInMinutes: 0, sessionLifespanInMinutes: 0, sessionCleanupInMinutes: 0, + sessionConcurrentSessionsMaxSessions: 0, anonymousCredentialType: undefined, }); }); @@ -476,10 +478,15 @@ describe('Security UsageCollector', () => { describe('session', () => { // Note: can't easily test deprecated 'sessionTimeout' value here because of the way that config deprecation renaming works - it('reports customized session idleTimeout, lifespan, and cleanupInterval', async () => { + it('reports customized session idleTimeout, lifespan, cleanupInterval, and max concurrent sessions', async () => { const config = createSecurityConfig( ConfigSchema.validate({ - session: { idleTimeout: '123m', lifespan: '456m', cleanupInterval: '789m' }, + session: { + idleTimeout: '123m', + lifespan: '456m', + cleanupInterval: '789m', + concurrentSessions: { maxSessions: 321 }, + }, }) ); const usageCollection = usageCollectionPluginMock.createSetupContract(); @@ -495,6 +502,7 @@ describe('Security UsageCollector', () => { sessionIdleTimeoutInMinutes: 123, sessionLifespanInMinutes: 456, sessionCleanupInMinutes: 789, + sessionConcurrentSessionsMaxSessions: 321, }); }); }); diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts index d33ff8617e4534..f73ac0bbb25a3b 100644 --- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts @@ -20,6 +20,7 @@ interface Usage { sessionIdleTimeoutInMinutes: number; sessionLifespanInMinutes: number; sessionCleanupInMinutes: number; + sessionConcurrentSessionsMaxSessions: number; anonymousCredentialType: string | undefined; } @@ -123,6 +124,12 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens 'The session cleanup interval that is configured, in minutes (0 if disabled).', }, }, + sessionConcurrentSessionsMaxSessions: { + type: 'long', + _meta: { + description: 'The maximum number of the concurrent user sessions (0 if not configured).', + }, + }, anonymousCredentialType: { type: 'keyword', _meta: { @@ -144,6 +151,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens sessionIdleTimeoutInMinutes: 0, sessionLifespanInMinutes: 0, sessionCleanupInMinutes: 0, + sessionConcurrentSessionsMaxSessions: 0, anonymousCredentialType: undefined, }; } @@ -172,6 +180,8 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens const sessionIdleTimeoutInMinutes = sessionExpirations.idleTimeout?.asMinutes() ?? 0; const sessionLifespanInMinutes = sessionExpirations.lifespan?.asMinutes() ?? 0; const sessionCleanupInMinutes = config.session.cleanupInterval?.asMinutes() ?? 0; + const sessionConcurrentSessionsMaxSessions = + config.session.concurrentSessions?.maxSessions ?? 0; const anonProviders = config.authc.providers.anonymous ?? ({} as Record); const foundProvider = Object.entries(anonProviders).find( @@ -201,6 +211,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens sessionIdleTimeoutInMinutes, sessionLifespanInMinutes, sessionCleanupInMinutes, + sessionConcurrentSessionsMaxSessions, anonymousCredentialType, }; }, diff --git a/x-pack/plugins/security_solution/public/common/components/charts/donutchart.tsx b/x-pack/plugins/security_solution/public/common/components/charts/donutchart.tsx index de7898b2e7296f..949ab19e4ef1d1 100644 --- a/x-pack/plugins/security_solution/public/common/components/charts/donutchart.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/donutchart.tsx @@ -56,7 +56,7 @@ export interface DonutChartProps { export interface DonutChartWrapperProps { children?: React.ReactElement; dataExists: boolean; - label: React.ReactElement | string; + label?: React.ReactElement | string; title: React.ReactElement | string | number | null; isChartEmbeddablesEnabled?: boolean; } @@ -111,17 +111,19 @@ const DonutChartWrapperComponent: React.FC = ({ justifyContent="center" > {title} - - - - {label} - - - + {label && ( + + + + {label} + + + + )} {children} diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/__mocks__/alert_donut_embeddable.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/__mocks__/visualization_embeddable.tsx similarity index 74% rename from x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/__mocks__/alert_donut_embeddable.tsx rename to x-pack/plugins/security_solution/public/common/components/visualization_actions/__mocks__/visualization_embeddable.tsx index 62343b498ea3e0..9979e829923fc7 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/__mocks__/alert_donut_embeddable.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/__mocks__/visualization_embeddable.tsx @@ -7,4 +7,4 @@ import React from 'react'; -export const AlertDonutEmbeddable = () =>
    ; +export const VisualizationEmbeddable = () =>
    ; diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_donut.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_donut.test.ts.snap new file mode 100644 index 00000000000000..2daccdaf1bae55 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_donut.test.ts.snap @@ -0,0 +1,154 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`getRiskScoreDonutAttributes should render 1`] = ` +Object { + "description": "", + "references": Array [], + "state": Object { + "adHocDataViews": Object { + "1dd5663b-f062-43f8-8688-fc8166c2ca8e": Object { + "allowNoIndex": false, + "fieldAttrs": Object {}, + "fieldFormats": Object {}, + "id": "1dd5663b-f062-43f8-8688-fc8166c2ca8e", + "name": "ml_host_risk_score_latest_mockSpaceId", + "runtimeFieldMap": Object {}, + "sourceFilters": Array [], + "timeFieldName": "@timestamp", + "title": "ml_host_risk_score_latest_mockSpaceId", + }, + }, + "datasourceStates": Object { + "formBased": Object { + "layers": Object { + "d594baeb-5eca-480c-8885-ba79eaf41372": Object { + "columnOrder": Array [ + "a2e8541a-c22f-4e43-8a12-caa33edc5de0", + "75179122-96fc-40e1-93b4-8e9310af5f06", + ], + "columns": Object { + "75179122-96fc-40e1-93b4-8e9310af5f06": Object { + "dataType": "number", + "isBucketed": false, + "label": "Count of records", + "operationType": "count", + "params": Object { + "emptyAsNull": true, + }, + "scale": "ratio", + "sourceField": "___records___", + }, + "a2e8541a-c22f-4e43-8a12-caa33edc5de0": Object { + "dataType": "string", + "isBucketed": true, + "label": "Filters", + "operationType": "filters", + "params": Object { + "filters": Array [ + Object { + "input": Object { + "language": "kuery", + "query": "host.risk.calculated_level : \\"Unknown\\"", + }, + "label": "Unknown", + }, + Object { + "input": Object { + "language": "kuery", + "query": "host.risk.calculated_level : \\"Low\\"", + }, + "label": "Low", + }, + Object { + "input": Object { + "language": "kuery", + "query": "host.risk.calculated_level : \\"Moderiate\\"", + }, + "label": "Moderiate", + }, + Object { + "input": Object { + "language": "kuery", + "query": "host.risk.calculated_level : \\"High\\"", + }, + "label": "High", + }, + Object { + "input": Object { + "language": "kuery", + "query": "host.risk.calculated_level : \\"Critical\\"", + }, + "label": "Critical", + }, + ], + }, + "scale": "ordinal", + }, + }, + "incompleteColumns": Object {}, + "sampling": 1, + }, + }, + }, + "textBased": Object { + "layers": Object {}, + }, + }, + "filters": Array [ + Object { + "meta": Object { + "alias": null, + "disabled": false, + "key": "host.id", + "negate": false, + "params": Object { + "query": "123", + }, + "type": "phrase", + }, + "query": Object { + "match_phrase": Object { + "host.id": "123", + }, + }, + }, + ], + "internalReferences": Array [ + Object { + "id": "1dd5663b-f062-43f8-8688-fc8166c2ca8e", + "name": "indexpattern-datasource-layer-d594baeb-5eca-480c-8885-ba79eaf41372", + "type": "index-pattern", + }, + ], + "query": Object { + "language": "kql", + "query": "host.name: *", + }, + "visualization": Object { + "layers": Array [ + Object { + "categoryDisplay": "hide", + "emptySizeRatio": 0.8, + "layerId": "d594baeb-5eca-480c-8885-ba79eaf41372", + "layerType": "data", + "legendDisplay": "hide", + "legendPosition": "right", + "legendSize": "small", + "metrics": Array [ + "75179122-96fc-40e1-93b4-8e9310af5f06", + ], + "nestedLegend": true, + "numberDisplay": "value", + "percentDecimals": 2, + "primaryGroups": Array [ + "a2e8541a-c22f-4e43-8a12-caa33edc5de0", + ], + }, + ], + "shape": "donut", + }, + }, + "title": "host risk donut", + "visualizationType": "lnsPie", +} +`; diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.test.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.test.ts new file mode 100644 index 00000000000000..b7a30e1c029791 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.test.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { wrapper } from '../../../mocks'; + +import { useLensAttributes } from '../../../use_lens_attributes'; + +import { getRiskScoreDonutAttributes } from './risk_score_donut'; + +jest.mock('../../../../../containers/sourcerer', () => ({ + useSourcererDataView: jest.fn().mockReturnValue({ + selectedPatterns: ['auditbeat-mytest-*'], + dataViewId: 'security-solution-my-test', + indicesExist: true, + }), +})); + +jest.mock('../../../../../utils/route/use_route_spy', () => ({ + useRouteSpy: jest.fn().mockReturnValue([ + { + detailName: 'undefined', + pageName: 'overview', + tabName: undefined, + }, + ]), +})); + +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('d594baeb-5eca-480c-8885-ba79eaf41372') + .mockReturnValue('1dd5663b-f062-43f8-8688-fc8166c2ca8e'), +})); + +describe('getRiskScoreDonutAttributes', () => { + it('should render', () => { + const { result } = renderHook( + () => + useLensAttributes({ + getLensAttributes: getRiskScoreDonutAttributes, + stackByField: 'host', + extraOptions: { + spaceId: 'mockSpaceId', + }, + }), + { wrapper } + ); + + expect(result?.current).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.ts new file mode 100644 index 00000000000000..85d71857c83313 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.ts @@ -0,0 +1,145 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 uuid from 'uuid'; +import type { GetLensAttributes } from '../../../types'; + +export const getRiskScoreDonutAttributes: GetLensAttributes = ( + stackByField, + extraOptions = { spaceId: 'default' } +) => { + const layerId = uuid.v4(); + const internalReferenceId = uuid.v4(); + return { + title: `${stackByField} risk donut`, + description: '', + visualizationType: 'lnsPie', + state: { + visualization: { + shape: 'donut', + layers: [ + { + layerId, + primaryGroups: ['a2e8541a-c22f-4e43-8a12-caa33edc5de0'], + metrics: ['75179122-96fc-40e1-93b4-8e9310af5f06'], + numberDisplay: 'value', + categoryDisplay: 'hide', + legendDisplay: 'hide', + nestedLegend: true, + layerType: 'data', + legendSize: 'small', + legendPosition: 'right', + percentDecimals: 2, + emptySizeRatio: 0.8, + }, + ], + }, + query: { + query: '', + language: 'kuery', + }, + filters: [], + datasourceStates: { + formBased: { + layers: { + [layerId]: { + columns: { + 'a2e8541a-c22f-4e43-8a12-caa33edc5de0': { + label: 'Filters', + dataType: 'string', + operationType: 'filters', + scale: 'ordinal', + isBucketed: true, + params: { + filters: [ + { + label: 'Unknown', + input: { + query: `${stackByField}.risk.calculated_level : \"Unknown\"`, + language: 'kuery', + }, + }, + { + input: { + query: `${stackByField}.risk.calculated_level : \"Low\"`, + language: 'kuery', + }, + label: 'Low', + }, + { + input: { + query: `${stackByField}.risk.calculated_level : \"Moderiate\"`, + language: 'kuery', + }, + label: 'Moderiate', + }, + { + input: { + query: `${stackByField}.risk.calculated_level : \"High\"`, + language: 'kuery', + }, + label: 'High', + }, + { + input: { + query: `${stackByField}.risk.calculated_level : \"Critical\"`, + language: 'kuery', + }, + label: 'Critical', + }, + ], + }, + }, + '75179122-96fc-40e1-93b4-8e9310af5f06': { + label: 'Count of records', + dataType: 'number', + operationType: 'count', + isBucketed: false, + scale: 'ratio', + sourceField: '___records___', + params: { + emptyAsNull: true, + }, + }, + }, + columnOrder: [ + 'a2e8541a-c22f-4e43-8a12-caa33edc5de0', + '75179122-96fc-40e1-93b4-8e9310af5f06', + ], + sampling: 1, + incompleteColumns: {}, + }, + }, + }, + textBased: { + layers: {}, + }, + }, + internalReferences: [ + { + type: 'index-pattern', + id: internalReferenceId, + name: `indexpattern-datasource-layer-${layerId}`, + }, + ], + adHocDataViews: { + [internalReferenceId]: { + id: internalReferenceId, + title: `ml_${stackByField}_risk_score_latest_${extraOptions.spaceId}`, + timeFieldName: '@timestamp', + sourceFilters: [], + fieldFormats: {}, + runtimeFieldMap: {}, + fieldAttrs: {}, + allowNoIndex: false, + name: `ml_${stackByField}_risk_score_latest_${extraOptions.spaceId}`, + }, + }, + }, + references: [], + }; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx index 5708aee06ecad0..985a9881d330b1 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx @@ -51,6 +51,7 @@ const initVisualizationData: { const style = { height: '100%', minWidth: '100px' }; const LensEmbeddableComponent: React.FC = ({ + applyGlobalQueriesAndFilters = true, extraActions, extraOptions, getLensAttributes, @@ -72,6 +73,7 @@ const LensEmbeddableComponent: React.FC = ({ const getGlobalQuery = inputsSelectors.globalQueryByIdSelector(); const { searchSessionId } = useDeepEqualSelector((state) => getGlobalQuery(state, id)); const attributes = useLensAttributes({ + applyGlobalQueriesAndFilters, extraOptions, getLensAttributes, lensAttributes, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts index 8b0a84f0843961..ef4830d71bd010 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts @@ -44,6 +44,7 @@ export type OnEmbeddableLoaded = (data: EmbeddableData) => void; export interface LensEmbeddableComponentProps { adHocDataViews?: string[]; + applyGlobalQueriesAndFilters?: boolean; extraActions?: Action[]; extraOptions?: ExtraOptions; getLensAttributes?: GetLensAttributes; @@ -104,3 +105,9 @@ export interface ExtraOptions { spaceId?: string; status?: Status; } + +export interface VisualizationEmbeddableProps extends LensEmbeddableComponentProps { + isDonut?: boolean; + label?: string; + inputId?: InputsModelId.global | InputsModelId.timeline; +} diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx index c7e0fbfa82195b..7451209120e066 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx @@ -21,6 +21,7 @@ import { filterFromSearchBar, queryFromSearchBar, wrapper } from './mocks'; import { useSourcererDataView } from '../../containers/sourcerer'; import { kpiHostMetricLensAttributes } from './lens_attributes/hosts/kpi_host_metric'; import { useRouteSpy } from '../../utils/route/use_route_spy'; +import { SecurityPageName } from '../../../app/types'; jest.mock('../../containers/sourcerer'); jest.mock('../../utils/route/use_route_spy', () => ({ @@ -126,6 +127,32 @@ describe('useLensAttributes', () => { ]); }); + it('should not apply global queries and filters - applyGlobalQueriesAndFilters = false', () => { + (useRouteSpy as jest.Mock).mockReturnValue([ + { + detailName: undefined, + pageName: SecurityPageName.entityAnalytics, + tabName: undefined, + }, + ]); + const { result } = renderHook( + () => + useLensAttributes({ + applyGlobalQueriesAndFilters: false, + getLensAttributes: getExternalAlertLensAttributes, + stackByField: 'event.dataset', + }), + { wrapper } + ); + + expect(result?.current?.state.query.query).toEqual(''); + + expect(result?.current?.state.filters).toEqual([ + ...getExternalAlertLensAttributes().state.filters, + ...getIndexFilters(['auditbeat-*']), + ]); + }); + it('should add data view id to references', () => { const { result } = renderHook( () => diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx index 6ec8370cd168f9..1976a743e5fa16 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx @@ -24,6 +24,7 @@ import { } from './utils'; export const useLensAttributes = ({ + applyGlobalQueriesAndFilters = true, extraOptions, getLensAttributes, lensAttributes, @@ -31,6 +32,7 @@ export const useLensAttributes = ({ stackByField, title, }: { + applyGlobalQueriesAndFilters?: boolean; extraOptions?: ExtraOptions; getLensAttributes?: GetLensAttributes; lensAttributes?: LensAttributes | null; @@ -97,10 +99,10 @@ export const useLensAttributes = ({ ...(title != null ? { title } : {}), state: { ...attrs.state, - query, + ...(applyGlobalQueriesAndFilters ? { query } : {}), filters: [ ...attrs.state.filters, - ...filters, + ...(applyGlobalQueriesAndFilters ? filters : []), ...pageFilters, ...tabsFilters, ...indexFilters, @@ -112,6 +114,7 @@ export const useLensAttributes = ({ })), } as LensAttributes; }, [ + applyGlobalQueriesAndFilters, attrs, dataViewId, filters, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx new file mode 100644 index 00000000000000..c53835c0f86b95 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 type { RenderResult } from '@testing-library/react'; +import { render } from '@testing-library/react'; +import { kpiHostMetricLensAttributes } from './lens_attributes/hosts/kpi_host_metric'; +import { VisualizationEmbeddable } from './visualization_embeddable'; +import * as inputActions from '../../store/inputs/actions'; +import { InputsModelId } from '../../store/inputs/constants'; +import { + createSecuritySolutionStorageMock, + kibanaObservable, + mockGlobalState, + SUB_PLUGINS_REDUCER, + TestProviders, +} from '../../mock'; +import { createStore } from '../../store'; +import type { State } from '../../store'; +import { useRefetchByRestartingSession } from '../page/use_refetch_by_session'; +import { getRiskScoreDonutAttributes } from './lens_attributes/common/risk_scores/risk_score_donut'; +import { TOTAL_LABEL } from '../../../overview/components/entity_analytics/common/translations'; + +jest.mock('./lens_embeddable'); +jest.mock('../page/use_refetch_by_session', () => ({ + useRefetchByRestartingSession: jest.fn(), +})); + +let res: RenderResult; +const mockSearchSessionId = 'mockSearchSessionId'; +const mockSearchSessionIdDefault = 'mockSearchSessionIdDefault'; +const mockRefetchByRestartingSession = jest.fn(); +const mockSetQuery = jest.spyOn(inputActions, 'setQuery'); +const mockDeleteQuery = jest.spyOn(inputActions, 'deleteOneQuery'); +const state: State = { + ...mockGlobalState, +}; +const { storage } = createSecuritySolutionStorageMock(); +const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); +describe('VisualizationEmbeddable', () => { + describe('when isDonut = false', () => { + beforeEach(() => { + jest.clearAllMocks(); + (useRefetchByRestartingSession as jest.Mock).mockReturnValue({ + session: { + current: { + start: jest + .fn() + .mockReturnValueOnce(mockSearchSessionId) + .mockReturnValue(mockSearchSessionIdDefault), + }, + }, + refetchByRestartingSession: mockRefetchByRestartingSession, + }); + res = render( + + + + ); + }); + + it('should render LensEmbeddable', () => { + expect(res.getByTestId('lens-embeddable')).toBeInTheDocument(); + }); + + it('should set query', () => { + expect(mockSetQuery).toHaveBeenCalledTimes(1); + expect(mockSetQuery).toHaveBeenCalledWith({ + inputId: InputsModelId.global, + id: 'testId', + searchSessionId: mockSearchSessionId, + refetch: mockRefetchByRestartingSession, + loading: false, + inspect: null, + }); + }); + + it('should delete query when unmount', () => { + res.unmount(); + expect(mockDeleteQuery).toHaveBeenCalledWith({ + inputId: InputsModelId.global, + id: 'testId', + }); + }); + }); + + describe('when isDonut = true', () => { + beforeEach(() => { + jest.clearAllMocks(); + (useRefetchByRestartingSession as jest.Mock).mockReturnValue({ + session: { + current: { + start: jest + .fn() + .mockReturnValueOnce(mockSearchSessionId) + .mockReturnValue(mockSearchSessionIdDefault), + }, + }, + refetchByRestartingSession: mockRefetchByRestartingSession, + }); + res = render( + + + + ); + }); + + it('should render donut wrapper ', () => { + expect(res.getByTestId('donut-chart')).toBeInTheDocument(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.tsx new file mode 100644 index 00000000000000..c2807d7fd8263c --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.tsx @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import { ChartLabel } from '../../../overview/components/detection_response/alerts_by_status/chart_label'; +import type { VisualizationAlertsByStatusResponse } from '../../../overview/components/detection_response/alerts_by_status/types'; +import { useDeepEqualSelector } from '../../hooks/use_selector'; +import { inputsActions, inputsSelectors } from '../../store/inputs'; +import { DonutChartWrapper } from '../charts/donutchart'; +import { parseVisualizationData } from './utils'; +import { InputsModelId } from '../../store/inputs/constants'; +import { useRefetchByRestartingSession } from '../page/use_refetch_by_session'; +import { LensEmbeddable } from './lens_embeddable'; +import type { EmbeddableData, VisualizationEmbeddableProps } from './types'; + +const VisualizationEmbeddableComponent: React.FC = (props) => { + const dispatch = useDispatch(); + const { inputId = InputsModelId.global, id, isDonut, label, onLoad, ...lensPorps } = props; + const { session, refetchByRestartingSession } = useRefetchByRestartingSession({ + inputId, + queryId: id, + }); + const getGlobalQuery = inputsSelectors.globalQueryByIdSelector(); + const { inspect } = useDeepEqualSelector((state) => getGlobalQuery(state, id)); + const visualizationData = inspect?.response + ? parseVisualizationData(inspect?.response) + : null; + const dataExists = visualizationData != null && visualizationData[0]?.hits.total !== 0; + + const onEmbeddableLoad = useCallback( + ({ requests, responses, isLoading }: EmbeddableData) => { + dispatch( + inputsActions.setQuery({ + inputId, + id, + searchSessionId: session.current.start(), + refetch: refetchByRestartingSession, + loading: isLoading, + inspect: { dsl: requests, response: responses }, + }) + ); + + if (typeof onLoad === 'function') { + onLoad({ requests, responses, isLoading }); + } + }, + [dispatch, inputId, id, session, refetchByRestartingSession, onLoad] + ); + + useEffect(() => { + dispatch( + inputsActions.setQuery({ + inputId, + id, + searchSessionId: session.current.start(), + refetch: refetchByRestartingSession, + loading: false, + inspect: null, + }) + ); + }, [dispatch, inputId, id, refetchByRestartingSession, session]); + + useEffect(() => { + return () => { + dispatch(inputsActions.deleteOneQuery({ inputId, id })); + }; + }, [dispatch, id, inputId]); + + if (isDonut) { + return ( + : null} + > + + + ); + } + + return ; +}; + +export const VisualizationEmbeddable = React.memo(VisualizationEmbeddableComponent); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx index f40f1dd0fecc08..0352dd03bbcff9 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx @@ -6,7 +6,7 @@ */ import React, { memo } from 'react'; -import { useKibana } from '../lib/kibana'; +import { KibanaServices, useKibana } from '../lib/kibana'; import type { RenderHookResult } from '@testing-library/react-hooks'; import { renderHook as _renderHook } from '@testing-library/react-hooks'; import { useUpgradeSecurityPackages } from './use_upgrade_security_packages'; @@ -23,8 +23,11 @@ jest.mock('../components/user_privileges', () => { }); jest.mock('../lib/kibana'); -// FLAKY: https://github.com/elastic/kibana/issues/112910 -describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { +describe('When using the `useUpgradeSecurityPackages()` hook', () => { + const mockGetPrebuiltRulesPackageVersion = + KibanaServices.getPrebuiltRulesPackageVersion as jest.Mock; + const mockGetKibanaVersion = KibanaServices.getKibanaVersion as jest.Mock; + const mockGetKibanaBranch = KibanaServices.getKibanaBranch as jest.Mock; let renderResult: RenderHookResult; let renderHook: () => RenderHookResult; let kibana: ReturnType; @@ -43,6 +46,7 @@ describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { }); afterEach(() => { + jest.clearAllMocks(); if (renderResult) { renderResult.unmount(); } @@ -65,4 +69,104 @@ describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { }) ); }); + + it('should send upgrade request with prerelease:false if branch is not `main` and build does not include `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0'); + mockGetKibanaBranch.mockReturnValue('release'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: false }), + }) + ); + }); + + it('should send upgrade request with prerelease:true if branch is `main` AND build includes `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0-SNAPSHOT'); + mockGetKibanaBranch.mockReturnValue('main'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); + + it('should send upgrade request with prerelease:true if branch is `release` and build includes `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0-SNAPSHOT'); + mockGetKibanaBranch.mockReturnValue('release'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); + + it('should send upgrade request with prerelease:true if branch is `main` and build does not include `-SNAPSHOT`', async () => { + mockGetKibanaVersion.mockReturnValue('8.0.0'); + mockGetKibanaBranch.mockReturnValue('main'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenCalledWith( + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: '{"packages":["endpoint","security_detection_engine"]}', + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); + + it('should send separate upgrade requests if prebuiltRulesPackageVersion is provided', async () => { + mockGetPrebuiltRulesPackageVersion.mockReturnValue('8.2.1'); + + renderHook(); + + await renderResult.waitFor( + () => (kibana.services.http.post as jest.Mock).mock.calls.length > 0 + ); + + expect(kibana.services.http.post).toHaveBeenNthCalledWith( + 1, + `${epmRouteService.getInstallPath('security_detection_engine', '8.2.1')}`, + expect.objectContaining({ query: { prerelease: true } }) + ); + expect(kibana.services.http.post).toHaveBeenNthCalledWith( + 2, + `${epmRouteService.getBulkInstallPath()}`, + expect.objectContaining({ + body: expect.stringContaining('endpoint'), + query: expect.objectContaining({ prerelease: true }), + }) + ); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts index 848f1458502ca1..1354770b7384dc 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_security_packages.ts @@ -9,7 +9,8 @@ import { useEffect } from 'react'; import type { HttpFetchOptions, HttpStart } from '@kbn/core/public'; import type { BulkInstallPackagesResponse } from '@kbn/fleet-plugin/common'; import { epmRouteService } from '@kbn/fleet-plugin/common'; -import { useKibana } from '../lib/kibana'; +import type { InstallPackageResponse } from '@kbn/fleet-plugin/common/types'; +import { KibanaServices, useKibana } from '../lib/kibana'; import { useUserPrivileges } from '../components/user_privileges'; /** @@ -17,17 +18,44 @@ import { useUserPrivileges } from '../components/user_privileges'; * * @param http an http client for sending the request * @param options an object containing options for the request + * @param prebuiltRulesPackageVersion specific version of the prebuilt rules package to install */ const sendUpgradeSecurityPackages = async ( http: HttpStart, - options: HttpFetchOptions = {} -): Promise => { - return http.post(epmRouteService.getBulkInstallPath(), { - ...options, - body: JSON.stringify({ - packages: ['endpoint', 'security_detection_engine'], - }), - }); + options: HttpFetchOptions = {}, + prebuiltRulesPackageVersion?: string +): Promise => { + const packages = ['endpoint', 'security_detection_engine']; + const requests: Array> = []; + + // If `prebuiltRulesPackageVersion` is provided, try to install that version + // Must be done as two separate requests as bulk API doesn't support versions + if (prebuiltRulesPackageVersion != null) { + packages.splice(packages.indexOf('security_detection_engine'), 1); + requests.push( + http.post( + epmRouteService.getInstallPath('security_detection_engine', prebuiltRulesPackageVersion), + { + ...options, + body: JSON.stringify({ + force: true, + }), + } + ) + ); + } + + // Note: if `prerelease:true` option is provided, endpoint package will also be installed as prerelease + requests.push( + http.post(epmRouteService.getBulkInstallPath(), { + ...options, + body: JSON.stringify({ + packages, + }), + }) + ); + + await Promise.allSettled(requests); }; export const useUpgradeSecurityPackages = () => { @@ -50,8 +78,23 @@ export const useUpgradeSecurityPackages = () => { // Make sure fleet is initialized first await context.services.fleet?.isInitialized(); + // Always install the latest package if in dev env or snapshot build + const isPrerelease = + KibanaServices.getKibanaVersion().includes('-SNAPSHOT') || + KibanaServices.getKibanaBranch() === 'main'; + // ignore the response for now since we aren't notifying the user - await sendUpgradeSecurityPackages(context.services.http, { signal }); + // Note: response would be Promise.allSettled, so must iterate all responses for errors and throw manually + await sendUpgradeSecurityPackages( + context.services.http, + { + query: { + prerelease: isPrerelease, + }, + signal, + }, + KibanaServices.getPrebuiltRulesPackageVersion() + ); } catch (error) { // Ignore Errors, since this should not hinder the user's ability to use the UI diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts index 6b736e3fbb5033..2822a48669b32d 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts @@ -36,6 +36,8 @@ export const KibanaServices = { }; }), getKibanaVersion: jest.fn(() => '8.0.0'), + getKibanaBranch: jest.fn(() => 'main'), + getPrebuiltRulesPackageVersion: jest.fn(() => undefined), }; export const useKibana = jest.fn().mockReturnValue({ services: { diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts index 7b38c7e2a4218e..cbd2ddce441ae9 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/services.ts @@ -12,7 +12,9 @@ type GlobalServices = Pick; export class KibanaServices { + private static kibanaBranch?: string; private static kibanaVersion?: string; + private static prebuiltRulesPackageVersion?: string; private static services?: GlobalServices; public static init({ @@ -20,19 +22,20 @@ export class KibanaServices { application, data, unifiedSearch, + kibanaBranch, kibanaVersion, + prebuiltRulesPackageVersion, uiSettings, notifications, - }: GlobalServices & { kibanaVersion: string }) { - this.services = { - application, - data, - http, - uiSettings, - unifiedSearch, - notifications, - }; + }: GlobalServices & { + kibanaBranch: string; + kibanaVersion: string; + prebuiltRulesPackageVersion?: string; + }) { + this.services = { application, data, http, uiSettings, unifiedSearch, notifications }; + this.kibanaBranch = kibanaBranch; this.kibanaVersion = kibanaVersion; + this.prebuiltRulesPackageVersion = prebuiltRulesPackageVersion; } public static get(): GlobalServices { @@ -43,6 +46,14 @@ export class KibanaServices { return this.services; } + public static getKibanaBranch(): string { + if (!this.kibanaBranch) { + this.throwUninitializedError(); + } + + return this.kibanaBranch; + } + public static getKibanaVersion(): string { if (!this.kibanaVersion) { this.throwUninitializedError(); @@ -51,6 +62,10 @@ export class KibanaServices { return this.kibanaVersion; } + public static getPrebuiltRulesPackageVersion(): string | undefined { + return this.prebuiltRulesPackageVersion; + } + private static throwUninitializedError(): never { throw new Error( 'Kibana services not initialized - are you trying to import this module from outside of the SIEM app?' diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx index 2e2cdbdd3eda5e..5a9d092ad50974 100644 --- a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx @@ -292,6 +292,7 @@ export const createAppRootMockRenderer = (): AppContextTestRender => { const globalKibanaServicesParams = { ...startServices, kibanaVersion: '8.0.0', + kibanaBranch: 'main', }; if (jest.isMockFunction(KibanaServices.get)) { diff --git a/x-pack/plugins/security_solution/public/common/types.ts b/x-pack/plugins/security_solution/public/common/types.ts index 8eced134242550..c639975e499a0b 100644 --- a/x-pack/plugins/security_solution/public/common/types.ts +++ b/x-pack/plugins/security_solution/public/common/types.ts @@ -18,6 +18,7 @@ export interface ServerApiError { export interface SecuritySolutionUiConfigType { enableExperimental: string[]; + prebuiltRulesPackageVersion?: string; } /** diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alert_donut_embeddable.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alert_donut_embeddable.tsx deleted file mode 100644 index 029bffdd8bc2bd..00000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alert_donut_embeddable.tsx +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useCallback, useEffect, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; -import { DonutChartWrapper } from '../../../../common/components/charts/donutchart'; -import { useRefetchByRestartingSession } from '../../../../common/components/page/use_refetch_by_session'; -import { getAlertsByStatusAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut'; -import { LensEmbeddable } from '../../../../common/components/visualization_actions/lens_embeddable'; -import type { EmbeddableData } from '../../../../common/components/visualization_actions/types'; -import { parseVisualizationData } from '../../../../common/components/visualization_actions/utils'; -import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import { inputsActions, inputsSelectors } from '../../../../common/store/inputs'; -import { InputsModelId } from '../../../../common/store/inputs/constants'; -import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; -import { ChartLabel } from './chart_label'; -import type { AlertDonutEmbeddableProps, VisualizationAlertsByStatusResponse } from './types'; -import { DETECTION_RESPONSE_ALERTS_BY_STATUS_ID } from './types'; - -const ChartSize = '135px'; - -const AlertDonutEmbeddableComponent: React.FC = ({ - status, - timerange, - label, -}) => { - const dispatch = useDispatch(); - const queryId = `${DETECTION_RESPONSE_ALERTS_BY_STATUS_ID}-${status}`; - const { session, refetchByRestartingSession } = useRefetchByRestartingSession({ - inputId: InputsModelId.global, - queryId, - }); - const getGlobalQuery = inputsSelectors.globalQueryByIdSelector(); - const { inspect } = useDeepEqualSelector((state) => getGlobalQuery(state, queryId)); - const visualizationData = inspect?.response - ? parseVisualizationData(inspect?.response) - : null; - - const onEmbeddableLoad = useCallback( - ({ requests, responses, isLoading }: EmbeddableData) => { - dispatch( - inputsActions.setQuery({ - inputId: InputsModelId.global, - id: queryId, - searchSessionId: session.current.start(), - refetch: refetchByRestartingSession, - loading: isLoading, - inspect: { dsl: requests, response: responses }, - }) - ); - }, - [dispatch, queryId, refetchByRestartingSession, session] - ); - - const extraOptions = useMemo(() => ({ status }), [status]); - - useEffect(() => { - dispatch( - inputsActions.setQuery({ - inputId: InputsModelId.global, - id: queryId, - searchSessionId: session.current.start(), - refetch: refetchByRestartingSession, - loading: false, - inspect: null, - }) - ); - }, [dispatch, queryId, refetchByRestartingSession, session, status]); - - useEffect(() => { - return () => { - dispatch( - inputsActions.deleteOneQuery({ - inputId: InputsModelId.global, - id: queryId, - }) - ); - }; - }, [dispatch, queryId]); - - const dataExists = visualizationData != null && visualizationData[0].hits.total !== 0; - - return ( - : null} - > - - - ); -}; - -export const AlertDonutEmbeddable = React.memo(AlertDonutEmbeddableComponent); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx index b955e096cc295a..40a9fab612ad69 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx @@ -20,8 +20,7 @@ jest.mock('../../../../common/hooks/use_experimental_features', () => { return { useIsExperimentalFeatureEnabled: jest.fn() }; }); -jest.mock('./alert_donut_embeddable'); - +jest.mock('../../../../common/components/visualization_actions/visualization_embeddable'); jest.mock('./chart_label', () => { return { ChartLabel: jest.fn((props) => ), @@ -173,7 +172,7 @@ describe('AlertsByStatus', () => { ); expect( - container.querySelector(`[data-test-subj="alert-donut-embeddable"]`) + container.querySelector(`[data-test-subj="visualization-embeddable"]`) ).toBeInTheDocument(); expect((useAlertsByStatus as jest.Mock).mock.calls[0][0].skip).toBeTruthy(); }); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx index 1032dd2d4e95c4..a23bfa31c9d105 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx @@ -55,9 +55,12 @@ import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/ import { useNavigateToTimeline } from '../hooks/use_navigate_to_timeline'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { AlertDonutEmbeddable } from './alert_donut_embeddable'; import { useAlertsByStatusVisualizationData } from './use_alerts_by_status_visualization_data'; import { DETECTION_RESPONSE_ALERTS_BY_STATUS_ID } from './types'; +import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; +import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; +import type { Status } from '../../../../../common/detection_engine/schemas/common'; +import { getAlertsByStatusAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut'; const StyledFlexItem = styled(EuiFlexItem)` padding: 0 4px; @@ -68,6 +71,8 @@ const StyledLegendFlexItem = styled(EuiFlexItem)` padding-top: 45px; `; +const ChartSize = '135px'; + interface AlertsByStatusProps { additionalFilters?: ESBoolQuery[]; entityFilter?: EntityFilter; @@ -87,6 +92,10 @@ const eventKindSignalFilter: EntityFilter = { value: 'signal', }; +const openDonutOptions = { status: 'open' as Status }; +const acknowledgedDonutOptions = { status: 'acknowledged' as Status }; +const closedDonutOptions = { status: 'closed' as Status }; + export const AlertsByStatus = ({ additionalFilters, signalIndexName, @@ -193,9 +202,9 @@ export const AlertsByStatus = ({ <> - {totalAlerts !== 0 || - (visualizationTotalAlerts !== 0 && ( - + + {totalAlerts !== 0 || + (visualizationTotalAlerts !== 0 && ( <> @@ -203,16 +212,25 @@ export const AlertsByStatus = ({ <> {ALERTS(totalAlertsCount)} - - ))} + ))} + + {isChartEmbeddablesEnabled ? ( - ) : ( {isChartEmbeddablesEnabled ? ( - ) : ( {isChartEmbeddablesEnabled ? ( - ) : ( + {legendItems.length > 0 && } diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/__mocks__/index.ts b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/__mocks__/index.ts new file mode 100644 index 00000000000000..bf863d0011ad38 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/__mocks__/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RiskSeverity } from '../../../../../../common/search_strategy/security_solution'; + +export const mockSeverityCount = { + [RiskSeverity.unknown]: 1, + [RiskSeverity.low]: 2, + [RiskSeverity.moderate]: 3, + [RiskSeverity.high]: 4, + [RiskSeverity.critical]: 5, +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.test.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.test.tsx new file mode 100644 index 00000000000000..cd2183cc9611fb --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.test.tsx @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { render } from '@testing-library/react'; +import React from 'react'; +import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { useSpaceId } from '../../../../common/hooks/use_space_id'; +import { TestProviders } from '../../../../common/mock'; +import { ChartContent } from './chart_content'; +import { mockSeverityCount } from './__mocks__'; + +jest.mock('../../../../common/components/visualization_actions/visualization_embeddable'); +jest.mock('../../../../common/hooks/use_experimental_features', () => ({ + useIsExperimentalFeatureEnabled: jest.fn(), +})); +jest.mock('../../../../common/hooks/use_space_id', () => ({ + useSpaceId: jest.fn(), +})); +describe('ChartContent', () => { + beforeEach(() => { + jest.clearAllMocks(); + (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false); + (useSpaceId as jest.Mock).mockReturnValue('default'); + }); + it('renders VisualizationEmbeddable when isChartEmbeddablesEnabled = true and dataExists = true', () => { + (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true); + + const { getByTestId } = render( + + ); + + expect(getByTestId('visualization-embeddable')).toBeInTheDocument(); + }); + + it('should not render VisualizationEmbeddable when dataExists = false', () => { + (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true); + + const { queryByTestId } = render( + + + + ); + + expect(queryByTestId('visualization-embeddable')).not.toBeInTheDocument(); + }); + + it('should not render VisualizationEmbeddable when spaceId = undefined', () => { + (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true); + (useSpaceId as jest.Mock).mockReturnValue(undefined); + const { queryByTestId } = render( + + + + ); + + expect(queryByTestId('visualization-embeddable')).not.toBeInTheDocument(); + }); + + it('renders RiskScoreDonutChart when isChartEmbeddablesEnabled = false', () => { + const { getByTestId } = render( + + + + ); + + expect(getByTestId('risk-score-donut-chart')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.tsx new file mode 100644 index 00000000000000..40acfe37f59a7e --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import type { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { EMPTY_SEVERITY_COUNT } from '../../../../../common/search_strategy'; +import { getRiskScoreDonutAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut'; +import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; +import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { useSpaceId } from '../../../../common/hooks/use_space_id'; +import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; +import { RiskScoreDonutChart } from '../common/risk_score_donut_chart'; +import { TOTAL_LABEL } from '../common/translations'; + +const ChartContentComponent = ({ + dataExists, + kpiQueryId, + riskEntity, + severityCount, + timerange, +}: { + dataExists?: boolean; + kpiQueryId: string; + riskEntity: RiskScoreEntity; + severityCount: SeverityCount | undefined; + timerange: { + from: string; + to: string; + }; +}) => { + const isChartEmbeddablesEnabled = useIsExperimentalFeatureEnabled('chartEmbeddablesEnabled'); + const spaceId = useSpaceId(); + const extraOptions = useMemo(() => ({ spaceId }), [spaceId]); + + return ( + <> + {isChartEmbeddablesEnabled && spaceId && dataExists && ( + + )} + {!isChartEmbeddablesEnabled && ( + + )} + + ); +}; + +export const ChartContent = React.memo(ChartContentComponent); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.test.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.test.tsx new file mode 100644 index 00000000000000..262bf4792288fe --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.test.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { RenderResult } from '@testing-library/react'; +import { render } from '@testing-library/react'; +import React from 'react'; +import { SecurityPageName } from '../../../../../common/constants'; +import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; +import { RiskScoreHeaderContent } from './header_content'; +import { mockSeverityCount } from './__mocks__'; + +jest.mock('../../../../common/components/links', () => { + const actual = jest.requireActual('../../../../common/components/links'); + return { + ...actual, + useGetSecuritySolutionLinkProps: jest.fn(), + }; +}); +const mockGetSecuritySolutionLinkProps = jest + .fn() + .mockReturnValue({ onClick: jest.fn(), href: '' }); + +describe('RiskScoreHeaderContent', () => { + let res: RenderResult; + jest.clearAllMocks(); + + (useGetSecuritySolutionLinkProps as jest.Mock).mockReturnValue(mockGetSecuritySolutionLinkProps); + beforeEach(() => { + res = render( + + ); + }); + it('should render when toggleStatus = true', () => { + expect(res.getByTestId(`user-risk-score-header-content`)).toBeInTheDocument(); + }); + + it('should render learn more button', () => { + expect(res.getByText(`Learn more`)).toBeInTheDocument(); + }); + + it('should render severity filter group', () => { + expect(res.getByTestId(`risk-filter-button`)).toBeInTheDocument(); + }); + + it('should render view all button', () => { + expect(res.getByTestId(`view-all-button`)).toBeInTheDocument(); + }); + + it('should not render if toggleStatus = false', () => { + res = render( + + ); + expect(res.getByTestId(`view-all-button`)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.tsx new file mode 100644 index 00000000000000..3ddd737486a2f5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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, { useMemo } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui'; +import type { RiskSeverity, RiskScoreEntity } from '../../../../../common/search_strategy'; +import { SeverityFilterGroup } from '../../../../explore/components/risk_score/severity/severity_filter_group'; +import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; +import { EMPTY_SEVERITY_COUNT } from '../../../../../common/search_strategy'; +import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; +import type { SecurityPageName } from '../../../../../common/constants'; +import * as i18n from './translations'; + +const RiskScoreHeaderContentComponent = ({ + entityDocLink, + entityLinkProps, + onSelectSeverityFilterGroup, + riskEntity, + selectedSeverity, + severityCount, + toggleStatus, +}: { + entityDocLink: string; + entityLinkProps: { + deepLinkId: SecurityPageName; + path: string; + onClick: () => void; + }; + onSelectSeverityFilterGroup: (newSelection: RiskSeverity[]) => void; + riskEntity: RiskScoreEntity; + selectedSeverity: RiskSeverity[]; + severityCount: SeverityCount | undefined; + toggleStatus: boolean; +}) => { + const getSecuritySolutionLinkProps = useGetSecuritySolutionLinkProps(); + + const [goToEntityRiskTab, entityRiskTabUrl] = useMemo(() => { + const { onClick, href } = getSecuritySolutionLinkProps(entityLinkProps); + return [onClick, href]; + }, [entityLinkProps, getSecuritySolutionLinkProps]); + return toggleStatus ? ( + + + + {i18n.LEARN_MORE} + + + + + + + + {i18n.VIEW_ALL} + + + + ) : null; +}; + +export const RiskScoreHeaderContent = React.memo(RiskScoreHeaderContentComponent); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx index a8bf0cd70be8eb..9f6e0180834592 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx @@ -5,93 +5,40 @@ * 2.0. */ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { useDispatch } from 'react-redux'; import { EnableRiskScore } from '../../../../explore/components/risk_score/enable_risk_score'; -import { getTabsOnUsersUrl } from '../../../../common/components/link_to/redirect_to_users'; -import { UsersTableType } from '../../../../explore/users/store/model'; -import { SeverityFilterGroup } from '../../../../explore/components/risk_score/severity/severity_filter_group'; -import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; -import { getTabsOnHostsUrl } from '../../../../common/components/link_to/redirect_to_hosts'; -import { HostsTableType, HostsType } from '../../../../explore/hosts/store/model'; import { getRiskScoreColumns } from './columns'; import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { HeaderSection } from '../../../../common/components/header_section'; import { useRiskScore, useRiskScoreKpi } from '../../../../explore/containers/risk_score'; import type { RiskSeverity } from '../../../../../common/search_strategy'; -import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../../../common/search_strategy'; -import { SecurityPageName } from '../../../../app/types'; -import * as i18n from './translations'; +import { RiskScoreEntity } from '../../../../../common/search_strategy'; import { generateSeverityFilter } from '../../../../explore/hosts/store/helpers'; import { useQueryInspector } from '../../../../common/components/page/manage_query'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { InspectButtonContainer } from '../../../../common/components/inspect'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { hostsActions } from '../../../../explore/hosts/store'; -import { RiskScoreDonutChart } from '../common/risk_score_donut_chart'; import { StyledBasicTable } from '../common/styled_basic_table'; -import { RISKY_HOSTS_DOC_LINK, RISKY_USERS_DOC_LINK } from '../../../../../common/constants'; import { RiskScoreHeaderTitle } from '../../../../explore/components/risk_score/risk_score_onboarding/risk_score_header_title'; import { RiskScoresNoDataDetected } from '../../../../explore/components/risk_score/risk_score_onboarding/risk_score_no_data_detected'; import { useRefetchQueries } from '../../../../common/hooks/use_refetch_queries'; import { Loader } from '../../../../common/components/loader'; import { Panel } from '../../../../common/components/panel'; import * as commonI18n from '../common/translations'; -import { usersActions } from '../../../../explore/users/store'; import { useNavigateToTimeline } from '../../detection_response/hooks/use_navigate_to_timeline'; import type { TimeRange } from '../../../../common/store/inputs/model'; import { openAlertsFilter } from '../../detection_response/utils'; -const HOST_RISK_TABLE_QUERY_ID = 'hostRiskDashboardTable'; -const HOST_RISK_KPI_QUERY_ID = 'headerHostRiskScoreKpiQuery'; -const USER_RISK_TABLE_QUERY_ID = 'userRiskDashboardTable'; -const USER_RISK_KPI_QUERY_ID = 'headerUserRiskScoreKpiQuery'; +import { useEntityInfo } from './use_entity'; +import { RiskScoreHeaderContent } from './header_content'; +import { ChartContent } from './chart_content'; const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskScoreEntity }) => { const { deleteQuery, setQuery, from, to } = useGlobalTime(); const [updatedAt, setUpdatedAt] = useState(Date.now()); - const dispatch = useDispatch(); - - const entity = useMemo( - () => - riskEntity === RiskScoreEntity.host - ? { - docLink: RISKY_HOSTS_DOC_LINK, - linkProps: { - deepLinkId: SecurityPageName.hosts, - path: getTabsOnHostsUrl(HostsTableType.risk), - onClick: () => { - dispatch( - hostsActions.updateHostRiskScoreSeverityFilter({ - severitySelection: [], - hostsType: HostsType.page, - }) - ); - }, - }, - tableQueryId: HOST_RISK_TABLE_QUERY_ID, - kpiQueryId: HOST_RISK_KPI_QUERY_ID, - } - : { - docLink: RISKY_USERS_DOC_LINK, - linkProps: { - deepLinkId: SecurityPageName.users, - path: getTabsOnUsersUrl(UsersTableType.risk), - onClick: () => { - dispatch( - usersActions.updateUserRiskScoreSeverityFilter({ - severitySelection: [], - }) - ); - }, - }, - tableQueryId: USER_RISK_TABLE_QUERY_ID, - kpiQueryId: USER_RISK_KPI_QUERY_ID, - }, - [dispatch, riskEntity] - ); + const entity = useEntityInfo(riskEntity); const { openTimelineWithFilters } = useNavigateToTimeline(); @@ -122,7 +69,10 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc [riskEntity, openEntityInTimeline] ); const [selectedSeverity, setSelectedSeverity] = useState([]); - const getSecuritySolutionLinkProps = useGetSecuritySolutionLinkProps(); + + const onSelectSeverityFilterGroup = useCallback((newSelection: RiskSeverity[]) => { + setSelectedSeverity(newSelection); + }, []); const severityFilter = useMemo(() => { const [filter] = generateSeverityFilter(selectedSeverity, riskEntity); @@ -191,11 +141,6 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc setUpdatedAt(Date.now()); }, [isTableLoading, isKpiLoading]); // Update the time when data loads - const [goToEntityRiskTab, entityRiskTabUrl] = useMemo(() => { - const { onClick, href } = getSecuritySolutionLinkProps(entity.linkProps); - return [onClick, href]; - }, [entity.linkProps, getSecuritySolutionLinkProps]); - const refreshPage = useRefetchQueries(); if (!isLicenseValid) { @@ -236,41 +181,26 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc toggleQuery={setToggleStatus} tooltip={commonI18n.HOST_RISK_TABLE_TOOLTIP} > - {toggleStatus && ( - - - - {i18n.LEARN_MORE} - - - - - - - - {i18n.VIEW_ALL} - - - - )} + {toggleStatus && ( - + 0} + kpiQueryId={entity.kpiQueryId} + riskEntity={riskEntity} + severityCount={severityCount} + timerange={timerange} + /> { + const actual = jest.requireActual('react-redux'); + return { + ...actual, + useDispatch: jest.fn(), + }; +}); + +describe('useEntityInfo', () => { + it('should return host entity info', () => { + const { result } = renderHook(() => useEntityInfo(RiskScoreEntity.host)); + expect(result?.current).toMatchInlineSnapshot(` + Object { + "docLink": "https://www.elastic.co/guide/en/security/current/host-risk-score.html", + "kpiQueryId": "headerHostRiskScoreKpiQuery", + "linkProps": Object { + "deepLinkId": "hosts", + "onClick": [Function], + "path": "/hostRisk", + }, + "tableQueryId": "hostRiskDashboardTable", + } + `); + }); + it('should return user entity info', () => { + const { result } = renderHook(() => useEntityInfo(RiskScoreEntity.user)); + expect(result?.current).toMatchInlineSnapshot(` + Object { + "docLink": "https://www.elastic.co/guide/en/security/current/user-risk-score.html", + "kpiQueryId": "headerUserRiskScoreKpiQuery", + "linkProps": Object { + "deepLinkId": "users", + "onClick": [Function], + "path": "/userRisk", + }, + "tableQueryId": "userRiskDashboardTable", + } + `); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.ts b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.ts new file mode 100644 index 00000000000000..10494a1d679f1d --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useDispatch } from 'react-redux'; +import { getTabsOnUsersUrl } from '../../../../common/components/link_to/redirect_to_users'; +import { UsersTableType } from '../../../../explore/users/store/model'; + +import { getTabsOnHostsUrl } from '../../../../common/components/link_to/redirect_to_hosts'; +import { HostsTableType, HostsType } from '../../../../explore/hosts/store/model'; + +import { RiskScoreEntity } from '../../../../../common/search_strategy/security_solution/risk_score'; +import { usersActions } from '../../../../explore/users/store'; +import { RISKY_HOSTS_DOC_LINK, RISKY_USERS_DOC_LINK } from '../../../../../common/constants'; +import { hostsActions } from '../../../../explore/hosts/store'; +import { SecurityPageName } from '../../../../app/types'; + +const HOST_RISK_TABLE_QUERY_ID = 'hostRiskDashboardTable'; +const HOST_RISK_KPI_QUERY_ID = 'headerHostRiskScoreKpiQuery'; +const USER_RISK_TABLE_QUERY_ID = 'userRiskDashboardTable'; +const USER_RISK_KPI_QUERY_ID = 'headerUserRiskScoreKpiQuery'; + +export const useEntityInfo = (riskEntity: RiskScoreEntity) => { + const dispatch = useDispatch(); + + return riskEntity === RiskScoreEntity.host + ? { + docLink: RISKY_HOSTS_DOC_LINK, + linkProps: { + deepLinkId: SecurityPageName.hosts, + path: getTabsOnHostsUrl(HostsTableType.risk), + onClick: () => { + dispatch( + hostsActions.updateHostRiskScoreSeverityFilter({ + severitySelection: [], + hostsType: HostsType.page, + }) + ); + }, + }, + tableQueryId: HOST_RISK_TABLE_QUERY_ID, + kpiQueryId: HOST_RISK_KPI_QUERY_ID, + } + : { + docLink: RISKY_USERS_DOC_LINK, + linkProps: { + deepLinkId: SecurityPageName.users, + path: getTabsOnUsersUrl(UsersTableType.risk), + onClick: () => { + dispatch( + usersActions.updateUserRiskScoreSeverityFilter({ + severitySelection: [], + }) + ); + }, + }, + tableQueryId: USER_RISK_TABLE_QUERY_ID, + kpiQueryId: USER_RISK_KPI_QUERY_ID, + }; +}; diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 3e08672939b5c3..b7b4fcb051d65a 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -61,7 +61,26 @@ import { LazyEndpointCustomAssetsExtension } from './management/pages/policy/vie import type { SecurityAppStore } from './common/store/types'; export class Plugin implements IPlugin { + /** + * The current Kibana branch. e.g. 'main' + */ + readonly kibanaBranch: string; + /** + * The current Kibana version. e.g. '8.0.0' or '8.0.0-SNAPSHOT' + */ readonly kibanaVersion: string; + /** + * For internal use. Specify which version of the Detection Rules fleet package to install + * when upgrading rules. If not provided, the latest compatible package will be installed, + * or if running from a dev environment or -SNAPSHOT build, the latest pre-release package + * will be used (if fleet is available or not within an airgapped environment). + * + * Note: This is for `upgrade only`, which occurs by means of the `useUpgradeSecurityPackages` + * hook when navigating to a Security Solution page. The package version specified in + * `fleet_packages.json` in project root will always be installed first on Kibana start if + * the package is not already installed. + */ + readonly prebuiltRulesPackageVersion?: string; private config: SecuritySolutionUiConfigType; readonly experimentalFeatures: ExperimentalFeatures; @@ -69,6 +88,8 @@ export class Plugin implements IPlugin(); this.experimentalFeatures = parseExperimentalConfigValue(this.config.enableExperimental || []); this.kibanaVersion = initializerContext.env.packageInfo.version; + this.kibanaBranch = initializerContext.env.packageInfo.branch; + this.prebuiltRulesPackageVersion = this.config.prebuiltRulesPackageVersion; } private appUpdater$ = new Subject(); @@ -214,7 +235,13 @@ export class Plugin implements IPlugin { - const { threatIntelligence } = useKibana().services; + const { threatIntelligence, http } = useKibana().services; const ThreatIntelligencePlugin = threatIntelligence.getComponent(); const sourcererDataView = useSourcererDataView(); @@ -44,6 +48,15 @@ const ThreatIntelligence = memo(() => { sourcererDataView: sourcererDataView as unknown as SourcererDataView, getUseInvestigateInTimeline: useInvestigateInTimeline, + blockList: { + exceptionListApiClient: BlocklistsApiClient.getInstance(http), + useSetUrlParams, + // @ts-ignore + getFlyoutComponent: () => ArtifactFlyout, + // @ts-ignore + getFormComponent: () => BlockListForm, + }, + useQuery: () => useSelector(inputsSelectors.globalQuerySelector()), useFilters: () => useSelector(inputsSelectors.globalFiltersQuerySelector()), useGlobalTime, diff --git a/x-pack/plugins/security_solution/server/config.mock.ts b/x-pack/plugins/security_solution/server/config.mock.ts index 45563178dd6ddb..10ea0b588b379c 100644 --- a/x-pack/plugins/security_solution/server/config.mock.ts +++ b/x-pack/plugins/security_solution/server/config.mock.ts @@ -24,6 +24,7 @@ export const createMockConfig = (): ConfigType => { maxTimelineImportPayloadBytes: 10485760, enableExperimental, packagerTaskInterval: '60s', + prebuiltRulesPackageVersion: '', alertMergeStrategy: 'missingFields', alertIgnoreFields: [], diff --git a/x-pack/plugins/security_solution/server/config.ts b/x-pack/plugins/security_solution/server/config.ts index 08683436505e34..5a4d18edda11c4 100644 --- a/x-pack/plugins/security_solution/server/config.ts +++ b/x-pack/plugins/security_solution/server/config.ts @@ -109,6 +109,19 @@ export const configSchema = schema.object({ * Artifacts Configuration */ packagerTaskInterval: schema.string({ defaultValue: '60s' }), + + /** + * For internal use. Specify which version of the Detection Rules fleet package to install + * when upgrading rules. If not provided, the latest compatible package will be installed, + * or if running from a dev environment or -SNAPSHOT build, the latest pre-release package + * will be used (if fleet is available or not within an airgapped environment). + * + * Note: This is for `upgrade only`, which occurs by means of the `useUpgradeSecurityPackages` + * hook when navigating to a Security Solution page. The package version specified in + * `fleet_packages.json` in project root will always be installed first on Kibana start if + * the package is not already installed. + */ + prebuiltRulesPackageVersion: schema.maybe(schema.string()), }); export type ConfigSchema = TypeOf; diff --git a/x-pack/plugins/security_solution/server/index.ts b/x-pack/plugins/security_solution/server/index.ts index e167f62afd1e72..cc59610f211241 100644 --- a/x-pack/plugins/security_solution/server/index.ts +++ b/x-pack/plugins/security_solution/server/index.ts @@ -20,6 +20,7 @@ export const plugin = (context: PluginInitializerContext) => { export const config: PluginConfigDescriptor = { exposeToBrowser: { enableExperimental: true, + prebuiltRulesPackageVersion: true, }, schema: configSchema, deprecations: ({ renameFromRoot, unused }) => [ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts index fd7351c677a2a3..3d3accea3fa241 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts @@ -12,7 +12,7 @@ import { getFindResultWithSingleHit, getPrepackagedRulesStatusRequest, } from '../../../routes/__mocks__/request_responses'; -import { requestContextMock, serverMock, createMockConfig } from '../../../routes/__mocks__'; +import { requestContextMock, serverMock } from '../../../routes/__mocks__'; import type { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { checkTimelinesStatus } from '../../../../timeline/utils/check_timelines_status'; import { @@ -82,7 +82,7 @@ describe('get_prepackaged_rule_status_route', () => { prepackagedTimelines: [], }); - getPrebuiltRulesAndTimelinesStatusRoute(server.router, createMockConfig(), securitySetup); + getPrebuiltRulesAndTimelinesStatusRoute(server.router, securitySetup); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts index c765ed4ab6cc33..ced2a0e8ea663a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts @@ -8,7 +8,6 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; import { buildSiemResponse } from '../../../routes/utils'; -import type { ConfigType } from '../../../../../config'; import type { SetupPlugins } from '../../../../../plugin'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; @@ -22,7 +21,7 @@ import { findRules } from '../../../rule_management/logic/search/find_rules'; import { getLatestPrebuiltRules } from '../../logic/get_latest_prebuilt_rules'; import { getRulesToInstall } from '../../logic/get_rules_to_install'; import { getRulesToUpdate } from '../../logic/get_rules_to_update'; -import { ruleAssetSavedObjectsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; +import { ruleAssetsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; import { rulesToMap } from '../../logic/utils'; import { buildFrameworkRequest } from '../../../../timeline/utils/common'; @@ -33,7 +32,6 @@ import { export const getPrebuiltRulesAndTimelinesStatusRoute = ( router: SecuritySolutionPluginRouter, - config: ConfigType, security: SetupPlugins['security'] ) => { router.get( @@ -49,7 +47,7 @@ export const getPrebuiltRulesAndTimelinesStatusRoute = ( const ctx = await context.resolve(['core', 'alerting']); const savedObjectsClient = ctx.core.savedObjects.client; const rulesClient = ctx.alerting.getRulesClient(); - const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); + const ruleAssetsClient = ruleAssetsClientFactory(savedObjectsClient); try { const latestPrebuiltRules = await getLatestPrebuiltRules(ruleAssetsClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts index 2eca0146dc8a7f..d2aa7216404d24 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts @@ -27,7 +27,7 @@ import { createPrebuiltRules } from '../../logic/create_prebuilt_rules'; import { updatePrebuiltRules } from '../../logic/update_prebuilt_rules'; import { getRulesToInstall } from '../../logic/get_rules_to_install'; import { getRulesToUpdate } from '../../logic/get_rules_to_update'; -import { ruleAssetSavedObjectsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; +import { ruleAssetsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; import { rulesToMap } from '../../logic/utils'; import { installPrepackagedTimelines } from '../../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; @@ -90,7 +90,7 @@ export const createPrepackagedRules = async ( const savedObjectsClient = context.core.savedObjects.client; const siemClient = context.getAppClient(); const exceptionsListClient = context.getExceptionListClient() ?? exceptionsClient; - const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); + const ruleAssetsClient = ruleAssetsClientFactory(savedObjectsClient); const { maxTimelineImportExportSize } = config; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts index 39e822af3e1474..c396eea87da9dd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { ConfigType } from '../../../../config'; import type { SetupPlugins } from '../../../../plugin_contract'; import type { SecuritySolutionPluginRouter } from '../../../../types'; @@ -14,9 +13,8 @@ import { installPrebuiltRulesAndTimelinesRoute } from './install_prebuilt_rules_ export const registerPrebuiltRulesRoutes = ( router: SecuritySolutionPluginRouter, - config: ConfigType, security: SetupPlugins['security'] ) => { - getPrebuiltRulesAndTimelinesStatusRoute(router, config, security); + getPrebuiltRulesAndTimelinesStatusRoute(router, security); installPrebuiltRulesAndTimelinesRoute(router); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts index 914ab6b7ccf7f2..36fb03c9bac7a6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts @@ -13,32 +13,23 @@ import { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/pr import { withSecuritySpan } from '../../../../utils/with_security_span'; import type { IRuleAssetSOAttributes, - RuleAssetSavedObjectsClient, + IRuleAssetsClient, } from './rule_asset/rule_asset_saved_objects_client'; +import { prebuiltRulesToMap } from './utils'; + export const getLatestPrebuiltRules = async ( - client: RuleAssetSavedObjectsClient + ruleAssetsClient: IRuleAssetsClient ): Promise> => withSecuritySpan('getLatestPrebuiltRules', async () => { - const fleetRules = await getFleetRules(client); - return new Map(fleetRules.map((rule) => [rule.rule_id, rule])); + const ruleAssets = await ruleAssetsClient.fetchLatestVersions(); + return prebuiltRulesToMap(validateRuleAssets(ruleAssets)); }); -/** - * Retrieve and validate prebuilt rules that were installed from Fleet as saved objects. - */ -const getFleetRules = async ( - client: RuleAssetSavedObjectsClient -): Promise => { - const fleetResponse = await client.all(); - const fleetRules = fleetResponse.map((so) => so.attributes); - return validateFleetRules(fleetRules); -}; - /** * Validate the rules from Saved Objects created by Fleet. */ -const validateFleetRules = (rules: IRuleAssetSOAttributes[]): PrebuiltRuleToInstall[] => { +const validateRuleAssets = (rules: IRuleAssetSOAttributes[]): PrebuiltRuleToInstall[] => { return rules.map((rule) => { const decoded = PrebuiltRuleToInstall.decode(rule); const checked = exactCheck(rule, decoded); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts index be963fb3dae9e9..556ebbe2df1082 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts @@ -5,17 +5,16 @@ * 2.0. */ -import type { - SavedObjectsClientContract, - SavedObjectsFindOptions, - SavedObjectsFindResponse, -} from '@kbn/core/server'; +import type { AggregationsMultiBucketAggregateBase } from '@elastic/elasticsearch/lib/api/types'; +import type { AggregationsTopHitsAggregate } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { SavedObjectsClientContract } from '@kbn/core/server'; +import { invariant } from '../../../../../../common/utils/invariant'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; import { ruleAssetSavedObjectType } from './rule_asset_saved_object_mappings'; -const DEFAULT_PAGE_SIZE = 100; +const MAX_PREBUILT_RULES_COUNT = 10_000; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export interface IRuleAssetSOAttributes extends Record { +export interface IRuleAssetSOAttributes extends Record { rule_id: string | null | undefined; version: string | null | undefined; name: string | null | undefined; @@ -27,33 +26,53 @@ export interface IRuleAssetSavedObject { attributes: IRuleAssetSOAttributes; } -export interface RuleAssetSavedObjectsClient { - find: ( - options?: Omit - ) => Promise>; - all: () => Promise; +export interface IRuleAssetsClient { + fetchLatestVersions: () => Promise; } -export const ruleAssetSavedObjectsClientFactory = ( +export const ruleAssetsClientFactory = ( savedObjectsClient: SavedObjectsClientContract -): RuleAssetSavedObjectsClient => { +): IRuleAssetsClient => { return { - find: (options) => - savedObjectsClient.find({ - ...options, - type: ruleAssetSavedObjectType, - }), - all: async () => { - const finder = savedObjectsClient.createPointInTimeFinder({ - perPage: DEFAULT_PAGE_SIZE, - type: ruleAssetSavedObjectType, + fetchLatestVersions: () => { + return withSecuritySpan('RuleAssetsClient.fetchLatestVersions', async () => { + const findResult = await savedObjectsClient.find< + IRuleAssetSavedObject, + { + rules: AggregationsMultiBucketAggregateBase<{ + latest_version: AggregationsTopHitsAggregate; + }>; + } + >({ + type: ruleAssetSavedObjectType, + aggs: { + rules: { + terms: { + field: `${ruleAssetSavedObjectType}.attributes.rule_id`, + size: MAX_PREBUILT_RULES_COUNT, + }, + aggs: { + latest_version: { + top_hits: { + size: 1, + sort: { + [`${ruleAssetSavedObjectType}.version`]: 'desc', + }, + }, + }, + }, + }, + }, + }); + const buckets = findResult.aggregations?.rules?.buckets ?? []; + + invariant(Array.isArray(buckets), 'Expected buckets to be an array'); + + return buckets.map((bucket) => { + const hit = bucket.latest_version.hits.hits[0]; + return hit._source[ruleAssetSavedObjectType]; + }); }); - const responses: IRuleAssetSavedObject[] = []; - for await (const response of finder.find()) { - responses.push(...response.saved_objects.map((so) => so as IRuleAssetSavedObject)); - } - await finder.close(); - return responses; }, }; }; diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index 38809aff316a0c..de0a0c4fab69d9 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -91,7 +91,7 @@ export const initRoutes = ( ) => { registerFleetIntegrationsRoutes(router, logger); registerLegacyRuleActionsRoutes(router, logger); - registerPrebuiltRulesRoutes(router, config, security); + registerPrebuiltRulesRoutes(router, security); registerRuleExceptionsRoutes(router); registerManageExceptionsRoutes(router); registerRuleManagementRoutes(router, config, ml, logger); diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/tabs/tab_summary.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/tabs/tab_summary.tsx index 814589275cad17..e1060f8743750a 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/tabs/tab_summary.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/tabs/tab_summary.tsx @@ -146,9 +146,9 @@ export const TabSummary: React.FunctionComponent = ({ policy }) => { - - - + + + = ({ policy }) => { {version} - + + - + + = ({ policy }) => { - - + + + + - - + + + = ({ policy }) => { {snapshotName} - + + - + + = ({ policy }) => { {repository} - - + + + + - - + + + = ({ policy }) => { {schedule} - + + - + + = ({ policy }) => { - - + + + + - - + + + = ({ policy }) => { - + + - + + = ({ policy }) => { /> )} - - + + + + - - + + + = ({ policy }) => { /> )} - + + - - + + + - - + + + = ({ policy }) => { /> )} - - - + + + {retention && ( diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts index f29a84beaecf89..c4b99028701ad7 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts @@ -380,6 +380,29 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse }); }); + it('should return successful ES response when using unknown setting', async () => { + const mockEsResponse = { + [name]: { type: 's3', settings: { awsAccount: 'test-account' } }, + }; + getRepoFn.mockResolvedValue({ [name]: {} }); + createRepoFn.mockResolvedValue(mockEsResponse); + + const expectedResponse = mockEsResponse; + + await expect( + router.runRequest({ + ...mockRequest, + body: { + name, + type: 's3', + settings: { + path_style_access: 'test-account', + }, + }, + }) + ).resolves.toEqual({ body: expectedResponse }); + }); + it('should throw if ES error', async () => { getRepoFn.mockRejectedValue(new Error()); await expect(router.runRequest(mockRequest)).rejects.toThrowError(); diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/validate_schemas.ts b/x-pack/plugins/snapshot_restore/server/routes/api/validate_schemas.ts index 35437c2e39acdd..d312d02a309812 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/validate_schemas.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/validate_schemas.ts @@ -62,14 +62,8 @@ export const policySchema = schema.object({ isManagedPolicy: schema.boolean(), }); -const fsRepositorySettings = schema.object({ - location: schema.string(), - compress: schema.maybe(schema.boolean()), - chunkSize: schema.maybe(schema.oneOf([schema.string(), schema.literal(null)])), - maxRestoreBytesPerSec: schema.maybe(schema.string()), - maxSnapshotBytesPerSec: schema.maybe(schema.string()), - readonly: schema.maybe(schema.boolean()), -}); +// Only validate required settings, everything else is optional +const fsRepositorySettings = schema.object({ location: schema.string() }, { unknowns: 'allow' }); const fsRepositorySchema = schema.object({ name: schema.string(), @@ -87,20 +81,8 @@ const readOnlyRepository = schema.object({ settings: readOnlyRepositorySettings, }); -const s3RepositorySettings = schema.object({ - bucket: schema.string(), - client: schema.maybe(schema.string()), - basePath: schema.maybe(schema.string()), - compress: schema.maybe(schema.boolean()), - chunkSize: schema.maybe(schema.oneOf([schema.string(), schema.literal(null)])), - serverSideEncryption: schema.maybe(schema.boolean()), - bufferSize: schema.maybe(schema.string()), - cannedAcl: schema.maybe(schema.string()), - storageClass: schema.maybe(schema.string()), - maxRestoreBytesPerSec: schema.maybe(schema.string()), - maxSnapshotBytesPerSec: schema.maybe(schema.string()), - readonly: schema.maybe(schema.boolean()), -}); +// Only validate required settings, everything else is optional +const s3RepositorySettings = schema.object({ bucket: schema.string() }, { unknowns: 'allow' }); const s3Repository = schema.object({ name: schema.string(), @@ -108,17 +90,11 @@ const s3Repository = schema.object({ settings: s3RepositorySettings, }); +// Only validate required settings, everything else is optional const hdsRepositorySettings = schema.object( { uri: schema.string(), path: schema.string(), - loadDefaults: schema.maybe(schema.boolean()), - compress: schema.maybe(schema.boolean()), - chunkSize: schema.maybe(schema.oneOf([schema.string(), schema.literal(null)])), - maxRestoreBytesPerSec: schema.maybe(schema.string()), - maxSnapshotBytesPerSec: schema.maybe(schema.string()), - readonly: schema.maybe(schema.boolean()), - ['security.principal']: schema.maybe(schema.string()), }, { unknowns: 'allow' } ); @@ -129,17 +105,7 @@ const hdsfRepository = schema.object({ settings: hdsRepositorySettings, }); -const azureRepositorySettings = schema.object({ - client: schema.maybe(schema.string()), - container: schema.maybe(schema.string()), - basePath: schema.maybe(schema.string()), - locationMode: schema.maybe(schema.string()), - compress: schema.maybe(schema.boolean()), - chunkSize: schema.maybe(schema.oneOf([schema.string(), schema.literal(null)])), - maxRestoreBytesPerSec: schema.maybe(schema.string()), - maxSnapshotBytesPerSec: schema.maybe(schema.string()), - readonly: schema.maybe(schema.boolean()), -}); +const azureRepositorySettings = schema.object({}, { unknowns: 'allow' }); const azureRepository = schema.object({ name: schema.string(), @@ -147,16 +113,8 @@ const azureRepository = schema.object({ settings: azureRepositorySettings, }); -const gcsRepositorySettings = schema.object({ - bucket: schema.string(), - client: schema.maybe(schema.string()), - basePath: schema.maybe(schema.string()), - compress: schema.maybe(schema.boolean()), - chunkSize: schema.maybe(schema.oneOf([schema.string(), schema.literal(null)])), - maxRestoreBytesPerSec: schema.maybe(schema.string()), - maxSnapshotBytesPerSec: schema.maybe(schema.string()), - readonly: schema.maybe(schema.boolean()), -}); +// Only validate required settings, everything else is optional +const gcsRepositorySettings = schema.object({ bucket: schema.string() }, { unknowns: 'allow' }); const gcsRepository = schema.object({ name: schema.string(), diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts index 4ab03837f416b6..199681a13e9683 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts @@ -90,6 +90,7 @@ describe('sendEmailGraphApi', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, @@ -180,6 +181,7 @@ describe('sendEmailGraphApi', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, @@ -269,6 +271,7 @@ describe('sendEmailGraphApi', () => { "maxSockets": Infinity, "maxTotalSockets": Infinity, "options": Object { + "noDelay": true, "path": null, "rejectUnauthorized": true, }, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts index 3731aa6f09dc7b..584a06f4b407af 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.test.ts @@ -15,7 +15,7 @@ describe('api_itom', () => { let externalService: jest.Mocked; const eventParamsWithFormattedDate = { ...itomEventParams, - time_of_event: '2021-10-13, 10:51:44', + time_of_event: '2021-10-13 10:51:44', }; beforeEach(() => { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts index d9479792967b20..c68f1d4419eb18 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/servicenow_itom/api.ts @@ -20,7 +20,7 @@ const formatTimeOfEvent = (timeOfEvent: string | null): string | undefined => { return isValidDate(date) ? // The format is: yyyy-MM-dd HH:mm:ss GMT - date.toLocaleDateString('en-CA', { + date.toLocaleDateString('eo', { year: 'numeric', month: '2-digit', day: '2-digit', diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts index 3df7a1c3267214..06252f2b567036 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts @@ -18,6 +18,8 @@ export const OverviewStatusMetaDataCodec = t.interface({ }); export const OverviewStatusCodec = t.interface({ + allMonitorsCount: t.number, + disabledMonitorsCount: t.number, up: t.number, down: t.number, disabledCount: t.number, diff --git a/x-pack/plugins/synthetics/e2e/journeys/uptime/alerts/status_alert_flyouts_in_alerting_app.ts b/x-pack/plugins/synthetics/e2e/journeys/uptime/alerts/status_alert_flyouts_in_alerting_app.ts index 7fd8355a69a757..325633bba7413c 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/uptime/alerts/status_alert_flyouts_in_alerting_app.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/uptime/alerts/status_alert_flyouts_in_alerting_app.ts @@ -61,8 +61,9 @@ journey('StatusFlyoutInAlertingApp', async ({ page, params }) => { await page.click(byTestId('"xpack.synthetics.alerts.monitorStatus.filterBar"')); - await assertText({ page, text: 'browser' }); - await assertText({ page, text: 'http' }); + await page.waitForSelector(`text=browser`); + await page.waitForSelector(`text=http`); + await retry.tryForTime(30 * 1000, async () => { await page.click('text=browser'); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/location_status_badges.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/location_status_badges.tsx new file mode 100644 index 00000000000000..a61daea24e52c4 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/location_status_badges.tsx @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; +import { + EuiBadge, + EuiFlexGroup, + EuiFlexItem, + EuiHealth, + EuiIcon, + EuiLoadingSpinner, + EuiToolTip, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EXPAND_LOCATIONS_LABEL } from '../../monitors_page/management/monitor_list_table/labels'; +import { LocationsStatus } from '../../../hooks'; +const DEFAULT_DISPLAY_COUNT = 3; + +export const LocationStatusBadges = ({ + loading, + locations, +}: { + locations: LocationsStatus; + loading: boolean; +}) => { + const [toDisplay, setToDisplay] = useState(DEFAULT_DISPLAY_COUNT); + + if (loading && !locations) { + return ; + } + + const locationsToDisplay = locations.slice(0, toDisplay); + + return ( + + {locationsToDisplay.map((loc) => ( + + } + color="hollow" + > + {loc.label} + + + ))} + {locations.length > toDisplay && ( + + + {locations.slice(toDisplay, locations.length).map((loc) => ( + {loc.label} + ))} + + } + > + { + setToDisplay(locations.length); + }} + onClickAriaLabel={EXPAND_LOCATIONS_LABEL} + > + +{locations.length - toDisplay} + + + + )} + {toDisplay > DEFAULT_DISPLAY_COUNT && ( + + + { + setToDisplay(DEFAULT_DISPLAY_COUNT); + }} + onClickAriaLabel={COLLAPSE_LOCATIONS_LABEL} + > + -{locations.length - DEFAULT_DISPLAY_COUNT} + + + + )} + + ); +}; + +const COLLAPSE_LOCATIONS_LABEL = i18n.translate( + 'xpack.synthetics.management.monitorList.locations.collapse', + { + defaultMessage: 'Click to collapse locations', + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx index de663a47cf878b..66d4f99b4bae28 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_details_panel.tsx @@ -7,26 +7,25 @@ import React from 'react'; import { - EuiDescriptionList, - EuiDescriptionListTitle as TitleLabel, - EuiDescriptionListDescription as DescriptionLabel, - EuiBadge, - EuiSpacer, EuiLink, EuiText, + EuiBadge, + EuiSpacer, + EuiDescriptionList, EuiLoadingContent, + EuiDescriptionListTitle, + EuiDescriptionListDescription, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useDispatch } from 'react-redux'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import moment from 'moment'; import { capitalize } from 'lodash'; +import { TagsBadges } from './tag_badges'; +import { useFormatTestRunAt } from '../../../utils/monitor_test_result/test_time_formats'; import { PanelWithTitle } from './panel_with_title'; -import { useKibanaDateFormat } from '../../../../../hooks/use_kibana_date_format'; import { MonitorEnabled } from '../../monitors_page/management/monitor_list_table/monitor_enabled'; import { getMonitorAction } from '../../../state'; import { LocationsStatus } from '../../monitor_details/monitor_summary/locations_status'; -import { MonitorTags } from '../../monitor_details/monitor_summary/monitor_tags'; import { ConfigKey, EncryptedSyntheticsSavedMonitor, @@ -34,6 +33,14 @@ import { Ping, } from '../../../../../../common/runtime_types'; +const TitleLabel = euiStyled(EuiDescriptionListTitle)` + width: 40%; +`; + +const DescriptionLabel = euiStyled(EuiDescriptionListDescription)` + width: 60%; +`; + export const MonitorDetailsPanel = ({ monitor, latestPing, @@ -116,12 +123,12 @@ export const MonitorDetailsPanel = ({ {frequencyStr(monitor[ConfigKey.SCHEDULE])} {LOCATIONS_LABEL} - + {TAGS_LABEL} - + @@ -183,9 +190,9 @@ function translateUnitMessage(unitMsg: string) { } const Time = ({ timestamp }: { timestamp?: string }) => { - const formatStr = useKibanaDateFormat(); + const dateTimeFormatted = useFormatTestRunAt(timestamp); - return timestamp ? : null; + return timestamp ? : null; }; export const WrapperStyle = euiStyled.div` diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_location_select.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_location_select.tsx index dc87881eb7ab28..9e2d864e720b09 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_location_select.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_location_select.tsx @@ -15,14 +15,12 @@ import { EuiPopover, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useTheme } from '@kbn/observability-plugin/public'; import React, { useMemo, useState, useCallback } from 'react'; import { EncryptedSyntheticsSavedMonitor, ServiceLocation, } from '../../../../../../common/runtime_types'; -import { useLocations } from '../../../hooks'; import { useStatusByLocation } from '../../../hooks'; export const MonitorLocationSelect = ({ @@ -40,11 +38,10 @@ export const MonitorLocationSelect = ({ selectedLocation?: ServiceLocation | null; monitorLocations?: EncryptedSyntheticsSavedMonitor['locations']; }) => { - const { locations } = useLocations(); - const theme = useTheme(); - - const { locations: locationsStatus, loading: loadingLocationsStatus } = - useStatusByLocation(configId); + const { locations: locationsStatus, loading: loadingLocationsStatus } = useStatusByLocation({ + configId, + monitorLocations, + }); const [isLocationListOpen, setIsLocationListOpen] = useState(false); const openLocationList = useCallback(() => setIsLocationListOpen(true), []); @@ -65,34 +62,18 @@ export const MonitorLocationSelect = ({ const menuItems = loadingLocationsStatus && !locationsStatus ? [Loading...] - : monitorLocations + : locationsStatus .map((location) => { - const fullLocation = locations.find((l) => l.id === location.id); - if (!fullLocation) { - return; - } - - const locationStatus = locationsStatus.find( - (ls) => ls.observer?.geo?.name === fullLocation.label - ); - - const locationHealthColor = - typeof locationStatus === 'undefined' - ? 'subdued' - : (locationStatus?.summary?.down ?? 0) > 0 - ? theme.eui.euiColorVis9 // down - : theme.eui.euiColorVis0; // up - return ( } + icon={} onClick={() => { closeLocationList(); - onChange(fullLocation.id, fullLocation.label); + onChange(location.id, location.label); }} > - {fullLocation.label} + {location.label} ); }) @@ -123,14 +104,11 @@ export const MonitorLocationSelect = ({ isDisabled, isLocationListOpen, loadingLocationsStatus, - locations, locationsStatus, monitorLocations, onChange, openLocationList, selectedLocation, - theme.eui.euiColorVis0, - theme.eui.euiColorVis9, ]); if (!selectedLocation || !monitorLocations) { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx index 271f748c471abf..c82a2e6141bfea 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/components/monitor_status.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React from 'react'; -import { EuiBadge, EuiDescriptionList, EuiLoadingSpinner } from '@elastic/eui'; +import { EuiBadge, EuiDescriptionList, EuiLoadingContent } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { EncryptedSyntheticsMonitor } from '../../../../../../common/runtime_types'; @@ -22,21 +22,22 @@ export const MonitorStatus = ({ }) => { const isBrowserType = monitor.type === 'browser'; - const badge = loading ? ( - - ) : !status ? ( - - {PENDING_LABEL} - - ) : status === 'up' ? ( - - {isBrowserType ? SUCCESS_LABEL : UP_LABEL} - - ) : ( - - {isBrowserType ? FAILED_LABEL : DOWN_LABEL} - - ); + const badge = + loading && !monitor ? ( + + ) : !status || status === 'unknown' ? ( + + {PENDING_LABEL} + + ) : status === 'up' ? ( + + {isBrowserType ? SUCCESS_LABEL : UP_LABEL} + + ) : ( + + {isBrowserType ? FAILED_LABEL : DOWN_LABEL} + + ); return ( { const tagsToDisplay = tags.slice(0, toDisplay); return ( - + {tagsToDisplay.map((tag) => ( // filtering only makes sense in monitor list, where we have summary - - { - onClick?.(tag); - }} - onClickAriaLabel={getFilterLabel(tag)} - color="hollow" - className="eui-textTruncate" - style={{ maxWidth: 120 }} - > - {tag} - + + {onClick ? ( + { + onClick(tag); + }} + onClickAriaLabel={getFilterLabel(tag)} + color="hollow" + className="eui-textTruncate" + style={{ maxWidth: 120 }} + > + {tag} + + ) : ( + + {tag} + + )} + ))} {tags.length > toDisplay && ( - { - setToDisplay(tags.length); - }} - onClickAriaLabel={EXPAND_TAGS_LABEL} - > - +{tags.length - toDisplay} - + + + {tags.slice(toDisplay, tags.length).map((tag) => ( + {tag} + ))} + + } + > + { + setToDisplay(tags.length); + }} + onClickAriaLabel={EXPAND_TAGS_LABEL} + > + +{tags.length - toDisplay} + + + )} - {tags.length === toDisplay && ( - { - setToDisplay(3); - }} - onClickAriaLabel={COLLAPSE_TAGS_LABEL} - > - -{tags.length - 3} - + {toDisplay > 3 && ( + + + { + setToDisplay(3); + }} + onClickAriaLabel={COLLAPSE_TAGS_LABEL} + > + -{tags.length - 3} + + + )} - + ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/edit_monitor.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/edit_monitor.tsx new file mode 100644 index 00000000000000..3573d2cffa1332 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/edit_monitor.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButton } from '@elastic/eui'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { useParams } from 'react-router-dom'; +import { useSyntheticsSettingsContext } from '../../../contexts'; + +export const EditMonitorLink = () => { + const { basePath } = useSyntheticsSettingsContext(); + + const { monitorId } = useParams<{ monitorId: string }>(); + + return ( + + {EDIT_MONITOR} + + ); +}; + +const EDIT_MONITOR = i18n.translate('xpack.synthetics.monitorSummary.editMonitor', { + defaultMessage: 'Edit monitor', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.tsx index 28efeeaf4946f1..0527b6ad8c67a9 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.tsx @@ -39,7 +39,9 @@ export const JourneyStepScreenshotContainer = ({ const { basePath } = useContext(SyntheticsSettingsContext); - const imgPath = `${basePath}/internal/uptime/journey/screenshot/${checkGroup}/${initialStepNumber}`; + const imgPath = checkGroup + ? `${basePath}/internal/uptime/journey/screenshot/${checkGroup}/${initialStepNumber}` + : ''; const intersection = useIntersection(intersectionRef, { root: null, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/run_test_btn.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/run_test_btn.tsx index 36a46b63b58a57..17c8fd1f3fef0a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/run_test_btn.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/run_test_btn.tsx @@ -118,9 +118,12 @@ const TEST_NOW_DESCRIPTION = i18n.translate('xpack.synthetics.testRun.descriptio defaultMessage: 'Test your monitor and verify the results before saving', }); -const TEST_SCHEDULED_LABEL = i18n.translate('xpack.synthetics.monitorList.testNow.scheduled', { - defaultMessage: 'Test is already scheduled', -}); +export const TEST_SCHEDULED_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.testNow.scheduled', + { + defaultMessage: 'Test is already scheduled', + } +); const PRIVATE_AVAILABLE_LABEL = i18n.translate( 'xpack.synthetics.monitorList.testNow.available.private', @@ -129,9 +132,12 @@ const PRIVATE_AVAILABLE_LABEL = i18n.translate( } ); -const TEST_NOW_ARIA_LABEL = i18n.translate('xpack.synthetics.monitorList.testNow.AriaLabel', { - defaultMessage: 'Click to run test now', -}); +export const TEST_NOW_ARIA_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.testNow.AriaLabel', + { + defaultMessage: 'Click to run test now', + } +); const RUN_TEST = i18n.translate('xpack.synthetics.monitorList.runTest.label', { defaultMessage: 'Run test', diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx index a5f6d38b2a4a46..75d6b623e34e0c 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx @@ -29,7 +29,9 @@ export const useJourneySteps = (checkGroup?: string, lastRefresh?: number) => { const dispatch = useDispatch(); useEffect(() => { - dispatch(fetchJourneyAction.get({ checkGroup: checkGroupId })); + if (checkGroupId) { + dispatch(fetchJourneyAction.get({ checkGroup: checkGroupId })); + } }, [checkGroupId, dispatch, lastRefresh]); const isFailed = @@ -43,7 +45,7 @@ export const useJourneySteps = (checkGroup?: string, lastRefresh?: number) => { const stepLabels = stepEnds.map((stepEnd) => stepEnd?.synthetics?.step?.name ?? ''); const currentStep = stepIndex - ? journeyData?.steps.find((step) => step.synthetics?.step?.index === Number(stepIndex)) + ? stepEnds.find((step) => step.synthetics?.step?.index === Number(stepIndex)) : undefined; return { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_last_run.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_last_run.tsx index 891421e1158d3b..311f1b49b8e798 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_last_run.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_last_run.tsx @@ -4,30 +4,23 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { ReactElement } from 'react'; import moment from 'moment'; -import { EuiDescriptionList, EuiLoadingSpinner } from '@elastic/eui'; +import { EuiDescriptionList, EuiLoadingContent } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useSelectedMonitor } from './hooks/use_selected_monitor'; import { useMonitorLatestPing } from './hooks/use_monitor_latest_ping'; export const MonitorDetailsLastRun: React.FC = () => { - const { monitor } = useSelectedMonitor(); const { latestPing, loading: pingsLoading } = useMonitorLatestPing(); + let description: string | ReactElement = latestPing + ? moment(latestPing.timestamp).fromNow() + : '--'; - if (!monitor) { - return null; + if (!latestPing && pingsLoading) { + description = ; } - const description = pingsLoading ? ( - - ) : latestPing ? ( - moment(latestPing.timestamp).fromNow() - ) : ( - '--' - ); - return ; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx index 51d50d1621e28d..5834e0cd1039c3 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/locations_status.tsx @@ -5,36 +5,18 @@ * 2.0. */ import React from 'react'; -import { EuiBadge, EuiBadgeGroup, EuiIcon, EuiLoadingSpinner } from '@elastic/eui'; -import { useTheme } from '@kbn/observability-plugin/public'; +import { LocationStatusBadges } from '../../common/components/location_status_badges'; +import { EncryptedSyntheticsSavedMonitor } from '../../../../../../common/runtime_types'; import { useStatusByLocation } from '../../../hooks/use_status_by_location'; -export const LocationsStatus = ({ configId }: { configId?: string }) => { - const { locations, loading } = useStatusByLocation(configId); +export const LocationsStatus = ({ + configId, + monitorLocations, +}: { + configId: string; + monitorLocations?: EncryptedSyntheticsSavedMonitor['locations']; +}) => { + const { locations, loading } = useStatusByLocation({ configId, monitorLocations }); - const theme = useTheme(); - - if (loading && !locations) { - return ; - } - - return ( - - {locations.map((loc) => ( - ( - 0 ? theme.eui.euiColorVis9 : theme.eui.euiColorVis0} - /> - )} - color="hollow" - > - {loc.observer?.geo?.name} - - ))} - - ); + return ; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx index 82fb8a2fb3cf6f..94de32f1ac4cc7 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx @@ -58,19 +58,19 @@ export const MonitorSummary = () => { - + - + - + {monitorId && } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_tags.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_tags.tsx deleted file mode 100644 index 7960d5efbc1e77..00000000000000 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_tags.tsx +++ /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 React from 'react'; -import { EuiBadge, EuiBadgeGroup } from '@elastic/eui'; - -export const MonitorTags = ({ tags }: { tags: string[] }) => { - return ( - - {tags.map((tag) => ( - {tag} - ))} - - ); -}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/run_test_manually.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/run_test_manually.tsx index 475436d6577db2..3c61057ba1f184 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/run_test_manually.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/run_test_manually.tsx @@ -5,15 +5,46 @@ * 2.0. */ -import { EuiButton } from '@elastic/eui'; +import { EuiButton, EuiToolTip } from '@elastic/eui'; import React from 'react'; import { i18n } from '@kbn/i18n'; +import { useDispatch, useSelector } from 'react-redux'; +import { TEST_NOW_ARIA_LABEL, TEST_SCHEDULED_LABEL } from '../monitor_add_edit/form/run_test_btn'; +import { useSelectedMonitor } from './hooks/use_selected_monitor'; +import { + manualTestMonitorAction, + manualTestRunInProgressSelector, +} from '../../state/manual_test_runs'; export const RunTestManually = () => { + const dispatch = useDispatch(); + + const { monitor } = useSelectedMonitor(); + + const hasPublicLocation = () => { + return monitor?.locations.some((loc) => loc.isServiceManaged); + }; + + const testInProgress = useSelector(manualTestRunInProgressSelector(monitor?.config_id)); + + const content = testInProgress ? TEST_SCHEDULED_LABEL : TEST_NOW_ARIA_LABEL; + return ( - - {RUN_TEST_LABEL} - + + { + if (monitor) { + dispatch(manualTestMonitorAction.get(monitor.config_id)); + } + }} + > + {RUN_TEST_LABEL} + + ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts index d6390a080b19bd..73da339d8aeb6a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useSyntheticsRefreshContext } from '../../../contexts/synthetics_refresh_context'; import { @@ -22,18 +22,22 @@ export function useOverviewStatus({ pageState }: { pageState: MonitorOverviewPag const lastRefreshRef = useRef(lastRefresh); const dispatch = useDispatch(); + const reload = useCallback(() => { + dispatch(fetchOverviewStatusAction.get(pageState)); + }, [dispatch, pageState]); useEffect(() => { if (lastRefresh !== lastRefreshRef.current) { dispatch(quietFetchOverviewStatusAction.get(pageState)); lastRefreshRef.current = lastRefresh; } else { - dispatch(fetchOverviewStatusAction.get(pageState)); + reload(); } - }, [dispatch, lastRefresh, pageState]); + }, [dispatch, reload, lastRefresh, pageState]); return { status, statusError, + reload, }; } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/labels.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/labels.ts index dbece4ae959834..d7f3f892c0c76b 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/labels.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/labels.ts @@ -71,3 +71,31 @@ export const BETA_TOOLTIP_MESSAGE = i18n.translate( 'This functionality is in beta and is subject to change. The design and code is less mature than official generally available features and is being provided as-is with no warranties. Beta features are not subject to the support service level agreement of official generally available features.', } ); + +export const SUMMARY_LABEL = i18n.translate('xpack.synthetics.monitorManagement.summary.heading', { + defaultMessage: 'Summary', +}); + +export const CONFIGURATIONS_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.configurations.label', + { + defaultMessage: 'Configurations', + } +); + +export const DISABLED_LABEL = i18n.translate('xpack.synthetics.monitorManagement.disabled.label', { + defaultMessage: 'Disabled', +}); + +export const TEST_RUNS_LABEL = i18n.translate('xpack.synthetics.monitorManagement.testRuns.label', { + defaultMessage: 'Test runs', +}); + +export function getLastXDaysLabel(count: number) { + return i18n.translate('xpack.synthetics.monitorManagement.lastXDays', { + defaultMessage: 'Last {count, number} {count, plural, one {day} other {days}}', + values: { + count, + }, + }); +} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_container.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_container.tsx index 3fe1d5c66de389..8b5f57fe7efdc8 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_container.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_list_container.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React, { useMemo, useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; import type { useMonitorList } from '../hooks/use_monitor_list'; @@ -13,6 +13,7 @@ import { MonitorAsyncError } from './monitor_errors/monitor_async_error'; import { useOverviewStatus } from '../hooks/use_overview_status'; import { ListFilters } from './list_filters/list_filters'; import { MonitorList } from './monitor_list_table/monitor_list'; +import { MonitorStats } from './monitor_stats/monitor_stats'; export const MonitorListContainer = ({ isEnabled, @@ -46,7 +47,11 @@ export const MonitorListContainer = ({ }; }, [pageState]); - const { status } = useOverviewStatus(overviewStatusArgs); + const { status, reload: reloadStatus } = useOverviewStatus(overviewStatusArgs); + + useEffect(() => { + reloadStatus(); + }, [reloadStatus, syntheticsMonitors]); if (!isEnabled && absoluteTotal === 0) { return null; @@ -57,6 +62,8 @@ export const MonitorListContainer = ({ + + { - const { euiTheme } = useEuiTheme(); const theme = useTheme(); const { locations: allLocations } = useLocations(); - const locationLabelsById = useMemo(() => { - return allLocations.reduce((acc, cur) => { - return { ...acc, [cur.id]: cur.label }; - }, {} as Record); - }, [allLocations]); - const [toDisplay, setToDisplay] = useState(INITIAL_LIMIT); - - const locationsToDisplay = locations.slice(0, toDisplay); - return ( - - {locationsToDisplay.map((location: ServiceLocation) => ( - - - {locationLabelsById[location.id]} - - ))} - {locations.length > toDisplay && ( - { - setToDisplay(locations.length); - }} - onClickAriaLabel={EXPAND_LOCATIONS_LABEL} - > - +{locations.length - INITIAL_LIMIT} - - )} - - ); + const locationsToDisplay = locations + .map((loc) => { + const fullLoc = allLocations.find((l) => l.id === loc.id); + if (fullLoc) { + return { + id: fullLoc.id, + label: fullLoc.label, + ...getLocationStatusColor(theme, fullLoc.label, monitorId, status), + }; + } + }) + .filter(Boolean) as LocationsStatus; + + return ; }; function getLocationStatusColor( @@ -88,10 +50,10 @@ function getLocationStatusColor( const locById = `${monitorId}-${locationLabel}`; if (overviewStatus?.downConfigs[locById]) { - return euiColorVis9; + return { status: 'down', color: euiColorVis9 }; } else if (overviewStatus?.upConfigs[locById]) { - return euiColorVis0; + return { status: 'up', color: euiColorVis0 }; } - return euiColorDisabled; + return { status: 'unknown', color: euiColorDisabled }; } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_stats.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_stats.tsx new file mode 100644 index 00000000000000..04e90680eb1c08 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_stats.tsx @@ -0,0 +1,113 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + EuiFlexGroup, + EuiPanel, + EuiStat, + EuiI18nNumber, + useEuiTheme, + EuiText, + EuiFlexItem, + EuiLoadingContent, +} from '@elastic/eui'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; + +import { OverviewStatusState } from '../../../../../../../common/runtime_types'; +import { useSyntheticsRefreshContext } from '../../../../contexts/synthetics_refresh_context'; + +import * as labels from '../labels'; +import { MonitorTestRunsCount } from './monitor_test_runs'; +import { MonitorTestRunsSparkline } from './monitor_test_runs_sparkline'; + +export const MonitorStats = ({ status }: { status: OverviewStatusState | null }) => { + const { euiTheme } = useEuiTheme(); + const { lastRefresh } = useSyntheticsRefreshContext(); + const to = new Date(lastRefresh).toISOString(); + + return ( + <> + + + +
    {labels.SUMMARY_LABEL}
    +
    + + + + + +
    + + + +
    {labels.getLastXDaysLabel(30)}
    +
    + + + + + + + +
    +
    + + ); +}; + +const EuiStatStyled = euiStyled(EuiStat)` + &&& { + color: ${({ theme }) => theme.eui.euiTitleColor}; + .euiStat__title { + color: ${({ theme }) => theme.eui.euiTitleColor}; + font-size: ${({ theme }) => theme.eui.euiFontSizeXL}; + } + } +`; + +const MonitorStat = ({ + description, + value, +}: { + description: string | undefined; + value: number | undefined; +}) => { + const { euiTheme } = useEuiTheme(); + const statValue = (value as number) ?? undefined; + + return ( + + ) : ( + + ) + } + reverse={true} + /> + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_test_runs.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_test_runs.tsx new file mode 100644 index 00000000000000..5a6c3553e82bef --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_test_runs.tsx @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { useTheme } from '@kbn/observability-plugin/public'; +import { ReportTypes } from '@kbn/observability-plugin/public'; + +import { ClientPluginsStart } from '../../../../../../plugin'; +import * as labels from '../labels'; + +interface MonitorCompleteCountProps { + from?: string; + to?: string; +} + +export const MonitorTestRunsCount = ({ + from = 'now-30d', + to = 'now', +}: MonitorCompleteCountProps) => { + const { observability } = useKibana().services; + const theme = useTheme(); + + const { ExploratoryViewEmbeddable } = observability; + + return ( + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_test_runs_sparkline.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_test_runs_sparkline.tsx new file mode 100644 index 00000000000000..9f94ab11965061 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/monitor_stats/monitor_test_runs_sparkline.tsx @@ -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 React from 'react'; + +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { useTheme } from '@kbn/observability-plugin/public'; + +import { ClientPluginsStart } from '../../../../../../plugin'; +import * as labels from '../labels'; + +interface Props { + from?: string; + to?: string; +} +export const MonitorTestRunsSparkline = ({ from = 'now-30d', to = 'now' }: Props) => { + const { observability } = useKibana().services; + + const { ExploratoryViewEmbeddable } = observability; + + const theme = useTheme(); + + return ( + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx index d1ed4ea2b2a806..c35b4b5db6f5a9 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/monitor_detail_flyout.tsx @@ -35,7 +35,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { useTheme } from '@kbn/observability-plugin/public'; import { MonitorDetailsPanel } from '../../../common/components/monitor_details_panel'; import { ClientPluginsStart } from '../../../../../../plugin'; -import { useStatusByLocation } from '../../../../hooks/use_status_by_location'; +import { LocationsStatus, useStatusByLocation } from '../../../../hooks/use_status_by_location'; import { MonitorEnabled } from '../../management/monitor_list_table/monitor_enabled'; import { ActionsPopover } from './actions_popover'; import { @@ -170,14 +170,14 @@ function DetailedFlyoutHeader({ monitor, onEnabledChange, }: { - locations: ReturnType['locations']; + locations: LocationsStatus; currentLocation: string; configId: string; monitor: EncryptedSyntheticsMonitor; onEnabledChange: () => void; setCurrentLocation: (location: string, locationId: string) => void; }) { - const status = locations.find((l) => l.observer?.geo?.name === currentLocation)?.monitor?.status; + const status = locations.find((l) => l.label === currentLocation)?.status; const { locations: allLocations } = useSelector(selectServiceLocationsState); const selectedLocation = allLocations.find((ll) => ll.label === currentLocation); @@ -270,8 +270,10 @@ export function MonitorDetailFlyout(props: Props) { const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false); const monitorDetail = useMonitorDetail(configId, props.location); - const locationStatuses = useStatusByLocation(configId); - const locations = locationStatuses.locations?.filter((l: any) => !!l?.observer?.geo?.name) ?? []; + const { locations } = useStatusByLocation({ + configId, + monitorLocations: monitorSavedObject?.attributes.locations, + }); const isOverlay = useIsWithinMaxBreakpoint('xl'); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/test_now_mode/hooks/use_test_flyout_open.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_now_mode/hooks/use_test_flyout_open.ts index 2a8d8b4035fabf..ed3bf648cfe57a 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/test_now_mode/hooks/use_test_flyout_open.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/test_now_mode/hooks/use_test_flyout_open.ts @@ -8,7 +8,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { useRouteMatch } from 'react-router-dom'; import { useEffect } from 'react'; -import { OVERVIEW_ROUTE } from '../../../../../../common/constants'; +import { MONITOR_ROUTE, OVERVIEW_ROUTE } from '../../../../../../common/constants'; import { hideTestNowFlyoutAction, testNowRunsSelector } from '../../../state/manual_test_runs'; export const useTestFlyoutOpen = () => { @@ -18,14 +18,20 @@ export const useTestFlyoutOpen = () => { path: [OVERVIEW_ROUTE], }); + const isMonitorDetails = useRouteMatch<{ monitorId: string }>({ + path: [MONITOR_ROUTE], + }); + const dispatch = useDispatch(); const flyoutTestOpen = Object.values(testNowRuns).find((value) => { return value.isTestNowFlyoutOpen; }); + const isSameMonitor = flyoutTestOpen?.configId === isMonitorDetails?.params.monitorId; + useEffect(() => { - if (!isOverview?.isExact && flyoutTestOpen) { + if (!isOverview?.isExact && flyoutTestOpen && !isSameMonitor) { dispatch(hideTestNowFlyoutAction()); } }); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_status_by_location.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_status_by_location.tsx index 5271f532a5c7da..296a870b66f426 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_status_by_location.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_status_by_location.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import { useEsSearch } from '@kbn/observability-plugin/public'; -import { useParams } from 'react-router-dom'; +import { useEsSearch, useTheme } from '@kbn/observability-plugin/public'; import { useMemo } from 'react'; -import { Ping } from '../../../../common/runtime_types'; +import { useLocations } from './use_locations'; +import { EncryptedSyntheticsSavedMonitor, Ping } from '../../../../common/runtime_types'; import { EXCLUDE_RUN_ONCE_FILTER, SUMMARY_FILTER, @@ -16,10 +16,20 @@ import { import { SYNTHETICS_INDEX_PATTERN, UNNAMED_LOCATION } from '../../../../common/constants'; import { useSyntheticsRefreshContext } from '../contexts'; -export function useStatusByLocation(monitorIdArg?: string) { +export type LocationsStatus = Array<{ status: string; id: string; label: string; color: string }>; + +export function useStatusByLocation({ + configId, + monitorLocations, +}: { + configId: string; + monitorLocations?: EncryptedSyntheticsSavedMonitor['locations']; +}) { + const theme = useTheme(); + const { lastRefresh } = useSyntheticsRefreshContext(); - const { monitorId } = useParams<{ monitorId: string }>(); + const { locations: allLocations } = useLocations(); const { data, loading } = useEsSearch( { @@ -33,7 +43,7 @@ export function useStatusByLocation(monitorIdArg?: string) { EXCLUDE_RUN_ONCE_FILTER, { term: { - config_id: monitorIdArg ?? monitorId, + config_id: configId, }, }, ], @@ -58,18 +68,51 @@ export function useStatusByLocation(monitorIdArg?: string) { }, }, }, - [lastRefresh, monitorId, monitorIdArg], + [lastRefresh, configId], { name: 'getMonitorStatusByLocation' } ); return useMemo(() => { - const locations = (data?.aggregations?.locations.buckets ?? []).map((loc) => { + const getColor = (status: string) => { + switch (status) { + case 'up': + return theme.eui.euiColorVis0; + case 'down': + return theme.eui.euiColorVis9; + default: + return 'subdued'; + } + }; + + const locationPings = (data?.aggregations?.locations.buckets ?? []).map((loc) => { return loc.summary.hits.hits?.[0]._source as Ping; }); + const locations = (monitorLocations ?? []) + .map((loc) => { + const fullLoc = allLocations.find((l) => l.id === loc.id); + if (fullLoc) { + const ping = locationPings.find((p) => p.observer?.geo?.name === fullLoc?.label); + const status = ping ? (ping.summary?.down ?? 0 > 0 ? 'down' : 'up') : 'unknown'; + return { + status, + id: fullLoc?.id, + label: fullLoc?.label, + color: getColor(status), + }; + } + }) + .filter(Boolean) as LocationsStatus; return { locations, loading, }; - }, [data, loading]); + }, [ + allLocations, + data?.aggregations?.locations.buckets, + loading, + monitorLocations, + theme.eui.euiColorVis0, + theme.eui.euiColorVis9, + ]); } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx index b219e872ca7214..69cad74504ddd9 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx @@ -16,6 +16,7 @@ import { APP_WRAPPER_CLASS } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useInspectorContext } from '@kbn/observability-plugin/public'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public'; +import { EditMonitorLink } from './components/common/links/edit_monitor'; import { MonitorDetailsLocation } from './components/monitor_details/monitor_details_location'; import { getStepDetailsRoute } from './components/step_details_page/route_config'; import { getTestRunDetailsRoute } from './components/test_run_details/route_config'; @@ -322,6 +323,7 @@ const getMonitorSummaryHeader = ( }, ], rightSideItems: [ + , , , , diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/effects.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/effects.ts index f28e3bbfc947db..5a403cdf878691 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/effects.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/browser_journey/effects.ts @@ -6,8 +6,14 @@ */ import { Action } from 'redux-actions'; -import { all, call, fork, put, select, takeEvery, takeLeading, throttle } from 'redux-saga/effects'; -import { ScreenshotBlockDoc, ScreenshotBlockCache } from '../../../../../common/runtime_types'; +import { all, call, fork, put, select, takeEvery, throttle } from 'redux-saga/effects'; +import { serializeHttpFetchError } from '../utils/http_error'; +import { FetchNetworkEventsParams } from '../network_events/actions'; +import { + ScreenshotBlockDoc, + ScreenshotBlockCache, + SyntheticsJourneyApiResponse, +} from '../../../../../common/runtime_types'; import { fetchBrowserJourney, fetchScreenshotBlockSet } from './api'; import { @@ -23,7 +29,6 @@ import { import { isPendingBlock } from './models'; import { selectBrowserJourneyState } from './selectors'; -import { fetchEffectFactory } from '../utils/fetch_effect'; export function* browserJourneyEffects() { yield all([fork(fetchScreenshotBlocks), fork(generateBlockStatsOnPut), fork(pruneBlockCache)]); @@ -89,8 +94,28 @@ function* pruneBlockCache() { } export function* fetchJourneyStepsEffect() { - yield takeLeading( - fetchJourneyAction.get, - fetchEffectFactory(fetchBrowserJourney, fetchJourneyAction.success, fetchJourneyAction.fail) + const inProgressRequests = new Set(); + + yield takeEvery( + String(fetchJourneyAction.get), + function* (action: Action): Generator { + try { + if (!inProgressRequests.has(action.payload.checkGroup)) { + inProgressRequests.add(action.payload.checkGroup); + + const response = (yield call( + fetchBrowserJourney, + action.payload + )) as SyntheticsJourneyApiResponse; + + inProgressRequests.delete(action.payload.checkGroup); + + yield put(fetchJourneyAction.success(response)); + } + } catch (e) { + inProgressRequests.delete(action.payload.checkGroup); + yield put(fetchJourneyAction.fail(serializeHttpFetchError(e, action.payload))); + } + } ); } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/selectors.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/selectors.ts index 2aaa9f14e9f32a..3531fd21d95d48 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/selectors.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/manual_test_runs/selectors.ts @@ -15,8 +15,9 @@ export const manualTestRunSelector = configId ? manualTestRuns[configId] : undefined; export const manualTestRunInProgressSelector = - (configId: string) => + (configId?: string) => ({ manualTestRuns }: SyntheticsAppState) => { + if (!configId) return false; return ( manualTestRuns[configId]?.status === 'in-progress' || manualTestRuns[configId]?.status === 'loading' diff --git a/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts b/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts index 6cf752d26ed8db..22c5f84cf28ffd 100644 --- a/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts +++ b/x-pack/plugins/synthetics/server/alert_rules/status_rule/status_rule_executor.ts @@ -129,7 +129,7 @@ export class StatusRuleExecutor { async getDownChecks( prevDownConfigs: OverviewStatus['downConfigs'] = {} ): Promise { - const { listOfLocations, enabledIds } = await this.getMonitors(); + const { listOfLocations, allIds, enabledIds } = await this.getMonitors(); if (enabledIds.length > 0) { const currentStatus = await queryMonitorStatus( @@ -153,7 +153,12 @@ export class StatusRuleExecutor { const staleDownConfigs = this.markDeletedConfigs(downConfigs); - return { ...currentStatus, staleDownConfigs }; + return { + ...currentStatus, + staleDownConfigs, + allMonitorsCount: allIds.length, + disabledMonitorsCount: allIds.length - enabledIds.length, + }; } const staleDownConfigs = this.markDeletedConfigs(prevDownConfigs); return { @@ -163,6 +168,8 @@ export class StatusRuleExecutor { down: 0, up: 0, enabledIds, + allMonitorsCount: allIds.length, + disabledMonitorsCount: allIds.length, }; } diff --git a/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts b/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts index 38b42674eab8c7..d2af120492597e 100644 --- a/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts +++ b/x-pack/plugins/synthetics/server/queries/query_monitor_status.ts @@ -18,7 +18,7 @@ export async function queryMonitorStatus( range: { from: string | number; to: string }, ids: string[], monitorLocationsMap?: Record -): Promise> { +): Promise> { const idSize = Math.trunc(DEFAULT_MAX_ES_BUCKET_SIZE / listOfLocations.length || 1); const pageCount = Math.ceil(ids.length / idSize); const promises: Array> = []; diff --git a/x-pack/plugins/synthetics/server/routes/status/current_status.ts b/x-pack/plugins/synthetics/server/routes/status/current_status.ts index 159b464312f69b..a9bdba81c95e6d 100644 --- a/x-pack/plugins/synthetics/server/routes/status/current_status.ts +++ b/x-pack/plugins/synthetics/server/routes/status/current_status.ts @@ -48,6 +48,7 @@ export async function getStatus( const { query } = params; const enabledIds: string[] = []; let disabledCount = 0; + let disabledMonitorsCount = 0; let maxPeriod = 0; let listOfLocationsSet = new Set(); const monitorLocationMap: Record = {}; @@ -89,6 +90,7 @@ export async function getStatus( const attrs = monitor.attributes; if (attrs[ConfigKey.ENABLED] === false) { disabledCount += attrs[ConfigKey.LOCATIONS].length; + disabledMonitorsCount += 1; } else { const missingLabels = new Set(); @@ -127,6 +129,8 @@ export async function getStatus( ); return { + allMonitorsCount: allMonitors.length, + disabledMonitorsCount, enabledIds, disabledCount, up, diff --git a/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts index 62a54db4460a6f..52056b77ae8b7e 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/service_api_client.test.ts @@ -200,7 +200,7 @@ describe('callAPI', () => { 'x-kibana-version': '8.7.0', }, httpsAgent: expect.objectContaining({ - options: { rejectUnauthorized: true, path: null }, + options: { noDelay: true, rejectUnauthorized: true, path: null }, }), method: 'POST', url: 'https://service.dev/monitors', @@ -213,7 +213,7 @@ describe('callAPI', () => { 'x-kibana-version': '8.7.0', }, httpsAgent: expect.objectContaining({ - options: { rejectUnauthorized: true, path: null }, + options: { noDelay: true, rejectUnauthorized: true, path: null }, }), method: 'POST', url: 'https://qa.service.elstc.co/monitors', @@ -226,7 +226,7 @@ describe('callAPI', () => { 'x-kibana-version': '8.7.0', }, httpsAgent: expect.objectContaining({ - options: { rejectUnauthorized: true, path: null }, + options: { noDelay: true, rejectUnauthorized: true, path: null }, }), method: 'POST', url: 'https://qa.service.stg.co/monitors', @@ -293,6 +293,7 @@ describe('callAPI', () => { httpsAgent: expect.objectContaining({ options: { rejectUnauthorized: true, + noDelay: true, path: null, cert: 'test-certificate', key: 'test-key', diff --git a/x-pack/plugins/task_manager/server/lib/retry_on_bulk_update_conflict.test.ts b/x-pack/plugins/task_manager/server/lib/retry_on_bulk_update_conflict.test.ts deleted file mode 100644 index 00c4a613fd4251..00000000000000 --- a/x-pack/plugins/task_manager/server/lib/retry_on_bulk_update_conflict.test.ts +++ /dev/null @@ -1,309 +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 { loggingSystemMock, savedObjectsRepositoryMock } from '@kbn/core/server/mocks'; -import { SerializedConcreteTaskInstance, TaskStatus } from '../task'; -import { NUM_RETRIES, retryOnBulkUpdateConflict } from './retry_on_bulk_update_conflict'; - -const mockSavedObjectsRepository = savedObjectsRepositoryMock.create(); -const mockLogger = loggingSystemMock.create().get(); -const mockedDate = new Date('2019-02-12T21:01:22.479Z'); - -const task1 = { - type: 'task', - id: 'task:123456', - attributes: { - runAt: mockedDate.toISOString(), - scheduledAt: mockedDate.toISOString(), - startedAt: null, - retryAt: null, - params: `{ "hello": "world" }`, - state: `{ "id": "123456" }`, - taskType: 'alert', - attempts: 3, - status: 'idle' as TaskStatus, - ownerId: null, - traceparent: '', - }, -}; - -const task2 = { - type: 'task', - id: 'task:324242', - attributes: { - runAt: mockedDate.toISOString(), - scheduledAt: mockedDate.toISOString(), - startedAt: null, - retryAt: null, - params: `{ "hello": "world" }`, - state: `{ "foo": "bar" }`, - taskType: 'report', - attempts: 3, - status: 'idle' as TaskStatus, - ownerId: null, - traceparent: '', - }, -}; - -const task3 = { - type: 'task', - id: 'task:xyaaa', - attributes: { - runAt: mockedDate.toISOString(), - scheduledAt: mockedDate.toISOString(), - startedAt: null, - retryAt: null, - params: `{ "goodbye": "world" }`, - state: `{ "foo": "bar" }`, - taskType: 'action', - attempts: 3, - status: 'idle' as TaskStatus, - ownerId: null, - traceparent: '', - }, -}; - -describe('retryOnBulkUpdateConflict', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - test('should not retry when all updates are successful', async () => { - const savedObjectResponse = [ - { - id: task1.id, - type: task1.type, - attributes: task1.attributes, - references: [], - }, - ]; - mockSavedObjectsRepository.bulkUpdate.mockResolvedValueOnce({ - saved_objects: savedObjectResponse, - }); - const { savedObjects } = await retryOnBulkUpdateConflict({ - logger: mockLogger, - savedObjectsRepository: mockSavedObjectsRepository, - objects: [task1], - }); - - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenCalledTimes(1); - expect(savedObjects).toEqual(savedObjectResponse); - }); - - test('should throw error when saved objects bulkUpdate throws an error', async () => { - mockSavedObjectsRepository.bulkUpdate.mockImplementationOnce(() => { - throw new Error('fail'); - }); - await expect(() => - retryOnBulkUpdateConflict({ - logger: mockLogger, - savedObjectsRepository: mockSavedObjectsRepository, - objects: [task1], - }) - ).rejects.toThrowErrorMatchingInlineSnapshot(`"fail"`); - }); - - test('should not retry and return non-conflict errors', async () => { - const savedObjectResponse = [ - { - id: task1.id, - type: task1.type, - attributes: task1.attributes, - references: [], - }, - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - error: { - error: `Not a conflict`, - message: `Some error that's not a conflict`, - statusCode: 404, - }, - references: [], - }, - ]; - mockSavedObjectsRepository.bulkUpdate.mockResolvedValueOnce({ - saved_objects: savedObjectResponse, - }); - const { savedObjects } = await retryOnBulkUpdateConflict({ - logger: mockLogger, - savedObjectsRepository: mockSavedObjectsRepository, - objects: [task1, task2], - }); - - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenCalledTimes(1); - expect(savedObjects).toEqual(savedObjectResponse); - }); - - test(`should return conflict errors when number of retries exceeds ${NUM_RETRIES}`, async () => { - const savedObjectResponse = [ - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - error: { - error: `Conflict`, - message: `There was a conflict`, - statusCode: 409, - }, - references: [], - }, - ]; - mockSavedObjectsRepository.bulkUpdate.mockResolvedValue({ - saved_objects: savedObjectResponse, - }); - const { savedObjects } = await retryOnBulkUpdateConflict({ - logger: mockLogger, - savedObjectsRepository: mockSavedObjectsRepository, - objects: [task2], - }); - - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenCalledTimes(NUM_RETRIES + 1); - expect(savedObjects).toEqual(savedObjectResponse); - - expect(mockLogger.warn).toBeCalledWith('Bulk update saved object conflicts, exceeded retries'); - }); - - test('should retry as expected when there are conflicts', async () => { - mockSavedObjectsRepository.bulkUpdate - .mockResolvedValueOnce({ - saved_objects: [ - { - id: task1.id, - type: task1.type, - attributes: task1.attributes, - references: [], - }, - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - error: { - error: `Conflict`, - message: `This is a conflict`, - statusCode: 409, - }, - references: [], - }, - { - id: task3.id, - type: task3.type, - attributes: task3.attributes, - error: { - error: `Conflict`, - message: `This is a conflict`, - statusCode: 409, - }, - references: [], - }, - ], - }) - .mockResolvedValueOnce({ - saved_objects: [ - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - error: { - error: `Conflict`, - message: `This is a conflict`, - statusCode: 409, - }, - references: [], - }, - { - id: task3.id, - type: task3.type, - attributes: task3.attributes, - references: [], - }, - ], - }) - .mockResolvedValueOnce({ - saved_objects: [ - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - error: { - error: `Conflict`, - message: `This is a conflict`, - statusCode: 409, - }, - references: [], - }, - ], - }) - .mockResolvedValueOnce({ - saved_objects: [ - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - error: { - error: `Conflict`, - message: `This is a conflict`, - statusCode: 409, - }, - references: [], - }, - ], - }) - .mockResolvedValueOnce({ - saved_objects: [ - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - references: [], - }, - ], - }); - const { savedObjects } = await retryOnBulkUpdateConflict({ - logger: mockLogger, - savedObjectsRepository: mockSavedObjectsRepository, - objects: [task1, task2, task3], - retries: 5, - }); - - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenCalledTimes(5); - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenNthCalledWith( - 1, - [task1, task2, task3], - undefined - ); - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenNthCalledWith( - 2, - [task2, task3], - undefined - ); - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenNthCalledWith(3, [task2], undefined); - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenNthCalledWith(4, [task2], undefined); - expect(mockSavedObjectsRepository.bulkUpdate).toHaveBeenNthCalledWith(5, [task2], undefined); - expect(savedObjects).toEqual([ - { - id: task1.id, - type: task1.type, - attributes: task1.attributes, - references: [], - }, - { - id: task3.id, - type: task3.type, - attributes: task3.attributes, - references: [], - }, - { - id: task2.id, - type: task2.type, - attributes: task2.attributes, - references: [], - }, - ]); - }); -}); diff --git a/x-pack/plugins/task_manager/server/lib/retry_on_bulk_update_conflict.ts b/x-pack/plugins/task_manager/server/lib/retry_on_bulk_update_conflict.ts deleted file mode 100644 index cdf4d9234e5416..00000000000000 --- a/x-pack/plugins/task_manager/server/lib/retry_on_bulk_update_conflict.ts +++ /dev/null @@ -1,123 +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 { - ISavedObjectsRepository, - Logger, - SavedObjectsBulkUpdateObject, - SavedObjectsBulkUpdateOptions, - SavedObjectsUpdateResponse, -} from '@kbn/core/server'; - -export const NUM_RETRIES = 2; - -interface RetryOnBulkUpdateConflictOpts { - logger: Logger; - savedObjectsRepository: ISavedObjectsRepository; - objects: Array>; - options?: SavedObjectsBulkUpdateOptions; - retries?: number; -} - -interface RetryOnBulkUpdateConflictResults { - savedObjects: Array>; -} - -export const retryOnBulkUpdateConflict = async ({ - logger, - savedObjectsRepository, - objects, - options, - retries = NUM_RETRIES, -}: RetryOnBulkUpdateConflictOpts): Promise> => { - return retryOnBulkUpdateConflictHelper({ - logger, - savedObjectsRepository, - objects, - options, - retries, - }); -}; - -const retryOnBulkUpdateConflictHelper = async ({ - logger, - savedObjectsRepository, - objects, - options, - retries = NUM_RETRIES, - accResults = [], -}: RetryOnBulkUpdateConflictOpts & { - accResults?: Array>; -}): Promise> => { - try { - const { saved_objects: savedObjectsResults } = await savedObjectsRepository.bulkUpdate( - objects, - options - ); - - const currResults: Array> = []; - const currConflicts: Array> = []; - const objectsToRetry: Array> = []; - savedObjectsResults.forEach( - (savedObjectResult: SavedObjectsUpdateResponse, index: number) => { - if (savedObjectResult.error && savedObjectResult.error.statusCode === 409) { - // The SavedObjectsRepository maintains the order of the docs - // so we can rely on the index in the `docs` to match an error - // on the same index in the `bulkUpdate` result - objectsToRetry.push(objects[index]); - currConflicts.push(savedObjectResult); - } else { - // Save results, whether they are successful or non-conflict errors - currResults.push(savedObjectResult); - } - } - ); - - const results = - retries <= 0 - ? [...accResults, ...currResults, ...currConflicts] - : [...accResults, ...currResults]; - - if (objectsToRetry.length === 0) { - return { - savedObjects: results, - }; - } - - if (retries <= 0) { - logger.warn(`Bulk update saved object conflicts, exceeded retries`); - - return { - savedObjects: results, - }; - } - - await waitBeforeNextRetry(retries); - - return retryOnBulkUpdateConflictHelper({ - logger, - savedObjectsRepository, - objects: objectsToRetry, - options, - retries: retries - 1, - accResults: results, - }); - } catch (err) { - throw err; - } -}; - -export const randomDelayMs = Math.floor(Math.random() * 100); -export const getExponentialDelayMultiplier = (retries: number) => 1 + (NUM_RETRIES - retries) ** 2; -export const RETRY_IF_CONFLICTS_DELAY = 250; -export const waitBeforeNextRetry = async (retries: number): Promise => { - const exponentialDelayMultiplier = getExponentialDelayMultiplier(retries); - - await new Promise((resolve) => - setTimeout(resolve, RETRY_IF_CONFLICTS_DELAY * exponentialDelayMultiplier + randomDelayMs) - ); -}; diff --git a/x-pack/plugins/task_manager/server/plugin.ts b/x-pack/plugins/task_manager/server/plugin.ts index 7f2f537a25284d..100254f6dae327 100644 --- a/x-pack/plugins/task_manager/server/plugin.ts +++ b/x-pack/plugins/task_manager/server/plugin.ts @@ -207,7 +207,6 @@ export class TaskManagerPlugin const serializer = savedObjects.createSerializer(); const taskStore = new TaskStore({ - logger: this.logger, serializer, savedObjectsRepository, esClient: elasticsearch.client.asInternalUser, diff --git a/x-pack/plugins/task_manager/server/task_scheduling.ts b/x-pack/plugins/task_manager/server/task_scheduling.ts index ac4294c12baaf2..22d80fdf218283 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.ts @@ -43,7 +43,6 @@ import { EphemeralTaskRejectedDueToCapacityError } from './task_running'; const VERSION_CONFLICT_STATUS = 409; const BULK_ACTION_SIZE = 100; -const BULK_UPDATE_NUM_RETRIES = 3; export interface TaskSchedulingOpts { logger: Logger; taskStore: TaskStore; @@ -265,10 +264,7 @@ export class TaskScheduling { } private async bulkUpdateTasksHelper(updatedTasks: ConcreteTaskInstance[]) { - // Performs bulk update with retries - return ( - await this.store.bulkUpdate(updatedTasks, BULK_UPDATE_NUM_RETRIES) - ).reduce( + return (await this.store.bulkUpdate(updatedTasks)).reduce( (acc, task) => { if (task.tag === 'ok') { acc.tasks.push(task.value); diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index 5d1484101cd0c0..dfc21a7142ecef 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -15,11 +15,7 @@ import { TaskLifecycleResult, SerializedConcreteTaskInstance, } from './task'; -import { - elasticsearchServiceMock, - savedObjectsServiceMock, - loggingSystemMock, -} from '@kbn/core/server/mocks'; +import { elasticsearchServiceMock, savedObjectsServiceMock } from '@kbn/core/server/mocks'; import { TaskStore, SearchOpts, AggregationOpts } from './task_store'; import { savedObjectsRepositoryMock } from '@kbn/core/server/mocks'; import { SavedObjectAttributes, SavedObjectsErrorHelpers } from '@kbn/core/server'; @@ -29,7 +25,6 @@ import { AdHocTaskCounter } from './lib/adhoc_task_counter'; const savedObjectsClient = savedObjectsRepositoryMock.create(); const serializer = savedObjectsServiceMock.createSerializer(); -const logger = loggingSystemMock.create().get(); const adHocTaskCounter = new AdHocTaskCounter(); const randomId = () => `id-${_.random(1, 20)}`; @@ -72,7 +67,6 @@ describe('TaskStore', () => { store = new TaskStore({ index: 'tasky', taskManagerId: '', - logger, serializer, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, @@ -239,7 +233,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -309,7 +302,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -408,7 +400,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -512,7 +503,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -520,98 +510,6 @@ describe('TaskStore', () => { }); }); - test('correctly returns errors from saved object bulk update', async () => { - const task = { - runAt: mockedDate, - scheduledAt: mockedDate, - startedAt: null, - retryAt: null, - id: 'task:324242', - params: { hello: 'world' }, - state: { foo: 'bar' }, - taskType: 'report', - attempts: 3, - status: 'idle' as TaskStatus, - version: '123', - ownerId: null, - traceparent: '', - }; - - savedObjectsClient.bulkUpdate.mockResolvedValueOnce({ - saved_objects: [ - { - id: task.id, - type: task.taskType, - attributes: { - runAt: mockedDate.toISOString(), - scheduledAt: mockedDate.toISOString(), - startedAt: null, - retryAt: null, - params: `{ "hello": "world" }`, - state: `{ "foo": "bar" }`, - taskType: 'report', - attempts: 3, - status: 'idle' as TaskStatus, - ownerId: null, - traceparent: '', - }, - error: { - error: `Not a conflict`, - message: `Some error that's not a conflict`, - statusCode: 404, - }, - references: [], - }, - ], - }); - const result = await store.bulkUpdate([task]); - expect(result).toEqual([ - { - error: { - entity: { - attempts: 3, - id: 'task:324242', - ownerId: null, - params: { hello: 'world' }, - retryAt: null, - runAt: mockedDate, - scheduledAt: mockedDate, - startedAt: null, - state: { foo: 'bar' }, - status: 'idle', - taskType: 'report', - traceparent: '', - version: '123', - }, - error: { - attributes: { - attempts: 3, - ownerId: null, - params: '{ "hello": "world" }', - retryAt: null, - runAt: mockedDate.toISOString(), - scheduledAt: mockedDate.toISOString(), - startedAt: null, - state: '{ "foo": "bar" }', - status: 'idle', - taskType: 'report', - traceparent: '', - }, - error: { - error: 'Not a conflict', - message: "Some error that's not a conflict", - statusCode: 404, - }, - id: 'task:324242', - references: [], - type: 'report', - }, - }, - tag: 'err', - }, - ]); - }); - test('pushes error from saved objects client to errors$', async () => { const task = { runAt: mockedDate, @@ -646,7 +544,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -681,7 +578,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -716,7 +612,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -802,7 +697,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -823,7 +717,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -842,7 +735,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, @@ -861,7 +753,6 @@ describe('TaskStore', () => { index: 'tasky', taskManagerId: '', serializer, - logger, esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, definitions: taskDefinitions, savedObjectsRepository: savedObjectsClient, diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index aca1d2af956dcd..e810ea5c1ef3e0 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -15,7 +15,6 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { SavedObjectsBulkDeleteResponse } from '@kbn/core/server'; import { - Logger, SavedObject, ISavedObjectsSerializer, SavedObjectsRawDoc, @@ -36,10 +35,8 @@ import { import { TaskTypeDictionary } from './task_type_dictionary'; import { AdHocTaskCounter } from './lib/adhoc_task_counter'; -import { retryOnBulkUpdateConflict } from './lib/retry_on_bulk_update_conflict'; export interface StoreOpts { - logger: Logger; esClient: ElasticsearchClient; index: string; taskManagerId: string; @@ -97,7 +94,6 @@ export class TaskStore { public readonly errors$ = new Subject(); private esClient: ElasticsearchClient; - private logger: Logger; private definitions: TaskTypeDictionary; private savedObjectsRepository: ISavedObjectsRepository; private serializer: ISavedObjectsSerializer; @@ -115,7 +111,6 @@ export class TaskStore { constructor(opts: StoreOpts) { this.esClient = opts.esClient; this.index = opts.index; - this.logger = opts.logger; this.taskManagerId = opts.taskManagerId; this.definitions = opts.definitions; this.serializer = opts.serializer; @@ -251,45 +246,34 @@ export class TaskStore { * @param {Array} docs * @returns {Promise>} */ - public async bulkUpdate( - docs: ConcreteTaskInstance[], - retries: number = 0 - ): Promise { + public async bulkUpdate(docs: ConcreteTaskInstance[]): Promise { const attributesByDocId = docs.reduce((attrsById, doc) => { attrsById.set(doc.id, taskInstanceToAttributes(doc)); return attrsById; }, new Map()); - let updatedSavedObjects: Array>; + let updatedSavedObjects: Array; try { - ({ savedObjects: updatedSavedObjects } = - await retryOnBulkUpdateConflict({ - logger: this.logger, - savedObjectsRepository: this.savedObjectsRepository, - objects: docs.map((doc) => ({ + ({ saved_objects: updatedSavedObjects } = + await this.savedObjectsRepository.bulkUpdate( + docs.map((doc) => ({ type: 'task', id: doc.id, options: { version: doc.version }, attributes: attributesByDocId.get(doc.id)!, })), - options: { + { refresh: false, - }, - retries, - })); + } + )); } catch (e) { this.errors$.next(e); throw e; } - return updatedSavedObjects.map((updatedSavedObject) => { - const doc = docs.find((d) => d.id === updatedSavedObject.id); - return updatedSavedObject.error !== undefined - ? asErr({ - entity: doc, - error: updatedSavedObject, - }) - : asOk( + return updatedSavedObjects.map((updatedSavedObject, index) => + isSavedObjectsUpdateResponse(updatedSavedObject) + ? asOk( savedObjectToConcreteTaskInstance({ ...updatedSavedObject, attributes: defaults( @@ -297,8 +281,15 @@ export class TaskStore { attributesByDocId.get(updatedSavedObject.id)! ), }) - ); - }) as BulkUpdateResult[]; + ) + : asErr({ + // The SavedObjectsRepository maintains the order of the docs + // so we can rely on the index in the `docs` to match an error + // on the same index in the `bulkUpdate` result + entity: docs[index], + error: updatedSavedObject, + }) + ); } /** @@ -544,3 +535,9 @@ function ensureAggregationOnlyReturnsTaskObjects(opts: AggregationOpts): Aggrega query, }; } + +function isSavedObjectsUpdateResponse( + result: SavedObjectsUpdateResponse | Error +): result is SavedObjectsUpdateResponse { + return result && typeof (result as SavedObjectsUpdateResponse).id === 'string'; +} diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index cb3e798e4a6e7a..d65ae5a95231d9 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -9534,6 +9534,12 @@ "description": "The session cleanup interval that is configured, in minutes (0 if disabled)." } }, + "sessionConcurrentSessionsMaxSessions": { + "type": "long", + "_meta": { + "description": "The maximum number of the concurrent user sessions (0 if not configured)." + } + }, "anonymousCredentialType": { "type": "keyword", "_meta": { diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts new file mode 100644 index 00000000000000..af3758906ea10c --- /dev/null +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + BLOCK_LIST_ADD_BUTTON, + BLOCK_LIST_DESCRIPTION, + BLOCK_LIST_NAME, + BLOCK_LIST_TOAST_LIST, + FLYOUT_ADD_TO_BLOCK_LIST_ITEM, + FLYOUT_TAKE_ACTION_BUTTON, + INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON, + INDICATORS_TABLE_MORE_ACTION_BUTTON_ICON, + TOGGLE_FLYOUT_BUTTON, +} from '../screens/indicators'; +import { login } from '../tasks/login'; +import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; +import { selectRange } from '../tasks/select_range'; + +const THREAT_INTELLIGENCE = '/app/security/threat_intelligence/indicators'; + +const BLOCK_LIST_NEW_NAME = 'new blocklist entry'; + +const fillBlocklistForm = () => { + cy.get(BLOCK_LIST_NAME).type(BLOCK_LIST_NEW_NAME); + cy.get(BLOCK_LIST_DESCRIPTION).type('the best description'); + cy.get(BLOCK_LIST_ADD_BUTTON).last().click(); + + const text: string = `"${BLOCK_LIST_NEW_NAME}" has been added`; + cy.get(BLOCK_LIST_TOAST_LIST).should('exist').and('contain.text', text); +}; + +describe('Block list with invalid indicators', () => { + before(() => { + esArchiverLoad('threat_intelligence/invalid_indicators_data'); + login(); + }); + + beforeEach(() => { + cy.visit(THREAT_INTELLIGENCE); + selectRange(); + }); + + after(() => { + esArchiverUnload('threat_intelligence/invalid_indicators_data'); + }); + + it('should disabled the indicators table context menu item if invalid indicator', () => { + cy.get(INDICATORS_TABLE_MORE_ACTION_BUTTON_ICON).eq(3).click(); + cy.get(INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON).should('be.disabled'); + }); + + it('should disable the flyout context menu items if invalid indicator', () => { + cy.get(TOGGLE_FLYOUT_BUTTON).eq(3).click({ force: true }); + cy.get(FLYOUT_TAKE_ACTION_BUTTON).first().click(); + cy.get(FLYOUT_ADD_TO_BLOCK_LIST_ITEM).should('be.disabled'); + }); +}); + +describe('Block list interactions', () => { + before(() => { + esArchiverLoad('threat_intelligence/indicators_data'); + login(); + }); + + beforeEach(() => { + cy.visit(THREAT_INTELLIGENCE); + selectRange(); + }); + + after(() => { + esArchiverUnload('threat_intelligence/indicators_data'); + }); + + it('should add to block list from the indicators table', () => { + cy.get(INDICATORS_TABLE_MORE_ACTION_BUTTON_ICON).first().click(); + cy.get(INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON).first().click(); + + fillBlocklistForm(); + }); + + it('should add to block list from the indicator flyout', () => { + cy.get(TOGGLE_FLYOUT_BUTTON).first().click({ force: true }); + cy.get(FLYOUT_TAKE_ACTION_BUTTON).first().click(); + cy.get(FLYOUT_ADD_TO_BLOCK_LIST_ITEM).first().click(); + + fillBlocklistForm(); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts index ac5637f5e722c9..764d6348a07a88 100644 --- a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts +++ b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts @@ -17,6 +17,7 @@ import { } from '../../public/modules/indicators/components/barchart/legend_action/test_ids'; import { DROPDOWN_TEST_ID } from '../../public/modules/indicators/components/barchart/field_selector/test_ids'; import { + ADD_TO_BLOCK_LIST_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_BLOCK_LIST_TEST_ID, ADD_TO_EXISTING_CASE_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_EXISTING_CASE_TEST_ID, ADD_TO_NEW_CASE_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_NEW_CASE_TEST_ID, INVESTIGATE_IN_TIMELINE_TEST_ID as INDICATOR_FLYOUT_TAKE_ACTION_INVESTIGATE_IN_TIMELINE_TEST_ID, @@ -33,6 +34,7 @@ import { INDICATORS_FLYOUT_TITLE_TEST_ID, } from '../../public/modules/indicators/components/flyout/test_ids'; import { + ADD_TO_BLOCK_LIST_TEST_ID as INDICATORS_TABLE_ADD_TO_BLOCK_LIST_TEST_ID, ADD_TO_EXISTING_TEST_ID as INDICATORS_TABLE_ADD_TO_EXISTING_TEST_ID, ADD_TO_NEW_CASE_TEST_ID as INDICATORS_TABLE_ADD_TO_NEW_CASE_TEST_ID, MORE_ACTIONS_TEST_ID as INDICATORS_TABLE_MORE_ACTIONS_TEST_ID, @@ -101,6 +103,8 @@ export const INDICATORS_TABLE_ADD_TO_NEW_CASE_BUTTON_ICON = `[data-test-subj="${ export const INDICATORS_TABLE_ADD_TO_EXISTING_CASE_BUTTON_ICON = `[data-test-subj="${INDICATORS_TABLE_ADD_TO_EXISTING_TEST_ID}"]`; +export const INDICATORS_TABLE_ADD_TO_BLOCK_LIST_BUTTON_ICON = `[data-test-subj="${INDICATORS_TABLE_ADD_TO_BLOCK_LIST_TEST_ID}"]`; + /* Flyout */ export const TOGGLE_FLYOUT_BUTTON = `[data-test-subj="${BUTTON_TEST_ID}"]`; @@ -147,6 +151,8 @@ export const FLYOUT_ADD_TO_NEW_CASE_ITEM = `[data-test-subj="${INDICATOR_FLYOUT_ export const FLYOUT_INVESTIGATE_IN_TIMELINE_ITEM = `[data-test-subj="${INDICATOR_FLYOUT_TAKE_ACTION_INVESTIGATE_IN_TIMELINE_TEST_ID}"]`; +export const FLYOUT_ADD_TO_BLOCK_LIST_ITEM = `[data-test-subj="${INDICATOR_FLYOUT_TAKE_ACTION_ADD_TO_BLOCK_LIST_TEST_ID}"]`; + /* Field selector */ export const FIELD_SELECTOR = `[data-test-subj="${DROPDOWN_TEST_ID}"]`; @@ -197,6 +203,16 @@ export const NEW_CASE_DESCRIPTION_INPUT = `[data-test-subj="euiMarkdownEditorTex export const NEW_CASE_CREATE_BUTTON = `[data-test-subj="create-case-submit"]`; +/* Block list */ + +export const BLOCK_LIST_NAME = '[data-test-subj="blocklist-form-name-input"]'; + +export const BLOCK_LIST_DESCRIPTION = '[data-test-subj="blocklist-form-description-input"]'; + +export const BLOCK_LIST_ADD_BUTTON = '[class="eui-textTruncate"]'; + +export const BLOCK_LIST_TOAST_LIST = '[data-test-subj="globalToastList"]'; + /* Miscellaneous */ export const UNTITLED_TIMELINE_BUTTON = `[data-test-subj="flyoutOverlay"]`; diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx index 77398772a3bb2a..80cf2259ee93dc 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx @@ -5,7 +5,8 @@ * 2.0. */ -import React from 'react'; +import React, { NamedExoticComponent } from 'react'; +import { BlockListFlyoutProps, BlockListFormProps } from '../../types'; import { SecuritySolutionPluginContext } from '../..'; export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext => ({ @@ -18,7 +19,10 @@ export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext ({ children }) =>
    {children}
    , licenseService: { - isEnterprise() { + isEnterprise(): boolean { + return true; + }, + isPlatinumPlus(): boolean { return true; }, }, @@ -48,4 +52,11 @@ export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext registerQuery: () => {}, deregisterQuery: () => {}, + + blockList: { + exceptionListApiClient: {}, + useSetUrlParams: () => (params, replace) => {}, + getFlyoutComponent: () => (
    ) as unknown as NamedExoticComponent, + getFormComponent: () => (
    ) as unknown as NamedExoticComponent, + }, }); diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx index fbbc134a42c130..07f62805fe5303 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx @@ -23,6 +23,7 @@ import { mockUiSettingsService } from './mock_kibana_ui_settings_service'; import { mockKibanaTimelinesService } from './mock_kibana_timelines_service'; import { mockTriggersActionsUiService } from './mock_kibana_triggers_actions_ui_service'; import { InspectorContext } from '../../containers/inspector'; +import { BlockListProvider } from '../../modules/indicators/containers/block_list_provider'; export interface KibanaContextMock { /** @@ -101,7 +102,9 @@ export const StoryProvidersComponent: VFC = ({ - {children} + + {children} + diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/__snapshots__/add_to_block_list.test.tsx.snap b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/__snapshots__/add_to_block_list.test.tsx.snap new file mode 100644 index 00000000000000..c8738e007c824c --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/__snapshots__/add_to_block_list.test.tsx.snap @@ -0,0 +1,193 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should render a disabled EuiContextMenuItem 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
    + +
    + , + "container":
    + +
    , + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[` should render an EuiContextMenuItem 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
    + +
    + , + "container":
    + +
    , + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.stories.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.stories.tsx new file mode 100644 index 00000000000000..437ad64d9fb99a --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.stories.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { Story } from '@storybook/react'; +import { EuiContextMenuPanel } from '@elastic/eui'; +import { SecuritySolutionContext } from '../../../../containers/security_solution_context'; +import { SecuritySolutionPluginContext } from '../../../..'; +import { getSecuritySolutionContextMock } from '../../../../common/mocks/mock_security_context'; +import { AddToBlockListContextMenu } from '.'; +import { BlockListProvider } from '../../../indicators/containers/block_list_provider'; + +export default { + title: 'AddToBlocklist', +}; + +export const ContextMenu: Story = () => { + const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); + + const mockIndicatorFileHashValue: string = 'abc'; + const mockOnClick: () => void = () => window.alert('clicked!'); + const items = [ + , + ]; + + return ( + + + + + + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.test.tsx new file mode 100644 index 00000000000000..1c0c3eb4480005 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.test.tsx @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import { AddToBlockListContextMenu } from '.'; +import { BlockListProvider } from '../../../indicators/containers/block_list_provider'; +import { SecuritySolutionContext } from '../../../../containers/security_solution_context'; +import { SecuritySolutionPluginContext } from '../../../..'; +import { getSecuritySolutionContextMock } from '../../../../common/mocks/mock_security_context'; + +describe('', () => { + it('should render an EuiContextMenuItem', () => { + const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); + + const mockIndicatorFileHashValue: string = 'abc'; + const mockOnClick: () => void = () => window.alert('clicked!'); + + const component = render( + + + + + + ); + + expect(component).toMatchSnapshot(); + }); + + it('should render a disabled EuiContextMenuItem', () => { + const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); + + const mockIndicatorFileHashValue = null; + const mockOnClick: () => void = () => window.alert('clicked!'); + + const component = render( + + + + + + ); + + expect(component).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.tsx new file mode 100644 index 00000000000000..ca74f9e5652efa --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/add_to_block_list.tsx @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { VFC } from 'react'; +import { EuiContextMenuItem } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useBlockListContext } from '../../../indicators/hooks/use_block_list_context'; +import { useSetUrlParams } from '../../hooks/use_set_url_params'; + +export interface AddToBlockListProps { + /** + * Indicator's filehash value (either sha256, sha1 or md5) + */ + data: string | null; + /** + * Used for unit and e2e tests + */ + ['data-test-subj']?: string; + /** + * Click event to notify the parent component (to for example close the popover) + */ + onClick: () => void; +} + +/** + * Add to blocklist functionality displayed as a ContextMenuItem (in the main indicators table row and in the indicator flyout). + * The entry is disabled is the filehash isn't sha256, sha1 or md5. + * When clicking on the ContextMenuItem, the indicator filehash value is saved in context. + * The flyout is shown by adding a parameter to the url. + */ +export const AddToBlockListContextMenu: VFC = ({ + data, + 'data-test-subj': dataTestSub, + onClick, +}) => { + const { setBlockListIndicatorValue } = useBlockListContext(); + const { setUrlParams } = useSetUrlParams(); + + const menuItemClicked = () => { + onClick(); + setBlockListIndicatorValue(data as string); + setUrlParams({ show: 'create' }); + }; + + return ( + menuItemClicked()} + data-test-subj={dataTestSub} + disabled={data == null} + > + + + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/index.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/index.ts new file mode 100644 index 00000000000000..b81a5690125d68 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/components/add_to_block_list/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './add_to_block_list'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/containers/flyout.tsx b/x-pack/plugins/threat_intelligence/public/modules/block_list/containers/flyout.tsx new file mode 100644 index 00000000000000..b75af1add4f41c --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/containers/flyout.tsx @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { VFC } from 'react'; +import { + CreateExceptionListItemSchema, + EntriesArray, +} from '@kbn/securitysolution-io-ts-list-types'; +import { useSecurityContext } from '../../../hooks/use_security_context'; + +export interface BlockListFlyoutProps { + /** + * Indicator file-hash value (sha256, sh1 or md5) to pass to the block list flyout. + */ + indicatorFileHash: string; +} + +/** + * Component calling the block list flyout (retrieved from the SecuritySolution plugin via context). + * This reuses a lot of components passed down via context from the Security Solution plugin: + * - the flyout component: https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx + * - the form component: https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx + */ +export const BlockListFlyout: VFC = ({ indicatorFileHash }) => { + const { blockList } = useSecurityContext(); + const Component = blockList.getFlyoutComponent(); + const exceptionListApiClient = blockList.exceptionListApiClient; + const FormComponent = blockList.getFormComponent(); + + // prepopulate the for with the indicator file hash + const entries: EntriesArray = [ + { + field: 'file.hash.*', + operator: 'included', + type: 'match_any', + value: [indicatorFileHash], + }, + ]; + + // prepare the payload to pass to the form (and then sent to the blocklist endpoint) + const item: CreateExceptionListItemSchema = { + description: '', + entries, + list_id: 'endpoint_blocklists', + name: '', + namespace_type: 'agnostic', + os_types: ['windows'], + tags: ['policy:all'], + type: 'simple', + }; + + const props = { + apiClient: exceptionListApiClient, + item, + policies: [], + FormComponent, + onClose: () => {}, + }; + + return ; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/index.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/index.ts new file mode 100644 index 00000000000000..491a1968d7974c --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './use_set_url_params'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/use_set_url_params.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/use_set_url_params.ts new file mode 100644 index 00000000000000..20f8312267c2b9 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/hooks/use_set_url_params.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useSecurityContext } from '../../../hooks'; + +/** + * Retrieve the useSetUrlParams hook from SecurityContext. + * The hook is passed down from the Security Solution plugin. + */ +export const useSetUrlParams = () => { + const { blockList } = useSecurityContext(); + return { setUrlParams: blockList.useSetUrlParams() }; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.test.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.test.ts new file mode 100644 index 00000000000000..35b8d479b681d2 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + generateMockFileIndicator, + Indicator, + RawIndicatorFieldId, +} from '../../../../common/types/indicator'; +import { canAddToBlockList } from './can_add_to_block_list'; +import { getIndicatorFieldAndValue } from '../../indicators'; + +describe('canAddToBlockList', () => { + it('should return null if indicator has none of required fields', () => { + const indicator = {} as unknown as Indicator; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(null); + }); + + it('should return sha256 value if indicator has the field', () => { + const indicator = generateMockFileIndicator(); + const sha256 = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.FileSha256).value; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(sha256); + }); + + it('should return sha1 value if sha256 is missing ', () => { + const indicator = generateMockFileIndicator(); + indicator.fields['threat.indicator.file.hash.sha256'] = undefined; + const sha1 = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.FileSha1).value; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(sha1); + }); + + it('should return md5 value if sha256 and sha1 are missing', () => { + const indicator = generateMockFileIndicator(); + indicator.fields['threat.indicator.file.hash.sha256'] = undefined; + indicator.fields['threat.indicator.file.hash.sha1'] = undefined; + const md5 = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.FileMd5).value; + const result = canAddToBlockList(indicator); + + expect(result).toEqual(md5); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.ts b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.ts new file mode 100644 index 00000000000000..037a4f4587e0f9 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/block_list/utils/can_add_to_block_list.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Indicator, RawIndicatorFieldId } from '../../../../common/types/indicator'; +import { getIndicatorFieldAndValue } from '../../indicators'; + +/** + * Checks if an indicator has sha256, sha1 or md5 (in that order) and returns an empty string if it does not. + * The value is returned to be used in the add to block list logic. + * + * @param indicator the indicator we want to + */ +export const canAddToBlockList = (indicator: Indicator): string | null => { + const sha256: string | null = getIndicatorFieldAndValue( + indicator, + RawIndicatorFieldId.FileSha256 + ).value; + if (sha256 != null) { + return sha256; + } + + const sha1: string | null = getIndicatorFieldAndValue( + indicator, + RawIndicatorFieldId.FileSha1 + ).value; + if (sha1 != null) { + return sha1; + } + + const md5: string | null = getIndicatorFieldAndValue( + indicator, + RawIndicatorFieldId.FileMd5 + ).value; + if (md5 != null) { + return md5; + } + + return null; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx index 8a67d596c13334..93c5890b23396a 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/take_action.tsx @@ -8,11 +8,14 @@ import React, { useState, VFC } from 'react'; import { EuiButton, EuiContextMenuPanel, EuiPopover, useGeneratedHtmlId } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { canAddToBlockList } from '../../../../block_list/utils/can_add_to_block_list'; +import { AddToBlockListContextMenu } from '../../../../block_list/components/add_to_block_list'; import { AddToNewCase } from '../../../../cases/components/add_to_new_case/add_to_new_case'; import { AddToExistingCase } from '../../../../cases/components/add_to_existing_case/add_to_existing_case'; import { Indicator } from '../../../../../../common/types/indicator'; import { InvestigateInTimelineContextMenu } from '../../../../timeline'; import { + ADD_TO_BLOCK_LIST_TEST_ID, ADD_TO_EXISTING_CASE_TEST_ID, ADD_TO_NEW_CASE_TEST_ID, INVESTIGATE_IN_TIMELINE_TEST_ID, @@ -39,6 +42,7 @@ export const TakeAction: VFC = ({ indicator }) => { setPopover(false); }; + const indicatorValue: string | null = canAddToBlockList(indicator); const items = [ = ({ indicator }) => { onClick={closePopover} data-test-subj={ADD_TO_NEW_CASE_TEST_ID} />, + , ]; const button = ( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts index 051a9637a9f6cd..f661ae23571714 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/flyout/take_action/test_ids.ts @@ -9,3 +9,4 @@ export const TAKE_ACTION_BUTTON_TEST_ID = 'tiIndicatorFlyoutTakeActionButton'; export const INVESTIGATE_IN_TIMELINE_TEST_ID = 'tiIndicatorFlyoutInvestigateInTimelineContextMenu'; export const ADD_TO_EXISTING_CASE_TEST_ID = 'tiIndicatorFlyoutAddToExistingCaseContextMenu'; export const ADD_TO_NEW_CASE_TEST_ID = 'tiIndicatorFlyoutAddToNewCaseContextMenu'; +export const ADD_TO_BLOCK_LIST_TEST_ID = 'tiIndicatorFlyoutAddToBlockListContextMenu'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx index 705b9c5090f6c2..a5f6955f000041 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/more_actions.tsx @@ -14,10 +14,17 @@ import { useGeneratedHtmlId, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { AddToBlockListContextMenu } from '../../../../../block_list/components/add_to_block_list'; import { AddToNewCase } from '../../../../../cases/components/add_to_new_case/add_to_new_case'; import { AddToExistingCase } from '../../../../../cases/components/add_to_existing_case/add_to_existing_case'; import { Indicator } from '../../../../../../../common/types/indicator'; -import { ADD_TO_EXISTING_TEST_ID, ADD_TO_NEW_CASE_TEST_ID, MORE_ACTIONS_TEST_ID } from './test_ids'; +import { canAddToBlockList } from '../../../../../block_list/utils/can_add_to_block_list'; +import { + ADD_TO_BLOCK_LIST_TEST_ID, + ADD_TO_EXISTING_TEST_ID, + ADD_TO_NEW_CASE_TEST_ID, + MORE_ACTIONS_TEST_ID, +} from './test_ids'; const BUTTON_LABEL = i18n.translate('xpack.threatIntelligence.indicator.table.moreActions', { defaultMessage: 'More actions', @@ -55,6 +62,11 @@ export const MoreActions: VFC = ({ indicator }) => { onClick={closePopover} data-test-subj={ADD_TO_NEW_CASE_TEST_ID} />, + , ]; const button = ( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts index 7e5666283b2184..37edc59e11e8b2 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/components/more_actions/test_ids.ts @@ -8,3 +8,4 @@ export const MORE_ACTIONS_TEST_ID = 'tiIndicatorTableMoreActionsButton'; export const ADD_TO_EXISTING_TEST_ID = 'tiIndicatorTableAddToExistingCaseContextMenu'; export const ADD_TO_NEW_CASE_TEST_ID = 'tiIndicatorTableAddToNewCaseContextMenu'; +export const ADD_TO_BLOCK_LIST_TEST_ID = 'tiIndicatorsTableAddToBlockListContextMenu'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx new file mode 100644 index 00000000000000..3bdd3be858af72 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/containers/block_list_provider.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { createContext, Dispatch, FC, SetStateAction, useState } from 'react'; + +export interface BlockListContextValue { + blockListIndicatorValue: string; + setBlockListIndicatorValue: Dispatch>; +} + +export const BlockListContext = createContext(undefined); + +export const BlockListProvider: FC = ({ children }) => { + const [blockListIndicatorValue, setBlockListIndicatorValue] = useState(''); + + const context: BlockListContextValue = { + blockListIndicatorValue, + setBlockListIndicatorValue, + }; + return {children}; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_block_list_context.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_block_list_context.ts new file mode 100644 index 00000000000000..7aad9bd41745a9 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_block_list_context.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useContext } from 'react'; +import { BlockListContext, BlockListContextValue } from '../containers/block_list_provider'; + +/** + * Hook to retrieve {@link BlockListContext} + */ +export const useBlockListContext = (): BlockListContextValue => { + const contextValue = useContext(BlockListContext); + + if (!contextValue) { + throw new Error('BlockListContext can only be used within BlockListContext provider'); + } + + return contextValue; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx index aaac18f3fb2159..005538fe383e99 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx @@ -6,6 +6,9 @@ */ import React, { FC, VFC } from 'react'; +import { useBlockListContext } from '../hooks/use_block_list_context'; +import { BlockListProvider } from '../containers/block_list_provider'; +import { BlockListFlyout } from '../../block_list/containers/flyout'; import { IndicatorsBarChartWrapper } from '../components/barchart'; import { IndicatorsTable } from '../components/table'; import { useAggregatedIndicators, useIndicators, useSourcererDataView } from '../hooks'; @@ -22,12 +25,16 @@ import { QueryBar } from '../../query_bar/query_bar'; const IndicatorsPageProviders: FC = ({ children }) => ( - {children} + + {children} + ); const IndicatorsPageContent: VFC = () => { + const { blockListIndicatorValue } = useBlockListContext(); + const { browserFields, indexPattern } = useSourcererDataView(); const columnSettings = useColumnSettings(); @@ -101,6 +108,8 @@ const IndicatorsPageContent: VFC = () => { onChangeItemsPerPage={onChangeItemsPerPage} onChangePage={onChangePage} /> + + {blockListIndicatorValue && } ); diff --git a/x-pack/plugins/threat_intelligence/public/types.ts b/x-pack/plugins/threat_intelligence/public/types.ts index 9b11c705a20d00..73051c0f0e285f 100644 --- a/x-pack/plugins/threat_intelligence/public/types.ts +++ b/x-pack/plugins/threat_intelligence/public/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ComponentType, ReactElement, ReactNode, VFC } from 'react'; +import { ComponentType, NamedExoticComponent, ReactElement, ReactNode, VFC } from 'react'; import { CoreStart } from '@kbn/core/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { @@ -22,6 +22,7 @@ import { Store } from 'redux'; import { DataProvider } from '@kbn/timelines-plugin/common'; import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; import { CasesUiSetup, CasesUiStart } from '@kbn/cases-plugin/public/types'; +import { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; export interface SecuritySolutionDataViewBase extends DataViewBase { fields: Array; @@ -57,6 +58,7 @@ export type Services = { export interface LicenseAware { isEnterprise(): boolean; + isPlatinumPlus(): boolean; } export type BrowserFields = Readonly>>; @@ -74,6 +76,18 @@ export interface UseInvestigateInTimelineProps { to: string; } +export interface BlockListFlyoutProps { + apiClient: unknown; + item: CreateExceptionListItemSchema; + policies: unknown[]; + FormComponent: NamedExoticComponent; + onClose: () => void; +} + +export interface BlockListFormProps { + item: CreateExceptionListItemSchema; +} + /** * Methods exposed from the security solution to the threat intelligence application. */ @@ -124,4 +138,14 @@ export interface SecuritySolutionPluginContext { * Deregister stale query */ deregisterQuery: (query: { id: string }) => void; + + blockList: { + exceptionListApiClient: unknown; + useSetUrlParams: () => ( + params: Record, + replace?: boolean | undefined + ) => void; + getFlyoutComponent: () => NamedExoticComponent; + getFormComponent: () => NamedExoticComponent; + }; } diff --git a/x-pack/plugins/threat_intelligence/tsconfig.json b/x-pack/plugins/threat_intelligence/tsconfig.json index a8e1b2a96b37d7..3006da321be78f 100644 --- a/x-pack/plugins/threat_intelligence/tsconfig.json +++ b/x-pack/plugins/threat_intelligence/tsconfig.json @@ -31,6 +31,7 @@ "@kbn/kibana-react-plugin", "@kbn/utility-types", "@kbn/ui-theme", + "@kbn/securitysolution-io-ts-list-types" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_flapping_form_section.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_flapping_form_section.tsx new file mode 100644 index 00000000000000..bfde62591f6266 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_flapping_form_section.tsx @@ -0,0 +1,213 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiFormRowProps, + EuiIconTip, + EuiRange, + EuiRangeProps, + EuiSpacer, + EuiTitle, + EuiText, + EuiPanel, +} from '@elastic/eui'; +import { + RulesSettingsFlappingProperties, + MIN_LOOK_BACK_WINDOW, + MIN_STATUS_CHANGE_THRESHOLD, + MAX_LOOK_BACK_WINDOW, + MAX_STATUS_CHANGE_THRESHOLD, +} from '@kbn/alerting-plugin/common'; +import { useKibana } from '../../../common/lib/kibana'; + +type OnChangeKey = keyof Omit; + +const lookBackWindowLabel = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.lookBackWindowLabel', + { + defaultMessage: 'Rule run look back window', + } +); + +const statusChangeThresholdLabel = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.statusChangeThresholdLabel', + { + defaultMessage: 'Alert status change threshold', + } +); + +const getLookBackWindowLabelRuleRuns = (amount: number) => { + return i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.lookBackWindowLabelRuleRuns', + { + defaultMessage: '{amount, number} rule {amount, plural, one {run} other {runs}}', + values: { amount }, + } + ); +}; + +const getStatusChangeThresholdRuleRuns = (amount: number) => { + return i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.flapping.statusChangeThresholdTimes', + { + defaultMessage: '{amount, number} {amount, plural, one {time} other {times}}', + values: { amount }, + } + ); +}; + +export interface RulesSettingsRangeProps { + label: EuiFormRowProps['label']; + labelPopoverText?: string; + min: number; + max: number; + value: number; + disabled?: EuiRangeProps['disabled']; + onChange?: EuiRangeProps['onChange']; +} + +export const RulesSettingsFlappingTitle = () => { + return ( + +
    + +
    +
    + ); +}; + +export const RulesSettingsFlappingDescription = () => { + return ( + + + + ); +}; + +export const RulesSettingsRange = memo((props: RulesSettingsRangeProps) => { + const { label, labelPopoverText, min, max, value, disabled, onChange, ...rest } = props; + + const renderLabel = () => { + return ( +
    + {label} +   + +
    + ); + }; + + return ( + + + + ); +}); + +export interface RulesSettingsFlappingFormSectionProps { + flappingSettings: RulesSettingsFlappingProperties; + compressed?: boolean; + onChange: (key: OnChangeKey, value: number) => void; +} + +export const RulesSettingsFlappingFormSection = memo( + (props: RulesSettingsFlappingFormSectionProps) => { + const { flappingSettings, compressed = false, onChange } = props; + + const { lookBackWindow, statusChangeThreshold } = flappingSettings; + + const { + application: { capabilities }, + } = useKibana().services; + + const { + rulesSettings: { writeFlappingSettingsUI }, + } = capabilities; + + const canWriteFlappingSettings = writeFlappingSettingsUI; + + return ( + + {compressed && ( + <> + + + + + + + + + + + + + )} + + onChange('lookBackWindow', parseInt(e.currentTarget.value, 10))} + label={lookBackWindowLabel} + disabled={!canWriteFlappingSettings} + /> + + + onChange('statusChangeThreshold', parseInt(e.currentTarget.value, 10))} + label={statusChangeThresholdLabel} + disabled={!canWriteFlappingSettings} + /> + + + + + {getLookBackWindowLabelRuleRuns(lookBackWindow)}
    , + statusChangeThreshold: ( + {getStatusChangeThresholdRuleRuns(statusChangeThreshold)} + ), + }} + /> + + + + + ); + } +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.test.tsx new file mode 100644 index 00000000000000..e2e454e644ac00 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.test.tsx @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; +import { render, cleanup, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { coreMock } from '@kbn/core/public/mocks'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { RulesSettingsLink } from './rules_settings_link'; +import { useKibana } from '../../../common/lib/kibana'; +import { getFlappingSettings } from '../../lib/rule_api'; +import { updateFlappingSettings } from '../../lib/rule_api'; + +jest.mock('../../../common/lib/kibana'); +jest.mock('../../lib/rule_api/get_flapping_settings', () => ({ + getFlappingSettings: jest.fn(), +})); +jest.mock('../../lib/rule_api/update_flapping_settings', () => ({ + updateFlappingSettings: jest.fn(), +})); + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + cacheTime: 0, + }, + }, +}); + +const useKibanaMock = useKibana as jest.Mocked; + +const mocks = coreMock.createSetup(); + +const getFlappingSettingsMock = getFlappingSettings as unknown as jest.MockedFunction< + typeof getFlappingSettings +>; +const updateFlappingSettingsMock = updateFlappingSettings as unknown as jest.MockedFunction< + typeof updateFlappingSettings +>; + +const mockFlappingSetting: RulesSettingsFlapping = { + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 11, + createdBy: 'test user', + updatedBy: 'test user', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), +}; + +const RulesSettingsLinkWithProviders: React.FunctionComponent<{}> = () => ( + + + + + +); + +describe('rules_settings_link', () => { + beforeEach(async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: true, + }, + }; + getFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + updateFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + }); + + afterEach(() => { + jest.clearAllMocks(); + queryClient.clear(); + cleanup(); + }); + + test('renders the rules setting link correctly', async () => { + const result = render(); + await waitFor(() => { + expect(result.getByText('Settings')).toBeInTheDocument(); + }); + expect(result.getByText('Settings')).not.toBeDisabled(); + expect(result.queryByTestId('rulesSettingsModal')).toBe(null); + }); + + test('clicking the settings link opens the rules settings modal', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsModal')).toBe(null); + }); + + userEvent.click(result.getByText('Settings')); + + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsModal')).not.toBe(null); + }); + }); + + test('link is hidden when provided with insufficient read permissions', async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: false, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: true, + }, + }; + + let result = render(); + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsLink')).toBe(null); + }); + + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: false, + }, + }; + + result = render(); + await waitFor(() => { + expect(result.queryByTestId('rulesSettingsLink')).toBe(null); + }); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.tsx new file mode 100644 index 00000000000000..bb72db2bc41639 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_link.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; +import { EuiButtonEmpty } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { RulesSettingsModal } from './rules_settings_modal'; +import { useKibana } from '../../../common/lib/kibana'; + +export const RulesSettingsLink = () => { + const [isVisible, setIsVisible] = useState(false); + const { + application: { capabilities }, + } = useKibana().services; + + const { show, readFlappingSettingsUI } = capabilities.rulesSettings; + + if (!show || !readFlappingSettingsUI) { + return null; + } + + return ( + <> + setIsVisible(true)} + iconType="gear" + data-test-subj="rulesSettingsLink" + > + + + setIsVisible(false)} /> + + ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.test.tsx new file mode 100644 index 00000000000000..6915a46123a407 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.test.tsx @@ -0,0 +1,264 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; +import { render, fireEvent, cleanup, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { coreMock } from '@kbn/core/public/mocks'; +import { IToasts } from '@kbn/core/public'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { RulesSettingsModal, RulesSettingsModalProps } from './rules_settings_modal'; +import { useKibana } from '../../../common/lib/kibana'; +import { getFlappingSettings } from '../../lib/rule_api/get_flapping_settings'; +import { updateFlappingSettings } from '../../lib/rule_api/update_flapping_settings'; + +jest.mock('../../../common/lib/kibana'); +jest.mock('../../lib/rule_api/get_flapping_settings', () => ({ + getFlappingSettings: jest.fn(), +})); +jest.mock('../../lib/rule_api/update_flapping_settings', () => ({ + updateFlappingSettings: jest.fn(), +})); + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + cacheTime: 0, + }, + }, +}); + +const useKibanaMock = useKibana as jest.Mocked; + +const mocks = coreMock.createSetup(); + +const getFlappingSettingsMock = getFlappingSettings as unknown as jest.MockedFunction< + typeof getFlappingSettings +>; +const updateFlappingSettingsMock = updateFlappingSettings as unknown as jest.MockedFunction< + typeof updateFlappingSettings +>; + +const mockFlappingSetting: RulesSettingsFlapping = { + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + createdBy: 'test user', + updatedBy: 'test user', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), +}; + +const modalProps: RulesSettingsModalProps = { + isVisible: true, + setUpdatingRulesSettings: jest.fn(), + onClose: jest.fn(), + onSave: jest.fn(), +}; + +const RulesSettingsModalWithProviders: React.FunctionComponent = ( + props +) => ( + + + + + +); + +describe('rules_settings_modal', () => { + beforeEach(async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: true, + }, + }; + + useKibanaMock().services.notifications.toasts = { + addSuccess: jest.fn(), + addError: jest.fn(), + addDanger: jest.fn(), + addWarning: jest.fn(), + } as unknown as IToasts; + + getFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + updateFlappingSettingsMock.mockResolvedValue(mockFlappingSetting); + }); + + afterEach(() => { + jest.clearAllMocks(); + queryClient.clear(); + cleanup(); + }); + + test('renders flapping settings correctly', async () => { + const result = render(); + expect(getFlappingSettingsMock).toHaveBeenCalledTimes(1); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + expect(result.getByTestId('rulesSettingsModalEnableSwitch').getAttribute('aria-checked')).toBe( + 'true' + ); + expect(result.getByTestId('lookBackWindowRangeInput').getAttribute('value')).toBe('10'); + expect(result.getByTestId('statusChangeThresholdRangeInput').getAttribute('value')).toBe('10'); + + expect(result.getByTestId('rulesSettingsModalCancelButton')).toBeInTheDocument(); + expect(result.getByTestId('rulesSettingsModalSaveButton').getAttribute('disabled')).toBeFalsy(); + }); + + test('can save flapping settings', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + const lookBackWindowInput = result.getByTestId('lookBackWindowRangeInput'); + const statusChangeThresholdInput = result.getByTestId('statusChangeThresholdRangeInput'); + + fireEvent.change(lookBackWindowInput, { target: { value: 20 } }); + fireEvent.change(statusChangeThresholdInput, { target: { value: 5 } }); + + expect(lookBackWindowInput.getAttribute('value')).toBe('20'); + expect(statusChangeThresholdInput.getAttribute('value')).toBe('5'); + + // Try saving + userEvent.click(result.getByTestId('rulesSettingsModalSaveButton')); + + await waitFor(() => { + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + }); + expect(modalProps.onClose).toHaveBeenCalledTimes(1); + expect(updateFlappingSettingsMock).toHaveBeenCalledWith( + expect.objectContaining({ + flappingSettings: { + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 5, + }, + }) + ); + expect(useKibanaMock().services.notifications.toasts.addSuccess).toHaveBeenCalledTimes(1); + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + expect(modalProps.onSave).toHaveBeenCalledTimes(1); + }); + + test('should prevent statusChangeThreshold from being greater than lookBackWindow', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + const lookBackWindowInput = result.getByTestId('lookBackWindowRangeInput'); + const statusChangeThresholdInput = result.getByTestId('statusChangeThresholdRangeInput'); + + // Change lookBackWindow to a smaller value + fireEvent.change(lookBackWindowInput, { target: { value: 5 } }); + // statusChangeThresholdInput gets pinned to be 5 + expect(statusChangeThresholdInput.getAttribute('value')).toBe('5'); + + // Try making statusChangeThreshold bigger + fireEvent.change(statusChangeThresholdInput, { target: { value: 20 } }); + // Still pinned + expect(statusChangeThresholdInput.getAttribute('value')).toBe('5'); + + fireEvent.change(statusChangeThresholdInput, { target: { value: 3 } }); + expect(statusChangeThresholdInput.getAttribute('value')).toBe('3'); + }); + + test('handles errors when saving settings', async () => { + updateFlappingSettingsMock.mockRejectedValue('failed!'); + + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + // Try saving + userEvent.click(result.getByTestId('rulesSettingsModalSaveButton')); + await waitFor(() => { + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + }); + expect(modalProps.onClose).toHaveBeenCalledTimes(1); + expect(useKibanaMock().services.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); + expect(modalProps.setUpdatingRulesSettings).toHaveBeenCalledWith(true); + expect(modalProps.onSave).toHaveBeenCalledTimes(1); + }); + + test('displays flapping detection off prompt when flapping is disabled', async () => { + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + expect(result.queryByTestId('rulesSettingsModalFlappingOffPrompt')).toBe(null); + userEvent.click(result.getByTestId('rulesSettingsModalEnableSwitch')); + expect(result.queryByTestId('rulesSettingsModalFlappingOffPrompt')).not.toBe(null); + }); + + test('form elements are disabled when provided with insufficient write permissions', async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: true, + writeFlappingSettingsUI: false, + readFlappingSettingsUI: true, + }, + }; + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + expect(result.getByTestId('rulesSettingsModalEnableSwitch')).toBeDisabled(); + expect(result.getByTestId('lookBackWindowRangeInput')).toBeDisabled(); + expect(result.getByTestId('statusChangeThresholdRangeInput')).toBeDisabled(); + expect(result.getByTestId('rulesSettingsModalSaveButton')).toBeDisabled(); + }); + + test('form elements are not visible when provided with insufficient read permissions', async () => { + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + useKibanaMock().services.application.capabilities = { + ...capabilities, + rulesSettings: { + save: true, + show: false, + writeFlappingSettingsUI: true, + readFlappingSettingsUI: false, + }, + }; + + const result = render(); + await waitFor(() => { + expect(result.queryByTestId('centerJustifiedSpinner')).toBe(null); + }); + + expect(result.getByTestId('rulesSettingsErrorPrompt')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.tsx new file mode 100644 index 00000000000000..3b9e5d9ecf0ae9 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/rules_setting/rules_settings_modal.tsx @@ -0,0 +1,299 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useState } from 'react'; +import { RulesSettingsFlappingProperties } from '@kbn/alerting-plugin/common'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiButton, + EuiButtonEmpty, + EuiCallOut, + EuiHorizontalRule, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiModal, + EuiModalHeader, + EuiModalBody, + EuiModalFooter, + EuiModalHeaderTitle, + EuiSpacer, + EuiSwitch, + EuiSwitchProps, + EuiPanel, + EuiText, + EuiEmptyPrompt, +} from '@elastic/eui'; +import { useKibana } from '../../../common/lib/kibana'; +import { + RulesSettingsFlappingFormSection, + RulesSettingsFlappingFormSectionProps, + RulesSettingsFlappingTitle, +} from './rules_settings_flapping_form_section'; +import { useGetFlappingSettings } from '../../hooks/use_get_flapping_settings'; +import { useUpdateFlappingSettings } from '../../hooks/use_update_flapping_settings'; +import { CenterJustifiedSpinner } from '../center_justified_spinner'; + +const flappingDescription = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.modal.flappingDetectionDescription', + { + defaultMessage: + 'Alerts that go quickly go between active and recovered are considered flapping. Detecting these changes and minimizing new alert generation can help reduce unwanted noise in your alerting system.', + } +); + +const flappingEnableLabel = i18n.translate( + 'xpack.triggersActionsUI.rulesSettings.modal.enableFlappingLabel', + { + defaultMessage: 'Enabled flapping detection (recommended)', + } +); + +export const RulesSettingsErrorPrompt = memo(() => { + return ( + + + + } + body={ +

    + +

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

    {flappingDescription}

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

    + +

    +
    +
    + + + + {maybeRenderForm()} + + + + + + + + + + + +
    + ); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_get_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_get_flapping_settings.ts new file mode 100644 index 00000000000000..23f4af9e9daa75 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_get_flapping_settings.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useQuery } from '@tanstack/react-query'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { useKibana } from '../../common/lib/kibana'; +import { getFlappingSettings } from '../lib/rule_api'; + +interface UseGetFlappingSettingsProps { + enabled: boolean; + onSuccess: (settings: RulesSettingsFlapping) => void; +} + +export const useGetFlappingSettings = (props: UseGetFlappingSettingsProps) => { + const { enabled, onSuccess } = props; + const { + http, + notifications: { toasts }, + } = useKibana().services; + + const queryFn = () => { + return getFlappingSettings({ http }); + }; + + const onErrorFn = () => { + toasts.addDanger( + i18n.translate('xpack.triggersActionsUI.rulesSettings.modal.getRulesSettingsError', { + defaultMessage: 'Failed to get rules Settings.', + }) + ); + }; + + const { data, isFetching, isError, isLoadingError, isLoading } = useQuery({ + queryKey: ['getFlappingSettings'], + queryFn, + onError: onErrorFn, + onSuccess, + enabled, + refetchOnWindowFocus: false, + retry: false, + }); + + return { + isLoading: isLoading || isFetching, + isError: isError || isLoadingError, + data, + }; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_update_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_update_flapping_settings.ts new file mode 100644 index 00000000000000..d5f978db9d3c04 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_update_flapping_settings.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useMutation } from '@tanstack/react-query'; +import { RulesSettingsFlappingProperties } from '@kbn/alerting-plugin/common'; +import { useKibana } from '../../common/lib/kibana'; +import { updateFlappingSettings } from '../lib/rule_api'; + +interface UseUpdateFlappingSettingsProps { + onClose: () => void; + onSave?: () => void; + setUpdatingRulesSettings?: (isUpdating: boolean) => void; +} + +export const useUpdateFlappingSettings = (props: UseUpdateFlappingSettingsProps) => { + const { onSave, onClose, setUpdatingRulesSettings } = props; + + const { + http, + notifications: { toasts }, + } = useKibana().services; + + const mutationFn = (flappingSettings: RulesSettingsFlappingProperties) => { + return updateFlappingSettings({ http, flappingSettings }); + }; + + return useMutation({ + mutationFn, + onMutate: () => { + onClose(); + setUpdatingRulesSettings?.(true); + }, + onSuccess: () => { + toasts.addSuccess( + i18n.translate('xpack.triggersActionsUI.rulesSettings.modal.updateRulesSettingsSuccess', { + defaultMessage: 'Rules settings updated successfully.', + }) + ); + }, + onError: () => { + toasts.addDanger( + i18n.translate('xpack.triggersActionsUI.rulesSettings.modal.updateRulesSettingsFailure', { + defaultMessage: 'Failed to update rules settings.', + }) + ); + }, + onSettled: () => { + setUpdatingRulesSettings?.(false); + onSave?.(); + }, + }); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/get_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/get_flapping_settings.ts new file mode 100644 index 00000000000000..68947de984fb4c --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/get_flapping_settings.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { HttpSetup } from '@kbn/core/public'; +import { RulesSettingsFlapping } from '@kbn/alerting-plugin/common'; +import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; + +export const getFlappingSettings = ({ http }: { http: HttpSetup }) => { + return http.get( + `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping` + ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts index f1d65768802ec4..74157ac200ce7a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/index.ts @@ -46,3 +46,5 @@ export { runSoon } from './run_soon'; export { bulkDeleteRules } from './bulk_delete'; export { bulkEnableRules } from './bulk_enable'; export { bulkDisableRules } from './bulk_disable'; +export { getFlappingSettings } from './get_flapping_settings'; +export { updateFlappingSettings } from './update_flapping_settings'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_flapping_settings.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_flapping_settings.ts new file mode 100644 index 00000000000000..f38393b591d72c --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_flapping_settings.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { HttpSetup } from '@kbn/core/public'; +import { + RulesSettingsFlapping, + RulesSettingsFlappingProperties, +} from '@kbn/alerting-plugin/common'; +import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; + +export const updateFlappingSettings = ({ + http, + flappingSettings, +}: { + http: HttpSetup; + flappingSettings: RulesSettingsFlappingProperties; +}) => { + let body: string; + try { + body = JSON.stringify(flappingSettings); + } catch (e) { + throw new Error(`Unable to parse flapping settings update params: ${e}`); + } + return http.post( + `${INTERNAL_BASE_ALERTING_API_PATH}/rules/settings/_flapping`, + { + body, + } + ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx index 26bc284f679bc7..d283526c9b55b3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx @@ -4,19 +4,24 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { useReducer } from 'react'; -import { render } from '@testing-library/react'; +import { fireEvent, render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy'; import { AlertsTable } from './alerts_table'; -import { AlertsField, AlertsTableProps } from '../../../types'; +import { AlertsField, AlertsTableProps, BulkActionsState, RowSelectionState } from '../../../types'; import { EuiButtonIcon, EuiFlexItem } from '@elastic/eui'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; +import { BulkActionsContext } from './bulk_actions/context'; +import { bulkActionsReducer } from './bulk_actions/reducer'; jest.mock('@kbn/data-plugin/public'); +jest.mock('@kbn/kibana-react-plugin/public/ui_settings/use_ui_setting', () => ({ + useUiSetting$: jest.fn((value: string) => ['0,0']), +})); const columns = [ { @@ -73,6 +78,15 @@ describe('AlertsTable', () => { jest.fn().mockImplementation((props) => { return `${props.colIndex}:${props.rowIndex}`; }), + useBulkActions: () => [ + { + label: 'Fake Bulk Action', + key: 'fakeBulkAction', + 'data-test-subj': 'fake-bulk-action', + disableOnQuery: false, + onClick: () => {}, + }, + ], }; const tableProps = { @@ -84,7 +98,6 @@ describe('AlertsTable', () => { pageSize: 1, pageSizeOptions: [1, 10, 20, 50, 100], leadingControlColumns: [], - showCheckboxes: false, showExpandToDetails: true, trailingControlColumns: [], alerts, @@ -99,11 +112,29 @@ describe('AlertsTable', () => { browserFields: {}, }; - const AlertsTableWithLocale: React.FunctionComponent = (props) => ( - - - - ); + const defaultBulkActionsState = { + rowSelection: new Map(), + isAllSelected: false, + areAllVisibleRowsSelected: false, + rowCount: 2, + }; + + const AlertsTableWithLocale: React.FunctionComponent< + AlertsTableProps & { initialBulkActionsState?: BulkActionsState } + > = (props) => { + const initialBulkActionsState = useReducer( + bulkActionsReducer, + props.initialBulkActionsState || defaultBulkActionsState + ); + + return ( + + + + + + ); + }; describe('Alerts table UI', () => { it('should support sorting', async () => { @@ -253,6 +284,78 @@ describe('AlertsTable', () => { expect(queryByTestId('expandColumnHeaderLabel')).toBe(null); expect(queryByTestId('expandColumnCellOpenFlyoutButton')).toBe(null); }); + + describe('row loading state on action', () => { + let mockedFn: jest.Mock; + let customTableProps: AlertsTableProps; + + beforeEach(() => { + mockedFn = jest.fn(); + customTableProps = { + ...tableProps, + pageSize: 2, + alertsTableConfiguration: { + ...alertsTableConfiguration, + useActionsColumn: () => { + return { + renderCustomActionsRow: mockedFn.mockReturnValue( + <> + + {}} + size="s" + data-test-subj="testActionColumn" + /> + + + ), + }; + }, + }, + }; + }); + + it('should show the row loader when callback triggered', async () => { + render(); + fireEvent.click((await screen.findAllByTestId('testActionColumn'))[0]); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][3](true); + + expect(await screen.findAllByTestId('row-loader')).toHaveLength(1); + const selectedOptions = await screen.findAllByTestId('dataGridRowCell'); + + // first row, first column + expect(within(selectedOptions[0]).getByLabelText('Loading')).toBeDefined(); + expect(within(selectedOptions[0]).queryByRole('checkbox')).not.toBeInTheDocument(); + + // second row, first column + expect(within(selectedOptions[4]).queryByLabelText('Loading')).not.toBeInTheDocument(); + expect(within(selectedOptions[4]).getByRole('checkbox')).toBeDefined(); + }); + + it('should show the row loader when callback triggered with false', async () => { + const initialBulkActionsState = { + ...defaultBulkActionsState, + rowSelection: new Map([[0, { isLoading: true }]]), + }; + + render( + + ); + fireEvent.click((await screen.findAllByTestId('testActionColumn'))[0]); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][3](false); + + expect(screen.queryByTestId('row-loader')).not.toBeInTheDocument(); + }); + }); }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx index 0055349deb8ffb..288ca1f6259547 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx @@ -17,7 +17,7 @@ import { EuiDataGridStyle, EuiLoadingContent, } from '@elastic/eui'; -import { useSorting, usePagination, useBulkActions } from './hooks'; +import { useSorting, usePagination, useBulkActions, useActionsColumn } from './hooks'; import { AlertsTableProps } from '../../../types'; import { ALERTS_TABLE_CONTROL_COLUMNS_ACTIONS_LABEL, @@ -28,7 +28,7 @@ import './alerts_table.scss'; import { getToolbarVisibility } from './toolbar'; export const ACTIVE_ROW_CLASS = 'alertsTableActiveRow'; -const DEFAULT_ACTIONS_COLUMNS_WIDTH = 75; + const AlertsFlyout = lazy(() => import('./alerts_flyout')); const GridStyles: EuiDataGridStyle = { border: 'none', @@ -50,16 +50,17 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab } = alertsData; const { sortingColumns, onSort } = useSorting(onSortChange, sortingFields); - const { useActionsColumn = () => ({ renderCustomActionsRow: undefined, width: undefined }) } = - props.alertsTableConfiguration; - const { renderCustomActionsRow, width: actionsColumnWidth = DEFAULT_ACTIONS_COLUMNS_WIDTH } = - useActionsColumn(); + const { renderCustomActionsRow, actionsColumnWidth, getSetIsActionLoadingCallback } = + useActionsColumn({ + options: props.alertsTableConfiguration.useActionsColumn, + }); const { isBulkActionsColumnActive, getBulkActionsLeadingControlColumn, bulkActionsState, bulkActions, + setIsBulkActionsLoading, } = useBulkActions({ alerts, useBulkActionsConfig: props.alertsTableConfiguration.useBulkActions, @@ -111,6 +112,8 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab onToggleColumn, onResetColumns, browserFields, + controls: props.controls, + setIsBulkActionsLoading, }); }, [ bulkActionsState, @@ -118,11 +121,13 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab alertsCount, alertsData.alerts, updatedAt, - browserFields, isLoading, visibleColumns, onToggleColumn, onResetColumns, + browserFields, + props.controls, + setIsBulkActionsLoading, ])(); const leadingControlColumns = useMemo(() => { @@ -168,7 +173,12 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab )} {renderCustomActionsRow && alerts[visibleRowIndex] && - renderCustomActionsRow(alerts[visibleRowIndex], handleFlyoutAlert, props.id)} + renderCustomActionsRow( + alerts[visibleRowIndex], + handleFlyoutAlert, + props.id, + getSetIsActionLoadingCallback(visibleRowIndex) + )} ); }, @@ -193,6 +203,7 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab props.showExpandToDetails, renderCustomActionsRow, setFlyoutAlertIndex, + getSetIsActionLoadingCallback, ]); useEffect(() => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx index 107f92434704ff..aee1274a710dd0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx @@ -340,6 +340,33 @@ describe('AlertsTableState', () => { ).toBe(AlertsField.uuid); }); }); + + describe('when persistent controls are set', () => { + let props: AlertsTableStateProps; + beforeEach(() => { + const getMockWithUsePersistentControls = jest.fn().mockImplementation((plugin: string) => { + return { + columns, + sort: DefaultSort, + usePersistentControls: () => ({ right: This is a persistent control }), + }; + }); + const alertsTableConfigurationRegistryWithPersistentControlsMock = { + has: hasMock, + get: getMockWithUsePersistentControls, + } as unknown as TypeRegistry; + props = { + ...tableProps, + alertsTableConfigurationRegistry: + alertsTableConfigurationRegistryWithPersistentControlsMock, + }; + }); + + it('should show persistent controls if set', () => { + const result = render(); + expect(result.getByText('This is a persistent control')).toBeInTheDocument(); + }); + }); }); describe('empty state', () => { @@ -362,5 +389,32 @@ describe('AlertsTableState', () => { const result = render(); expect(result.getByTestId('alertsStateTableEmptyState')).toBeTruthy(); }); + + describe('when persisten controls are set', () => { + let props: AlertsTableStateProps; + beforeEach(() => { + const getMockWithUsePersistentControls = jest.fn().mockImplementation((plugin: string) => { + return { + columns, + sort: DefaultSort, + usePersistentControls: () => ({ right: This is a persistent control }), + }; + }); + const alertsTableConfigurationRegistryWithPersistentControlsMock = { + has: hasMock, + get: getMockWithUsePersistentControls, + } as unknown as TypeRegistry; + props = { + ...tableProps, + alertsTableConfigurationRegistry: + alertsTableConfigurationRegistryWithPersistentControlsMock, + }; + }); + + it('should show persistent controls if set', () => { + const result = render(); + expect(result.getByText('This is a persistent control')).toBeInTheDocument(); + }); + }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx index f75aee03afcf0d..a7f6c91a8f5d76 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx @@ -31,6 +31,7 @@ import { AlertsTableProps, BulkActionsReducerAction, BulkActionsState, + RowSelectionState, } from '../../../types'; import { ALERTS_TABLE_CONF_ERROR_MESSAGE, ALERTS_TABLE_CONF_ERROR_TITLE } from './translations'; import { TypeRegistry } from '../../type_registry'; @@ -66,21 +67,11 @@ export interface AlertsTableStorage { sort: SortCombinations[]; } -const EmptyConfiguration = { +const EmptyConfiguration: AlertsTableConfigurationRegistry = { id: '', casesFeatureId: '', columns: [], sort: [], - externalFlyout: { - header: () => null, - body: () => null, - footer: () => null, - }, - internalFlyout: { - header: () => null, - body: () => null, - footer: () => null, - }, getRenderCellValue: () => () => null, }; @@ -116,6 +107,7 @@ const AlertsTableState = ({ const storage = useRef(new Storage(window.localStorage)); const localAlertsTableConfig = storage.current.get(id) as Partial; + const persistentControls = alertsTableConfiguration?.usePersistentControls?.(); const columnsLocal = localAlertsTableConfig && @@ -187,7 +179,7 @@ const AlertsTableState = ({ }, []); const initialBulkActionsState = useReducer(bulkActionsReducer, { - rowSelection: new Set(), + rowSelection: new Map(), isAllSelected: false, areAllVisibleRowsSelected: false, rowCount: alerts.length, @@ -264,6 +256,7 @@ const AlertsTableState = ({ onResetColumns, onColumnsChange, onChangeVisibleColumns, + controls: persistentControls, }), [ alertsTableConfiguration, @@ -280,6 +273,7 @@ const AlertsTableState = ({ onResetColumns, onColumnsChange, onChangeVisibleColumns, + persistentControls, ] ); @@ -288,7 +282,7 @@ const AlertsTableState = ({ return hasAlertsTableConfiguration ? ( <> - {!isLoading && alertsCount === 0 && } + {!isLoading && alertsCount === 0 && } {(isLoading || isBrowserFieldDataLoading) && ( )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx index 43743d09d381ad..8eab96f14d23e4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/bulk_actions.test.tsx @@ -6,14 +6,18 @@ */ import React, { useReducer } from 'react'; -import { render, within } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { render, screen, within, fireEvent } from '@testing-library/react'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy'; import { BulkActionsContext } from './context'; import { AlertsTable } from '../alerts_table'; -import { AlertsField, AlertsTableProps, BulkActionsState } from '../../../../types'; +import { + AlertsField, + AlertsTableProps, + BulkActionsState, + RowSelectionState, +} from '../../../../types'; import { bulkActionsReducer } from './reducer'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; @@ -121,7 +125,7 @@ describe('AlertsTable.BulkActions', () => { }; const defaultBulkActionsState = { - rowSelection: new Set(), + rowSelection: new Map(), isAllSelected: false, areAllVisibleRowsSelected: false, rowCount: 2, @@ -167,32 +171,33 @@ describe('AlertsTable.BulkActions', () => { describe('and click on select all', () => { it('should check that all rows are selected', async () => { - const { getAllByTestId, getByTestId } = render( - - ); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; + render(); + let bulkActionsCells = screen.getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; expect(bulkActionsCells[0].checked).toBeFalsy(); expect(bulkActionsCells[1].checked).toBeFalsy(); - userEvent.click(getByTestId('bulk-actions-header')); + fireEvent.click(screen.getByTestId('bulk-actions-header')); + bulkActionsCells = screen.getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; expect(bulkActionsCells[0].checked).toBeTruthy(); expect(bulkActionsCells[1].checked).toBeTruthy(); }); - it('should show the right amount of alerts selected', () => { + it('should show the right amount of alerts selected', async () => { const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getByTestId } = render(); - const { getByText } = within(getByTestId('selectedShowBulkActionsButton')); - expect(getByText('Selected 2 alerts')).toBeDefined(); + render(); + expect(await screen.findByText('Selected 2 alerts')).toBeDefined(); }); describe('and clicking on a single row', () => { @@ -203,23 +208,29 @@ describe('AlertsTable.BulkActions', () => { initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - const columnHeader = getByTestId('bulk-actions-header') as HTMLInputElement; - expect(columnHeader.checked).toBeTruthy(); - - userEvent.click(bulkActionsCells[1]); - expect(columnHeader.checked).toBeFalsy(); + render(); + const bulkActionsCells = screen.getAllByTestId( + 'bulk-actions-row-cell' + ) as HTMLInputElement[]; + expect( + (screen.getByTestId('bulk-actions-header') as HTMLInputElement).checked + ).toBeTruthy(); + + fireEvent.click(bulkActionsCells[1]); + expect( + (screen.getByTestId('bulk-actions-header') as HTMLInputElement).checked + ).toBeFalsy(); }); }); describe('and its a page with count of alerts different than page size', () => { - it('should show the right amount of alerts selected', () => { + it('should show the right amount of alerts selected', async () => { const secondPageAlerts = [ { [AlertsField.name]: ['five'], @@ -241,58 +252,64 @@ describe('AlertsTable.BulkActions', () => { initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0]), + rowSelection: new Map([[0, { isLoading: false }]]), }, }; - const { getByTestId, getAllByTestId } = render( - - ); - const { getByText } = within(getByTestId('selectedShowBulkActionsButton')); - expect(getByText('Selected 1 alert')).toBeDefined(); - expect(getAllByTestId('bulk-actions-row-cell').length).toBe(1); + render(); + + expect(await screen.findByText('Selected 1 alert')).toBeDefined(); + expect((await screen.findAllByTestId('bulk-actions-row-cell')).length).toBe(1); }); }); }); describe('and clicking unselect all', () => { - it('should uncheck all rows', () => { + it('should uncheck all rows', async () => { // state after having already clicked on select all before const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeTruthy(); - - userEvent.click(getByTestId('bulk-actions-header')); - - expect(bulkActionsCells[0].checked).toBeFalsy(); - expect(bulkActionsCells[1].checked).toBeFalsy(); + render(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0].checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1].checked + ).toBeTruthy(); + + fireEvent.click(await screen.findByTestId('bulk-actions-header')); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0].checked + ).toBeFalsy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1].checked + ).toBeFalsy(); }); }); describe('and a row is selected', () => { - it('should show the toolbar', () => { - const { queryByTestId, getAllByTestId, getByTestId } = render( - - ); + it('should show the toolbar', async () => { + render(); - expect(queryByTestId('selectedShowBulkActionsButton')).toBeNull(); - expect(queryByTestId('selectAllAlertsButton')).toBeNull(); + expect(screen.queryByTestId('selectedShowBulkActionsButton')).toBeNull(); + expect(screen.queryByTestId('selectAllAlertsButton')).toBeNull(); - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - userEvent.click(bulkActionsCells[0]); + const bulkActionsCells = screen.getAllByTestId( + 'bulk-actions-row-cell' + ) as HTMLInputElement[]; + fireEvent.click(bulkActionsCells[0]); - expect(getByTestId('selectedShowBulkActionsButton')).toBeDefined(); - expect(getByTestId('selectAllAlertsButton')).toBeDefined(); + expect(await screen.findByTestId('selectedShowBulkActionsButton')).toBeDefined(); + expect(await screen.findByTestId('selectAllAlertsButton')).toBeDefined(); }); describe('and the last remaining row is unchecked', () => { @@ -302,7 +319,7 @@ describe('AlertsTable.BulkActions', () => { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, - rowSelection: new Set([0]), + rowSelection: new Map([[0, { isLoading: false }]]), }, }; const { queryByTestId, getAllByTestId, getByTestId } = render( @@ -313,7 +330,7 @@ describe('AlertsTable.BulkActions', () => { expect(getByTestId('selectAllAlertsButton')).toBeDefined(); const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - userEvent.click(bulkActionsCells[0]); + fireEvent.click(bulkActionsCells[0]); expect(queryByTestId('selectAllAlertsButton')).toBeNull(); expect(queryByTestId('selectedShowBulkActionsButton')).toBeNull(); @@ -329,11 +346,10 @@ describe('AlertsTable.BulkActions', () => { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, - rowSelection: new Set([1]), + rowSelection: new Map([[1, { isLoading: false }]]), }, alertsTableConfiguration: { ...alertsTableConfiguration, - useBulkActions: () => [ { label: 'Fake Bulk Action', @@ -346,84 +362,182 @@ describe('AlertsTable.BulkActions', () => { }, }; - const { getByText, getByTestId } = render( - - ); + render(); - userEvent.click(getByTestId('selectedShowBulkActionsButton')); + fireEvent.click(await screen.findByTestId('selectedShowBulkActionsButton')); await waitForEuiPopoverOpen(); - userEvent.click(getByText('Fake Bulk Action')); - expect(mockedFn.mock.calls[0]).toEqual([ - [ - { + fireEvent.click(await screen.findByText('Fake Bulk Action')); + expect(mockedFn.mock.calls[0][0]).toEqual([ + { + _id: 'alert1', + _index: 'idx1', + data: [ + { + field: 'kibana.alert.rule.name', + value: ['three'], + }, + { + field: 'kibana.alert.rule.uuid', + value: ['uuidtwo'], + }, + ], + ecs: { _id: 'alert1', _index: 'idx1', - data: [ - { - field: 'kibana.alert.rule.name', - value: ['three'], - }, + }, + }, + ]); + expect(mockedFn.mock.calls[0][1]).toEqual(false); + expect(mockedFn.mock.calls[0][2]).toBeDefined(); // it's a callback + }); + + describe('and the callback to represent the loading state is executed', () => { + let mockedFn: jest.Mock; + let props: AlertsTableProps; + + beforeEach(() => { + mockedFn = jest.fn(); + props = { + ...tablePropsWithBulkActions, + alertsTableConfiguration: { + ...alertsTableConfiguration, + useBulkActions: () => [ { - field: 'kibana.alert.rule.uuid', - value: ['uuidtwo'], + label: 'Fake Bulk Action', + key: 'fakeBulkAction', + 'data-test-subj': 'fake-bulk-action', + disableOnQuery: false, + onClick: mockedFn, }, ], - ecs: { - _id: 'alert1', - _index: 'idx1', - }, }, - ], - false, - ]); + }; + }); + + it('should show the loading state on each selected row', async () => { + const initialBulkActionsState = { + ...defaultBulkActionsState, + rowSelection: new Map([[1, { isLoading: false }]]), + }; + render( + + ); + fireEvent.click(await screen.findByTestId('selectedShowBulkActionsButton')); + await waitForEuiPopoverOpen(); + + fireEvent.click(await screen.findByText('Fake Bulk Action')); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][2](true); + + expect(await screen.findAllByTestId('row-loader')).toHaveLength(1); + const selectedOptions = await screen.findAllByTestId('dataGridRowCell'); + // first row, first column + expect(within(selectedOptions[0]).queryByLabelText('Loading')).not.toBeInTheDocument(); + expect(within(selectedOptions[0]).getByRole('checkbox')).toBeDefined(); + + // second row, first column + expect(within(selectedOptions[4]).getByLabelText('Loading')).toBeDefined(); + expect(within(selectedOptions[4]).queryByRole('checkbox')).not.toBeInTheDocument(); + }); + + it('should hide the loading state on each selected row', async () => { + const initialBulkActionsState = { + ...defaultBulkActionsState, + rowSelection: new Map([[1, { isLoading: true }]]), + }; + render( + + ); + fireEvent.click(await screen.findByTestId('selectedShowBulkActionsButton')); + await waitForEuiPopoverOpen(); + + fireEvent.click(await screen.findByText('Fake Bulk Action')); + + // the callback given to our clients to run when they want to update the loading state + mockedFn.mock.calls[0][2](false); + + expect(screen.queryByTestId('row-loader')).not.toBeInTheDocument(); + }); }); }); describe('and select all is clicked', () => { - it('should check all the visible rows', () => { + it('should check all the visible rows', async () => { const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, - rowSelection: new Set([0]), + rowSelection: new Map([[0, { isLoading: false }]]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeFalsy(); - userEvent.click(getByTestId('selectAllAlertsButton')); - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeTruthy(); + render(); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeFalsy(); + + fireEvent.click(screen.getByTestId('selectAllAlertsButton')); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeTruthy(); }); describe('and clear the selection is clicked', () => { - it('should turn off the toolbar', () => { + it('should turn off the toolbar', async () => { const props = { ...tablePropsWithBulkActions, initialBulkActionsState: { ...defaultBulkActionsState, areAllVisibleRowsSelected: true, isAllSelected: true, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, }; - const { getAllByTestId, getByTestId } = render( - - ); - - const bulkActionsCells = getAllByTestId('bulk-actions-row-cell') as HTMLInputElement[]; - expect(bulkActionsCells[0].checked).toBeTruthy(); - expect(bulkActionsCells[1].checked).toBeTruthy(); - userEvent.click(getByTestId('selectAllAlertsButton')); - expect(bulkActionsCells[0].checked).toBeFalsy(); - expect(bulkActionsCells[1].checked).toBeFalsy(); + render(); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeTruthy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeTruthy(); + + fireEvent.click(screen.getByTestId('selectAllAlertsButton')); + + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[0] + .checked + ).toBeFalsy(); + expect( + ((await screen.findAllByTestId('bulk-actions-row-cell')) as HTMLInputElement[])[1] + .checked + ).toBeFalsy(); }); }); @@ -436,7 +550,10 @@ describe('AlertsTable.BulkActions', () => { ...defaultBulkActionsState, isAllSelected: true, rowCount: 2, - rowSelection: new Set([0, 1]), + rowSelection: new Map([ + [0, { isLoading: false }], + [1, { isLoading: false }], + ]), }, alertsTableConfiguration: { ...alertsTableConfiguration, @@ -456,51 +573,50 @@ describe('AlertsTable.BulkActions', () => { ); - userEvent.click(getByTestId('selectedShowBulkActionsButton')); + fireEvent.click(getByTestId('selectedShowBulkActionsButton')); await waitForEuiPopoverOpen(); - userEvent.click(getByText('Fake Bulk Action')); - expect(mockedFn.mock.calls[0]).toEqual([ - [ - { + fireEvent.click(getByText('Fake Bulk Action')); + expect(mockedFn.mock.calls[0][0]).toEqual([ + { + _id: 'alert0', + _index: 'idx0', + data: [ + { + field: 'kibana.alert.rule.name', + value: ['one'], + }, + { + field: 'kibana.alert.rule.uuid', + value: ['uuidone'], + }, + ], + ecs: { _id: 'alert0', _index: 'idx0', - data: [ - { - field: 'kibana.alert.rule.name', - value: ['one'], - }, - { - field: 'kibana.alert.rule.uuid', - value: ['uuidone'], - }, - ], - ecs: { - _id: 'alert0', - _index: 'idx0', - }, }, - { + }, + { + _id: 'alert1', + _index: 'idx1', + data: [ + { + field: 'kibana.alert.rule.name', + value: ['three'], + }, + { + field: 'kibana.alert.rule.uuid', + value: ['uuidtwo'], + }, + ], + ecs: { _id: 'alert1', _index: 'idx1', - data: [ - { - field: 'kibana.alert.rule.name', - value: ['three'], - }, - { - field: 'kibana.alert.rule.uuid', - value: ['uuidtwo'], - }, - ], - ecs: { - _id: 'alert1', - _index: 'idx1', - }, }, - ], - true, + }, ]); + expect(mockedFn.mock.calls[0][1]).toEqual(true); + expect(mockedFn.mock.calls[0][2]).toBeDefined(); }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx index 303141d98b247a..75bd47ba1ffad9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/components/row_cell.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiCheckbox } from '@elastic/eui'; +import { EuiCheckbox, EuiLoadingSpinner } from '@elastic/eui'; import React, { ChangeEvent } from 'react'; import { useContext } from 'react'; import { BulkActionsVerbs } from '../../../../../types'; @@ -14,6 +14,11 @@ import { BulkActionsContext } from '../context'; const BulkActionsRowCellComponent = ({ rowIndex }: { rowIndex: number }) => { const [{ rowSelection }, updateSelectedRows] = useContext(BulkActionsContext); const isChecked = rowSelection.has(rowIndex); + const isLoading = isChecked && rowSelection.get(rowIndex)?.isLoading; + + if (isLoading) { + return ; + } return ( void; } // Duplicated just for legacy reasons. Timelines plugin will be removed but @@ -40,9 +41,9 @@ const containerStyles = { display: 'inline-block', position: 'relative' } as con const selectedIdsToTimelineItemMapper = ( alerts: EcsFieldsResponse[], - rowSelection: Set + rowSelection: RowSelection ): TimelineItem[] => { - return Array.from(rowSelection.values()).map((rowIndex: number) => { + return Array.from(rowSelection.keys()).map((rowIndex: number) => { const alert = alerts[rowIndex]; return { _id: alert._id, @@ -61,7 +62,8 @@ const selectedIdsToTimelineItemMapper = ( const useBulkActionsToMenuItemMapper = ( items: BulkActionsConfig[], - alerts: EcsFieldsResponse[] + alerts: EcsFieldsResponse[], + setIsBulkActionsLoading: (loading: boolean) => void ) => { const [{ isAllSelected, rowSelection }] = useContext(BulkActionsContext); @@ -76,25 +78,30 @@ const useBulkActionsToMenuItemMapper = ( disabled={isDisabled} onClick={() => { const selectedAlertIds = selectedIdsToTimelineItemMapper(alerts, rowSelection); - item.onClick(selectedAlertIds, isAllSelected); + item.onClick(selectedAlertIds, isAllSelected, setIsBulkActionsLoading); }} > {isDisabled && item.disabledLabel ? item.disabledLabel : item.label} ); }), - [alerts, isAllSelected, items, rowSelection] + [alerts, isAllSelected, items, rowSelection, setIsBulkActionsLoading] ); return bulkActionsItems; }; -const BulkActionsComponent: React.FC = ({ totalItems, items, alerts }) => { +const BulkActionsComponent: React.FC = ({ + totalItems, + items, + alerts, + setIsBulkActionsLoading, +}) => { const [{ rowSelection, isAllSelected }, updateSelectedRows] = useContext(BulkActionsContext); const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false); const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT); const [showClearSelection, setShowClearSelectiong] = useState(false); - const bulkActionItems = useBulkActionsToMenuItemMapper(items, alerts); + const bulkActionItems = useBulkActionsToMenuItemMapper(items, alerts, setIsBulkActionsLoading); useEffect(() => { setShowClearSelectiong(isAllSelected); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts index cafc06a98bb857..85e88815beace4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/context.ts @@ -6,13 +6,13 @@ */ import { createContext } from 'react'; -import { BulkActionsReducerAction, BulkActionsState } from '../../../../types'; +import { BulkActionsReducerAction, BulkActionsState, RowSelectionState } from '../../../../types'; export const BulkActionsContext = createContext< [BulkActionsState, React.Dispatch] >([ { - rowSelection: new Set(), + rowSelection: new Map(), isAllSelected: false, areAllVisibleRowsSelected: false, rowCount: 0, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts index 4d624dbadfc291..db9c8523fb0afc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/bulk_actions/reducer.ts @@ -7,21 +7,22 @@ import { BulkActionsReducerAction, BulkActionsState, BulkActionsVerbs } from '../../../../types'; -const getAllRowsInPage = (rowCount: number) => new Set(Array.from(Array(rowCount).keys())); +const getAllRowsInPage = (rowCount: number) => + new Map(Array.from(Array(rowCount).keys()).map((idx) => [idx, { isLoading: false }])); export const bulkActionsReducer = ( currentState: BulkActionsState, - { action, rowIndex, rowCount }: BulkActionsReducerAction + { action, rowIndex, rowCount, isLoading = false }: BulkActionsReducerAction ): BulkActionsState => { const { rowSelection, rowCount: currentRowCount } = currentState; const nextState = { ...currentState }; if (action === BulkActionsVerbs.add && rowIndex !== undefined) { - const nextRowSelection = new Set(rowSelection); - nextRowSelection.add(rowIndex); + const nextRowSelection = new Map(rowSelection); + nextRowSelection.set(rowIndex, { isLoading }); nextState.rowSelection = nextRowSelection; } else if (action === BulkActionsVerbs.delete && rowIndex !== undefined) { - const nextRowSelection = new Set(rowSelection); + const nextRowSelection = new Map(rowSelection); nextRowSelection.delete(rowIndex); nextState.rowSelection = nextRowSelection; } else if (action === BulkActionsVerbs.selectCurrentPage) { @@ -30,10 +31,17 @@ export const bulkActionsReducer = ( nextState.rowSelection = getAllRowsInPage(currentRowCount); nextState.isAllSelected = true; } else if (action === BulkActionsVerbs.clear) { - nextState.rowSelection = new Set(); + nextState.rowSelection = new Map(); nextState.isAllSelected = false; } else if (action === BulkActionsVerbs.rowCountUpdate && rowCount !== undefined) { nextState.rowCount = rowCount; + } else if (action === BulkActionsVerbs.updateAllLoadingState) { + const nextRowSelection = new Map( + Array.from(rowSelection.keys()).map((idx: number) => [idx, { isLoading }]) + ); + nextState.rowSelection = nextRowSelection; + } else if (action === BulkActionsVerbs.updateRowLoadingState && rowIndex !== undefined) { + nextState.rowSelection.set(rowIndex, { isLoading }); } nextState.areAllVisibleRowsSelected = nextState.rowSelection.size === nextState.rowCount; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/empty_state.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/empty_state.tsx index 1a8ee2c3e59669..5be40f91afd0bf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/empty_state.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/empty_state.tsx @@ -6,7 +6,15 @@ */ import React from 'react'; -import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiImage, EuiText, EuiTitle } from '@elastic/eui'; +import { + EuiPanel, + EuiFlexGroup, + EuiFlexItem, + EuiImage, + EuiText, + EuiTitle, + EuiDataGridToolBarAdditionalControlsOptions, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import icon from './assets/illustration_product_no_results_magnifying_glass.svg'; @@ -19,9 +27,17 @@ const panelStyle = { maxWidth: 500, }; -export const EmptyState: React.FC<{ height?: keyof typeof heights }> = ({ height = 'tall' }) => { +export const EmptyState: React.FC<{ + height?: keyof typeof heights; + controls?: EuiDataGridToolBarAdditionalControlsOptions; +}> = ({ height = 'tall', controls }) => { return ( + {controls?.right && ( + + {controls.right} + + )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts index 6c89cec2d59dbd..3ce3b5ae5cd9ab 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/index.ts @@ -12,3 +12,4 @@ export type { UseFetchAlerts } from './use_fetch_alerts'; export { useFetchAlerts } from './use_fetch_alerts'; export { DefaultSort } from './constants'; export { useBulkActions } from './use_bulk_actions'; +export { useActionsColumn } from './use_actions_column'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_actions_column.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_actions_column.ts new file mode 100644 index 00000000000000..679fe79b0b0365 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_actions_column.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useContext } from 'react'; +import { UseActionsColumnRegistry, BulkActionsVerbs } from '../../../../types'; +import { BulkActionsContext } from '../bulk_actions/context'; + +const DEFAULT_ACTIONS_COLUMNS_WIDTH = 75; + +interface UseActionsColumnProps { + options?: UseActionsColumnRegistry; +} + +export const useActionsColumn = ({ options }: UseActionsColumnProps) => { + const [, updateBulkActionsState] = useContext(BulkActionsContext); + + const useUserActionsColumn = options + ? options + : () => ({ + renderCustomActionsRow: undefined, + width: undefined, + }); + + const { renderCustomActionsRow, width: actionsColumnWidth = DEFAULT_ACTIONS_COLUMNS_WIDTH } = + useUserActionsColumn(); + + // we save the rowIndex when creating the function to be used by the clients + // so they don't have to manage it + const getSetIsActionLoadingCallback = + (rowIndex: number) => + (isLoading: boolean = true) => { + updateBulkActionsState({ + action: BulkActionsVerbs.updateRowLoadingState, + rowIndex, + isLoading, + }); + }; + + return { + renderCustomActionsRow, + actionsColumnWidth, + getSetIsActionLoadingCallback, + }; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts index 0ea19b93e0915c..a6cdfe8af22493 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts @@ -28,6 +28,7 @@ export interface UseBulkActions { getBulkActionsLeadingControlColumn: GetLeadingControlColumn; bulkActionsState: BulkActionsState; bulkActions: BulkActionsConfig[]; + setIsBulkActionsLoading: (isLoading: boolean) => void; } export function useBulkActions({ @@ -43,10 +44,15 @@ export function useBulkActions({ updateBulkActionsState({ action: BulkActionsVerbs.rowCountUpdate, rowCount: alerts.length }); }, [alerts, updateBulkActionsState]); + const setIsBulkActionsLoading = (isLoading: boolean = true) => { + updateBulkActionsState({ action: BulkActionsVerbs.updateAllLoadingState, isLoading }); + }; + return { isBulkActionsColumnActive, getBulkActionsLeadingControlColumn, bulkActionsState, bulkActions, + setIsBulkActionsLoading, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx index 84e5eb308b4f46..da451195c18a64 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/toolbar/toolbar_visibility.tsx @@ -5,17 +5,33 @@ * 2.0. */ -import { EuiDataGridToolBarVisibilityOptions } from '@elastic/eui'; +import { + EuiDataGridToolBarAdditionalControlsOptions, + EuiDataGridToolBarVisibilityOptions, +} from '@elastic/eui'; import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy'; import React, { lazy, Suspense } from 'react'; import { BrowserFields } from '@kbn/rule-registry-plugin/common'; import { AlertsCount } from './components/alerts_count/alerts_count'; -import { BulkActionsConfig } from '../../../../types'; +import { BulkActionsConfig, RowSelection } from '../../../../types'; import { LastUpdatedAt } from './components/last_updated_at'; import { FieldBrowser } from '../../field_browser'; const BulkActionsToolbar = lazy(() => import('../bulk_actions/components/toolbar')); +const rightControl = ({ + controls, + updatedAt, +}: { + controls?: EuiDataGridToolBarAdditionalControlsOptions; + updatedAt: number; +}) => ( + <> + + {controls?.right} + +); + const getDefaultVisibility = ({ alertsCount, updatedAt, @@ -23,6 +39,7 @@ const getDefaultVisibility = ({ onToggleColumn, onResetColumns, browserFields, + controls, }: { alertsCount: number; updatedAt: number; @@ -30,22 +47,23 @@ const getDefaultVisibility = ({ onToggleColumn: (columnId: string) => void; onResetColumns: () => void; browserFields: BrowserFields; + controls?: EuiDataGridToolBarAdditionalControlsOptions; }): EuiDataGridToolBarVisibilityOptions => { const hasBrowserFields = Object.keys(browserFields).length > 0; const additionalControls = { - right: , + right: rightControl({ controls, updatedAt }), left: { append: ( <> - {hasBrowserFields ? ( + {hasBrowserFields && ( - ) : undefined} + )} ), }, @@ -71,10 +89,12 @@ export const getToolbarVisibility = ({ onToggleColumn, onResetColumns, browserFields, + setIsBulkActionsLoading, + controls, }: { bulkActions: BulkActionsConfig[]; alertsCount: number; - rowSelection: Set; + rowSelection: RowSelection; alerts: EcsFieldsResponse[]; isLoading: boolean; updatedAt: number; @@ -82,6 +102,8 @@ export const getToolbarVisibility = ({ onToggleColumn: (columnId: string) => void; onResetColumns: () => void; browserFields: any; + setIsBulkActionsLoading: (isLoading: boolean) => void; + controls?: EuiDataGridToolBarAdditionalControlsOptions; }): EuiDataGridToolBarVisibilityOptions => { const selectedRowsCount = rowSelection.size; const defaultVisibility = getDefaultVisibility({ @@ -91,6 +113,7 @@ export const getToolbarVisibility = ({ onToggleColumn, onResetColumns, browserFields, + controls, }); const isBulkActionsActive = selectedRowsCount === 0 || selectedRowsCount === undefined || bulkActions.length === 0; @@ -101,13 +124,18 @@ export const getToolbarVisibility = ({ showColumnSelector: false, showSortSelector: false, additionalControls: { - right: , + right: rightControl({ controls, updatedAt }), left: { append: ( <> - + ), diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx index d87a1d4f3a8315..360d54c6e4bf0f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx @@ -97,6 +97,7 @@ import { MULTIPLE_RULE_TITLE, } from '../translations'; import { useBulkOperationToast } from '../../../hooks/use_bulk_operation_toast'; +import { RulesSettingsLink } from '../../../components/rules_setting/rules_settings_link'; import { useRulesListUiState as useUiState } from '../../../hooks/use_rules_list_ui_state'; // Directly lazy import the flyouts because the suspendedComponentWithProps component @@ -614,11 +615,15 @@ export const RulesList = ({ if (!setHeaderActions) return; if (showHeaderWithoutCreateButton) { - setHeaderActions([]); + setHeaderActions([, ]); return; } if (showHeaderWithCreateButton) { - setHeaderActions([, ]); + setHeaderActions([ + , + , + , + ]); return; } setHeaderActions(); diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index bbf0d3f99c5598..146ffbbd8f4207 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -13,7 +13,12 @@ import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; -import type { IconType, EuiFlyoutSize, RecursivePartial } from '@elastic/eui'; +import type { + IconType, + EuiFlyoutSize, + RecursivePartial, + EuiDataGridToolBarAdditionalControlsOptions, +} from '@elastic/eui'; import { EuiDataGridColumn, EuiDataGridControlColumn, EuiDataGridSorting } from '@elastic/eui'; import { HttpSetup } from '@kbn/core/public'; import { KueryNode } from '@kbn/es-query'; @@ -477,6 +482,7 @@ export interface AlertsTableProps { onResetColumns: () => void; onColumnsChange: (columns: EuiDataGridColumn[], visibleColumns: string[]) => void; onChangeVisibleColumns: (newColumns: string[]) => void; + controls?: EuiDataGridToolBarAdditionalControlsOptions; } // TODO We need to create generic type between our plugin, right now we have different one because of the old alerts table @@ -503,9 +509,23 @@ export interface BulkActionsConfig { 'data-test-subj'?: string; disableOnQuery: boolean; disabledLabel?: string; - onClick: (selectedIds: TimelineItem[], isAllSelected: boolean) => void; + onClick: ( + selectedIds: TimelineItem[], + isAllSelected: boolean, + setIsBulkActionsLoading: (isLoading: boolean) => void + ) => void; } +export type UseActionsColumnRegistry = () => { + renderCustomActionsRow: ( + alert: EcsFieldsResponse, + setFlyoutAlert: (data: unknown) => void, + id?: string, + setIsActionLoading?: (isLoading: boolean) => void + ) => JSX.Element; + width?: number; +}; + export type UseBulkActionsRegistry = () => BulkActionsConfig[]; export interface AlertsTableConfigurationRegistry { @@ -519,15 +539,11 @@ export interface AlertsTableConfigurationRegistry { }; sort?: SortCombinations[]; getRenderCellValue?: GetRenderCellValue; - useActionsColumn?: () => { - renderCustomActionsRow: ( - alert: EcsFieldsResponse, - setFlyoutAlert: (data: unknown) => void, - id?: string - ) => JSX.Element; - width?: number; - }; + useActionsColumn?: UseActionsColumnRegistry; useBulkActions?: UseBulkActionsRegistry; + usePersistentControls?: () => { + right?: ReactNode; + }; } export enum BulkActionsVerbs { @@ -537,21 +553,30 @@ export enum BulkActionsVerbs { selectCurrentPage = 'selectCurrentPage', selectAll = 'selectAll', rowCountUpdate = 'rowCountUpdate', + updateRowLoadingState = 'updateRowLoadingState', + updateAllLoadingState = 'updateAllLoadingState', } export interface BulkActionsReducerAction { action: BulkActionsVerbs; rowIndex?: number; rowCount?: number; + isLoading?: boolean; } export interface BulkActionsState { - rowSelection: Set; + rowSelection: Map; isAllSelected: boolean; areAllVisibleRowsSelected: boolean; rowCount: number; } +export type RowSelection = Map; + +export interface RowSelectionState { + isLoading: boolean; +} + export type RuleStatus = 'enabled' | 'disabled' | 'snoozed'; export enum RRuleFrequency { diff --git a/x-pack/test/accessibility/apps/snapshot_and_restore.ts b/x-pack/test/accessibility/apps/snapshot_and_restore.ts index aac70396b461db..c5f0f52c9c9fe7 100644 --- a/x-pack/test/accessibility/apps/snapshot_and_restore.ts +++ b/x-pack/test/accessibility/apps/snapshot_and_restore.ts @@ -106,9 +106,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await a11y.testAppSnapshot(); }); it('submit page four and flyout', async () => { - // Commenting out this snapshot as this is reported. https://github.com/elastic/kibana/issues/134514 await PageObjects.snapshotRestore.submitNewPolicy(); - // await a11y.testAppSnapshot(); + await a11y.testAppSnapshot(); }); it('policy table with data', async () => { await PageObjects.snapshotRestore.closeFlyout(); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts index df9fc34e170145..a645d899980932 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts @@ -26,7 +26,8 @@ export default function createDisableAlertTests({ getService }: FtrProviderConte const supertest = getService('supertest'); const supertestWithoutAuth = getService('supertestWithoutAuth'); - describe('disable', () => { + // Failing: See https://github.com/elastic/kibana/issues/141849 + describe.skip('disable', () => { const objectRemover = new ObjectRemover(supertest); after(() => objectRemover.removeAll()); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/get_flapping_settings.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/get_flapping_settings.ts new file mode 100644 index 00000000000000..80e0a3e4a5986c --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/get_flapping_settings.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; +import { UserAtSpaceScenarios } from '../../../scenarios'; +import { getUrlPrefix } from '../../../../common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function getFlappingSettingsTests({ getService }: FtrProviderContext) { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + describe('getFlappingSettings', () => { + for (const scenario of UserAtSpaceScenarios) { + const { user, space } = scenario; + describe(scenario.id, () => { + it('should handle get flapping settings request appropriately', async () => { + const response = await supertestWithoutAuth + .get(`${getUrlPrefix(space.id)}/internal/alerting/rules/settings/_flapping`) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + case 'space_1_all_with_restricted_fixture at space1': + case 'space_1_all_alerts_none_actions at space1': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Forbidden', + statusCode: 403, + }); + break; + case 'global_read at space1': + case 'superuser at space1': + case 'space_1_all at space1': + expect(response.statusCode).to.eql(200); + expect(response.body.enabled).to.eql(DEFAULT_FLAPPING_SETTINGS.enabled); + expect(response.body.lookBackWindow).to.eql(DEFAULT_FLAPPING_SETTINGS.lookBackWindow); + expect(response.body.statusChangeThreshold).to.eql( + DEFAULT_FLAPPING_SETTINGS.statusChangeThreshold + ); + expect(response.body.createdBy).to.be.a('string'); + expect(response.body.updatedBy).to.be.a('string'); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + }); + } + }); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts index 0dd1ec2531733e..0c6b4f815c9dcb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/index.ts @@ -25,6 +25,8 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./bulk_enable')); loadTestFile(require.resolve('./bulk_disable')); loadTestFile(require.resolve('./clone')); + loadTestFile(require.resolve('./get_flapping_settings')); + loadTestFile(require.resolve('./update_flapping_settings')); }); }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/update_flapping_settings.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/update_flapping_settings.ts new file mode 100644 index 00000000000000..29c82ee5e642ec --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/update_flapping_settings.ts @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; +import { UserAtSpaceScenarios, Superuser } from '../../../scenarios'; +import { getUrlPrefix } from '../../../../common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; + +const resetRulesSettings = (supertestWithoutAuth: any, space: string) => { + return supertestWithoutAuth + .post(`${getUrlPrefix(space)}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send(DEFAULT_FLAPPING_SETTINGS); +}; + +// eslint-disable-next-line import/no-default-export +export default function updateFlappingSettingsTest({ getService }: FtrProviderContext) { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + describe('updateFlappingSettings', () => { + afterEach(async () => { + await resetRulesSettings(supertestWithoutAuth, 'space1'); + await resetRulesSettings(supertestWithoutAuth, 'space2'); + }); + + for (const scenario of UserAtSpaceScenarios) { + const { user, space } = scenario; + describe(scenario.id, () => { + it('should handle update flapping settings request appropriately', async () => { + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(user.username, user.password) + .send({ + enabled: false, + lookBackWindow: 20, + statusChangeThreshold: 20, + }); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'global_read at space1': + case 'space_1_all at space2': + case 'space_1_all_with_restricted_fixture at space1': + case 'space_1_all_alerts_none_actions at space1': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Forbidden', + statusCode: 403, + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + expect(response.statusCode).to.eql(200); + expect(response.body.enabled).to.eql(false); + expect(response.body.lookBackWindow).to.eql(20); + expect(response.body.statusChangeThreshold).to.eql(20); + expect(response.body.createdBy).to.eql(user.username); + expect(response.body.updatedBy).to.eql(user.username); + expect(Date.parse(response.body.createdAt)).to.be.greaterThan(0); + expect(Date.parse(response.body.updatedAt)).to.be.greaterThan(0); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + }); + } + + it('should error if provided with invalid inputs', async () => { + let response = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: true, + lookBackWindow: 200, + statusChangeThreshold: 200, + }) + .expect(400); + + expect(response.body.message).to.eql( + 'Invalid lookBackWindow value, must be between 2 and 20, but got: 200.' + ); + + response = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: true, + lookBackWindow: 20, + statusChangeThreshold: 200, + }) + .expect(400); + + expect(response.body.message).to.eql( + 'Invalid statusChangeThreshold value, must be between 2 and 20, but got: 200.' + ); + + response = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: true, + lookBackWindow: 5, + statusChangeThreshold: 10, + }) + .expect(400); + + expect(response.body.message).to.eql( + 'Invalid values,lookBackWindow (5) must be equal to or greater than statusChangeThreshold (10).' + ); + }); + + describe('updateFlappingSettings for other spaces', () => { + it('should update specific isolated settings depending on space', async () => { + // Update the rules setting in space1 + const postResponse = await supertestWithoutAuth + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .auth(Superuser.username, Superuser.password) + .send({ + enabled: false, + lookBackWindow: 20, + statusChangeThreshold: 20, + }); + + expect(postResponse.statusCode).to.eql(200); + expect(postResponse.body.enabled).to.eql(false); + expect(postResponse.body.lookBackWindow).to.eql(20); + expect(postResponse.body.statusChangeThreshold).to.eql(20); + + // Get the rules settings in space2 + const getResponse = await supertestWithoutAuth + .get(`${getUrlPrefix('space2')}/internal/alerting/rules/settings/_flapping`) + .auth(Superuser.username, Superuser.password); + + expect(getResponse.statusCode).to.eql(200); + expect(getResponse.body.enabled).to.eql(true); + expect(getResponse.body.lookBackWindow).to.eql(20); + expect(getResponse.body.statusChangeThreshold).to.eql(4); + }); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts index bfa4968e2e4b51..9e0bc69a4175b4 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts @@ -5,6 +5,10 @@ * 2.0. */ +import { + READ_FLAPPING_SETTINGS_SUB_FEATURE_ID, + ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID, +} from '@kbn/alerting-plugin/common'; import { ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; import { Space, User } from '../common/types'; @@ -51,6 +55,7 @@ const GlobalRead: User = { alertsFixture: ['read'], alertsRestrictedFixture: ['read'], actionsSimulators: ['read'], + rulesSettings: ['read', READ_FLAPPING_SETTINGS_SUB_FEATURE_ID], }, spaces: ['*'], }, @@ -78,6 +83,7 @@ const Space1All: User = { actions: ['all'], alertsFixture: ['all'], actionsSimulators: ['all'], + rulesSettings: ['all', ALL_FLAPPING_SETTINGS_SUB_FEATURE_ID], }, spaces: ['space1'], }, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/disable.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/disable.ts index d4149c9cf2fb85..dab57143e0b6d8 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/disable.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/disable.ts @@ -26,7 +26,8 @@ export default function createDisableRuleTests({ getService }: FtrProviderContex const retry = getService('retry'); const supertest = getService('supertest'); - describe('disable', () => { + // Failing: See https://github.com/elastic/kibana/issues/141864 + describe.skip('disable', () => { const objectRemover = new ObjectRemover(supertestWithoutAuth); const ruleUtils = new RuleUtils({ space: Spaces.space1, supertestWithoutAuth }); diff --git a/x-pack/test/api_integration/apis/features/features/features.ts b/x-pack/test/api_integration/apis/features/features/features.ts index ce937a5e4618ee..57012451eeb45a 100644 --- a/x-pack/test/api_integration/apis/features/features/features.ts +++ b/x-pack/test/api_integration/apis/features/features/features.ts @@ -118,6 +118,7 @@ export default function ({ getService }: FtrProviderContext) { 'logs', 'maps', 'osquery', + 'rulesSettings', 'uptime', 'siem', 'securitySolutionCases', diff --git a/x-pack/test/api_integration/apis/maps/get_grid_tile.js b/x-pack/test/api_integration/apis/maps/get_grid_tile.js index 6f35ca27cb9263..0b3a454da814c4 100644 --- a/x-pack/test/api_integration/apis/maps/get_grid_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_grid_tile.js @@ -21,7 +21,8 @@ function findFeature(layer, callbackFn) { export default function ({ getService }) { const supertest = getService('supertest'); - describe('getGridTile', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/149068 + describe.skip('getGridTile', () => { const URL = `/api/maps/mvt/getGridTile/3/2/3.pbf\ ?geometryFieldName=geo.coordinates\ &hasLabels=false\ diff --git a/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_empty.json b/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_empty.json index 5272e1a84d3d81..c2fec825e4b289 100644 --- a/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_empty.json +++ b/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_empty.json @@ -12,5 +12,12 @@ "timedOut": false }, "products": {} + }, + "packageErrors": { + "execution": { + "errors": [], + "timedOut": false + }, + "products": {} } } \ No newline at end of file diff --git a/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_es_beats.js b/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_es_beats.js index 55e697e9e5f1ff..fe3bf897fa45d9 100644 --- a/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_es_beats.js +++ b/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_es_beats.js @@ -122,5 +122,12 @@ export const esBeatsResponse = (date = moment().format('YYYY.MM.DD')) => { }, }, }, + packageErrors: { + execution: { + errors: [], + timedOut: false, + }, + products: {}, + }, }; }; diff --git a/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_es_package.js b/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_es_package.js new file mode 100644 index 00000000000000..0caa0ac5c02569 --- /dev/null +++ b/x-pack/test/api_integration/apis/monitoring/_health/fixtures/response_es_package.js @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const esPackageResponse = () => { + return { + monitoredClusters: { + clusters: { + standalone: {}, + }, + execution: { + timedOut: false, + errors: [], + }, + }, + metricbeatErrors: { + execution: { + errors: [], + timedOut: false, + }, + products: {}, + }, + packageErrors: { + execution: { + errors: [], + timedOut: false, + }, + products: { + elasticsearch: { + 'elasticsearch.stack_monitoring.node_stats': [ + { + lastSeen: '2023-01-13T15:11:40.458Z', + message: + 'error making http request: Get "http://localhost:9200/_nodes/_local/stats": dial tcp [::1]:9200: connect: cannot assign requested address', + }, + { + lastSeen: '2023-01-13T15:11:30.458Z', + message: + 'error making http request: Get "http://localhost:9200/_nodes/_local/stats": dial tcp 127.0.0.1:9200: connect: connection refused', + }, + ], + }, + }, + }, + }; +}; diff --git a/x-pack/test/api_integration/apis/monitoring/_health/index.js b/x-pack/test/api_integration/apis/monitoring/_health/index.js index 95e4db48d7f739..ba7ee0378e7a0c 100644 --- a/x-pack/test/api_integration/apis/monitoring/_health/index.js +++ b/x-pack/test/api_integration/apis/monitoring/_health/index.js @@ -12,7 +12,10 @@ import { getLifecycleMethods } from '../data_stream'; import emptyResponse from './fixtures/response_empty.json'; import { esBeatsResponse } from './fixtures/response_es_beats'; +import { esPackageResponse } from './fixtures/response_es_package'; +const ELASTICSEARCH_PACKAGE_ARCHIVE = + 'x-pack/test/api_integration/apis/monitoring/es_archives/_health/elasticsearch_package_error'; const METRICBEAT_ARCHIVE = 'x-pack/test/api_integration/apis/monitoring/es_archives/_health/metricbeat_8'; export default function ({ getService }) { @@ -36,7 +39,7 @@ export default function ({ getService }) { }); }); - describe('with data', () => { + describe('with metricbeat data', () => { const archives = [ 'x-pack/test/api_integration/apis/monitoring/es_archives/_health/monitoring_es_8', 'x-pack/test/api_integration/apis/monitoring/es_archives/_health/monitoring_beats_8', @@ -82,5 +85,32 @@ export default function ({ getService }) { }); }); }); + + describe('with integration package data', () => { + const timeRange = { + min: '2023-01-10T14:46:10.461Z', + max: '2023-01-15T22:30:00.000Z', + }; + const archives = [ELASTICSEARCH_PACKAGE_ARCHIVE]; + const { setup, tearDown } = getLifecycleMethods(getService); + + before('load archive', () => { + return setup(archives); + }); + + after('unload archive', () => { + return tearDown([ELASTICSEARCH_PACKAGE_ARCHIVE]); + }); + + it('returns the state of the monitoring documents', async () => { + const { body } = await supertest + .get(`/api/monitoring/v1/_health?min=${timeRange.min}&max=${timeRange.max}`) + .set('kbn-xsrf', 'xxx') + .expect(200); + + delete body.settings; + expect(body).to.eql(esPackageResponse()); + }); + }); }); } diff --git a/x-pack/test/api_integration/apis/monitoring/es_archives/_health/elasticsearch_package_error/data.json.gz b/x-pack/test/api_integration/apis/monitoring/es_archives/_health/elasticsearch_package_error/data.json.gz new file mode 100644 index 00000000000000..76dba68666e4d3 Binary files /dev/null and b/x-pack/test/api_integration/apis/monitoring/es_archives/_health/elasticsearch_package_error/data.json.gz differ diff --git a/x-pack/test/api_integration/apis/monitoring/es_archives/_health/elasticsearch_package_error/mappings.json b/x-pack/test/api_integration/apis/monitoring/es_archives/_health/elasticsearch_package_error/mappings.json new file mode 100644 index 00000000000000..44f4d4ee042f26 --- /dev/null +++ b/x-pack/test/api_integration/apis/monitoring/es_archives/_health/elasticsearch_package_error/mappings.json @@ -0,0 +1,1440 @@ +{ + "type": "data_stream", + "value": { + "data_stream": "metrics-elasticsearch.stack_monitoring.node_stats-default", + "template": { + "_meta": { + "managed": true, + "managed_by": "fleet", + "package": { + "name": "elasticsearch" + } + }, + "data_stream": { + "allow_custom_routing": false, + "hidden": false + }, + "index_patterns": [ + "metrics-elasticsearch.stack_monitoring.node_stats-*" + ], + "name": "metrics-elasticsearch.stack_monitoring.node_stats", + "priority": 200, + "template": { + "mappings": { + "_meta": { + "managed": true, + "managed_by": "fleet", + "package": { + "name": "elasticsearch" + } + }, + "date_detection": false, + "dynamic": false, + "dynamic_templates": [ + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "cluster_uuid": { + "path": "elasticsearch.cluster.id", + "type": "alias" + }, + "data_stream": { + "properties": { + "dataset": { + "type": "constant_keyword" + }, + "namespace": { + "type": "constant_keyword" + }, + "type": { + "type": "constant_keyword" + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "elasticsearch": { + "properties": { + "cluster": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "node": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "stats": { + "properties": { + "fs": { + "properties": { + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "properties": { + "count": { + "type": "long" + } + } + }, + "read": { + "properties": { + "operations": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "write": { + "properties": { + "operations": { + "properties": { + "count": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "summary": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "free": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "available_in_bytes": { + "type": "long" + }, + "total_in_bytes": { + "type": "long" + } + } + } + } + }, + "indexing_pressure": { + "properties": { + "memory": { + "properties": { + "current": { + "properties": { + "all": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "combined_coordinating_and_primary": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "coordinating": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "primary": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "replica": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "limit_in_bytes": { + "type": "long" + }, + "total": { + "properties": { + "all": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "combined_coordinating_and_primary": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "coordinating": { + "properties": { + "bytes": { + "type": "long" + }, + "rejections": { + "type": "long" + } + } + }, + "primary": { + "properties": { + "bytes": { + "type": "long" + }, + "rejections": { + "type": "long" + } + } + }, + "replica": { + "properties": { + "bytes": { + "type": "long" + }, + "rejections": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "indices": { + "properties": { + "bulk": { + "properties": { + "avg_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "avg_time": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "operations": { + "properties": { + "total": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "total_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total_time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "indexing": { + "properties": { + "index_time": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "index_total": { + "properties": { + "count": { + "type": "long" + } + } + }, + "throttle_time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "query_cache": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "request_cache": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "search": { + "properties": { + "query_time": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "query_total": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "doc_values": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "fixed_bit_set": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "index_writer": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "norms": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "points": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "stored_fields": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "term_vectors": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "terms": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "version_map": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + } + } + }, + "ingest": { + "properties": { + "total": { + "properties": { + "count": { + "type": "long" + }, + "current": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "time_in_millis": { + "type": "long" + } + } + } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" + } + } + } + } + }, + "young": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "mem": { + "properties": { + "heap": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "double" + } + } + } + } + }, + "pools": { + "properties": { + "old": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "survivor": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "young": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpu": { + "properties": { + "cfs": { + "properties": { + "quota": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "stat": { + "properties": { + "elapsed_periods": { + "properties": { + "count": { + "type": "long" + } + } + }, + "time_throttled": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "times_throttled": { + "properties": { + "count": { + "type": "long" + } + } + } + } + } + } + }, + "cpuacct": { + "properties": { + "usage": { + "properties": { + "ns": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "ignore_above": 1024, + "type": "keyword" + }, + "limit": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "usage": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "cpu": { + "properties": { + "load_avg": { + "properties": { + "1m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "pct": { + "type": "double" + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "queue": { + "properties": { + "count": { + "type": "long" + } + } + }, + "rejected": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "get": { + "properties": { + "queue": { + "properties": { + "count": { + "type": "long" + } + } + }, + "rejected": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "index": { + "properties": { + "queue": { + "properties": { + "count": { + "type": "long" + } + } + }, + "rejected": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "search": { + "properties": { + "queue": { + "properties": { + "count": { + "type": "long" + } + } + }, + "rejected": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "write": { + "properties": { + "queue": { + "properties": { + "count": { + "type": "long" + } + } + }, + "rejected": { + "properties": { + "count": { + "type": "long" + } + } + } + } + } + } + } + } + } + } + } + } + }, + "error": { + "properties": { + "message": { + "type": "match_only_text" + } + } + }, + "event": { + "properties": { + "agent_id_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "ingested": { + "format": "strict_date_time_no_millis||strict_date_optional_time||epoch_millis", + "type": "date" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "metricset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "node_stats": { + "properties": { + "fs": { + "properties": { + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "path": "elasticsearch.node.stats.fs.io_stats.total.operations.count", + "type": "alias" + }, + "read_operations": { + "path": "elasticsearch.node.stats.fs.io_stats.total.read.operations.count", + "type": "alias" + }, + "write_operations": { + "path": "elasticsearch.node.stats.fs.io_stats.total.write.operations.count", + "type": "alias" + } + } + } + } + }, + "summary": { + "properties": { + "available": { + "properties": { + "bytes": { + "path": "elasticsearch.node.stats.fs.summary.available.bytes", + "type": "alias" + } + } + }, + "total": { + "properties": { + "bytes": { + "path": "elasticsearch.node.stats.fs.summary.total.bytes", + "type": "alias" + } + } + } + } + }, + "total": { + "properties": { + "available_in_bytes": { + "path": "elasticsearch.node.stats.fs.summary.available.bytes", + "type": "alias" + }, + "total_in_bytes": { + "path": "elasticsearch.node.stats.fs.summary.total.bytes", + "type": "alias" + } + } + } + } + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "path": "elasticsearch.node.stats.indices.docs.count", + "type": "alias" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "path": "elasticsearch.node.stats.indices.fielddata.memory.bytes", + "type": "alias" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "path": "elasticsearch.node.stats.indices.indexing.index_time.ms", + "type": "alias" + }, + "index_total": { + "path": "elasticsearch.node.stats.indices.indexing.index_total.count", + "type": "alias" + }, + "throttle_time_in_millis": { + "path": "elasticsearch.node.stats.indices.indexing.throttle_time.ms", + "type": "alias" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "path": "elasticsearch.node.stats.indices.query_cache.memory.bytes", + "type": "alias" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "path": "elasticsearch.node.stats.indices.request_cache.memory.bytes", + "type": "alias" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "path": "elasticsearch.node.stats.indices.search.query_time.ms", + "type": "alias" + }, + "query_total": { + "path": "elasticsearch.node.stats.indices.search.query_total.count", + "type": "alias" + } + } + }, + "segments": { + "properties": { + "count": { + "path": "elasticsearch.node.stats.indices.segments.count", + "type": "alias" + }, + "doc_values_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.doc_values.memory.bytes", + "type": "alias" + }, + "fixed_bit_set_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.fixed_bit_set.memory.bytes", + "type": "alias" + }, + "index_writer_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.index_writer.memory.bytes", + "type": "alias" + }, + "memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.memory.bytes", + "type": "alias" + }, + "norms_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.norms.memory.bytes", + "type": "alias" + }, + "points_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.points.memory.bytes", + "type": "alias" + }, + "stored_fields_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.stored_fields.memory.bytes", + "type": "alias" + }, + "term_vectors_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.term_vectors.memory.bytes", + "type": "alias" + }, + "terms_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.terms.memory.bytes", + "type": "alias" + }, + "version_map_memory_in_bytes": { + "path": "elasticsearch.node.stats.indices.segments.version_map.memory.bytes", + "type": "alias" + } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "path": "elasticsearch.node.stats.indices.store.size.bytes", + "type": "alias" + } + } + }, + "size_in_bytes": { + "path": "elasticsearch.node.stats.indices.store.size.bytes", + "type": "alias" + } + } + } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection_count": { + "path": "elasticsearch.node.stats.jvm.gc.collectors.old.collection.count", + "type": "alias" + }, + "collection_time_in_millis": { + "path": "elasticsearch.node.stats.jvm.gc.collectors.old.collection.ms", + "type": "alias" + } + } + }, + "young": { + "properties": { + "collection_count": { + "path": "elasticsearch.node.stats.jvm.gc.collectors.young.collection.count", + "type": "alias" + }, + "collection_time_in_millis": { + "path": "elasticsearch.node.stats.jvm.gc.collectors.young.collection.ms", + "type": "alias" + } + } + } + } + } + } + }, + "mem": { + "properties": { + "heap_max_in_bytes": { + "path": "elasticsearch.node.stats.jvm.mem.heap.max.bytes", + "type": "alias" + }, + "heap_used_in_bytes": { + "path": "elasticsearch.node.stats.jvm.mem.heap.used.bytes", + "type": "alias" + }, + "heap_used_percent": { + "path": "elasticsearch.node.stats.jvm.mem.heap.used.pct", + "type": "alias" + } + } + } + } + }, + "node_id": { + "path": "elasticsearch.node.id", + "type": "alias" + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpu": { + "properties": { + "cfs_quota_micros": { + "path": "elasticsearch.node.stats.os.cgroup.cpu.cfs.quota.us", + "type": "alias" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "path": "elasticsearch.node.stats.os.cgroup.cpu.stat.elapsed_periods.count", + "type": "alias" + }, + "number_of_times_throttled": { + "path": "elasticsearch.node.stats.os.cgroup.cpu.stat.times_throttled.count", + "type": "alias" + }, + "time_throttled_nanos": { + "path": "elasticsearch.node.stats.os.cgroup.cpu.stat.time_throttled.ns", + "type": "alias" + } + } + } + } + }, + "cpuacct": { + "properties": { + "usage_nanos": { + "path": "elasticsearch.node.stats.os.cgroup.cpuacct.usage.ns", + "type": "alias" + } + } + }, + "memory": { + "properties": { + "control_group": { + "path": "elasticsearch.node.stats.os.cgroup.memory.control_group", + "type": "alias" + }, + "limit_in_bytes": { + "path": "elasticsearch.node.stats.os.cgroup.memory.limit.bytes", + "type": "alias" + }, + "usage_in_bytes": { + "path": "elasticsearch.node.stats.os.cgroup.memory.usage.bytes", + "type": "alias" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "path": "elasticsearch.node.stats.os.cpu.load_avg.1m", + "type": "alias" + } + } + } + } + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "percent": { + "path": "elasticsearch.node.stats.process.cpu.pct", + "type": "alias" + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "queue": { + "path": "elasticsearch.node.stats.thread_pool.bulk.queue.count", + "type": "alias" + }, + "rejected": { + "path": "elasticsearch.node.stats.thread_pool.bulk.rejected.count", + "type": "alias" + } + } + }, + "get": { + "properties": { + "queue": { + "path": "elasticsearch.node.stats.thread_pool.get.queue.count", + "type": "alias" + }, + "rejected": { + "path": "elasticsearch.node.stats.thread_pool.get.rejected.count", + "type": "alias" + } + } + }, + "index": { + "properties": { + "queue": { + "path": "elasticsearch.node.stats.thread_pool.index.queue.count", + "type": "alias" + }, + "rejected": { + "path": "elasticsearch.node.stats.thread_pool.index.rejected.count", + "type": "alias" + } + } + }, + "search": { + "properties": { + "queue": { + "path": "elasticsearch.node.stats.thread_pool.search.queue.count", + "type": "alias" + }, + "rejected": { + "path": "elasticsearch.node.stats.thread_pool.search.rejected.count", + "type": "alias" + } + } + }, + "write": { + "properties": { + "queue": { + "path": "elasticsearch.node.stats.thread_pool.write.queue.count", + "type": "alias" + }, + "rejected": { + "path": "elasticsearch.node.stats.thread_pool.write.rejected.count", + "type": "alias" + } + } + } + } + } + } + }, + "service": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source_node": { + "properties": { + "name": { + "path": "elasticsearch.node.name", + "type": "alias" + }, + "uuid": { + "path": "elasticsearch.node.id", + "type": "alias" + } + } + }, + "timestamp": { + "path": "@timestamp", + "type": "alias" + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "final_pipeline": ".fleet_final_pipeline-1", + "lifecycle": { + "name": "metrics" + }, + "mapping": { + "total_fields": { + "limit": "10000" + } + }, + "query": { + "default_field": [ + "metricset.name", + "ecs.version", + "event.dataset", + "event.module", + "host.name", + "service.address", + "service.type", + "service.name", + "error.message", + "elasticsearch.node.stats.os.cgroup.memory.control_group", + "elasticsearch.node.stats.os.cgroup.memory.limit.bytes", + "elasticsearch.node.stats.os.cgroup.memory.usage.bytes", + "elasticsearch.node.id", + "elasticsearch.node.name", + "elasticsearch.cluster.name", + "elasticsearch.cluster.id", + "elasticsearch.cluster.state.id" + ] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index 5e2c0dcc257426..ba81febadfece5 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -92,6 +92,14 @@ export default function ({ getService }: FtrProviderContext) { ], filesManagement: ['all', 'read', 'minimal_all', 'minimal_read'], filesSharedImage: ['all', 'read', 'minimal_all', 'minimal_read'], + rulesSettings: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'allFlappingSettings', + 'readFlappingSettings', + ], }, reserved: ['fleet-setup', 'ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'], }; diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 63f0b922a30e09..36cb665c838f4b 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -47,6 +47,7 @@ export default function ({ getService }: FtrProviderContext) { actions: ['all', 'read', 'minimal_all', 'minimal_read'], filesManagement: ['all', 'read', 'minimal_all', 'minimal_read'], filesSharedImage: ['all', 'read', 'minimal_all', 'minimal_read'], + rulesSettings: ['all', 'read', 'minimal_all', 'minimal_read'], }, global: ['all', 'read'], space: ['all', 'read'], @@ -161,6 +162,14 @@ export default function ({ getService }: FtrProviderContext) { 'packs_all', 'packs_read', ], + rulesSettings: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'allFlappingSettings', + 'readFlappingSettings', + ], }, reserved: ['fleet-setup', 'ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'], }; diff --git a/x-pack/test/apm_api_integration/tests/mobile/mobile_http_requests_chart.spec.ts b/x-pack/test/apm_api_integration/tests/mobile/mobile_http_requests_chart.spec.ts new file mode 100644 index 00000000000000..33467b486704f8 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/mobile/mobile_http_requests_chart.spec.ts @@ -0,0 +1,141 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ENVIRONMENT_ALL } from '@kbn/apm-plugin/common/environment_filter_values'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { generateMobileData } from './generate_mobile_data'; + +export default function ApiTest({ getService }: FtrProviderContext) { + const apmApiClient = getService('apmApiClient'); + const registry = getService('registry'); + const synthtraceEsClient = getService('synthtraceEsClient'); + + const start = new Date('2023-01-01T00:00:00.000Z').getTime(); + const end = new Date('2023-01-01T02:00:00.000Z').getTime(); + + async function getHttpRequestsChart({ + environment = ENVIRONMENT_ALL.value, + kuery = '', + serviceName, + transactionType = 'mobile', + offset, + }: { + environment?: string; + kuery?: string; + serviceName: string; + transactionType?: string; + offset?: string; + }) { + return await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/mobile-services/{serviceName}/transactions/charts/http_requests', + params: { + path: { serviceName }, + query: { + environment, + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + kuery, + transactionType, + offset, + }, + }, + }); + } + + registry.when('without data loaded', { config: 'basic', archives: [] }, () => { + describe('when no data', () => { + it('handles empty state', async () => { + const response = await getHttpRequestsChart({ serviceName: 'foo' }); + expect(response.body.currentPeriod).to.eql([]); + expect(response.body.previousPeriod).to.eql([]); + expect(response.status).to.be(200); + }); + }); + }); + + registry.when('with data loaded', { config: 'basic', archives: [] }, () => { + before(async () => { + await generateMobileData({ + synthtraceEsClient, + start, + end, + }); + }); + + after(() => synthtraceEsClient.clean()); + + describe('when data is loaded', () => { + it('returns timeseries for http requests chart', async () => { + const response = await getHttpRequestsChart({ serviceName: 'synth-android', offset: '1d' }); + + expect(response.status).to.be(200); + expect( + response.body.currentPeriod.some( + (item: { x: number; y?: number | null }) => item.y === 0 && item.x + ) + ).to.eql(true); + expect(response.body.previousPeriod[0].y).to.eql(0); + }); + + it('returns only current period timeseries when offset is not available', async () => { + const response = await getHttpRequestsChart({ serviceName: 'synth-android' }); + + expect(response.status).to.be(200); + expect( + response.body.currentPeriod.some( + (item: { x: number; y?: number | null }) => item.y === 0 && item.x + ) + ).to.eql(true); + + expect(response.body.currentPeriod[0].y).to.eql(0); + expect(response.body.previousPeriod).to.eql([]); + }); + }); + + describe('when filters are applied', () => { + it('returns empty state for filters', async () => { + const response = await getHttpRequestsChart({ + serviceName: 'synth-android', + environment: 'production', + kuery: `app.version:"none"`, + }); + + expect(response.status).to.be(200); + expect( + response.body.currentPeriod.every( + (item: { x: number; y?: number | null }) => item.y === 0 + ) + ).to.eql(true); + expect( + response.body.previousPeriod.every( + (item: { x: number; y?: number | null }) => item.y === 0 + ) + ).to.eql(true); + }); + + it('returns the correct values when filter is applied', async () => { + const response = await getHttpRequestsChart({ + serviceName: 'synth-android', + environment: 'production', + kuery: `network.connection.type:"wifi"`, + }); + + const ntcCell = await getHttpRequestsChart({ + serviceName: 'synth-android', + environment: 'production', + kuery: `network.connection.type:"cell"`, + }); + + expect(response.status).to.be(200); + expect(ntcCell.status).to.be(200); + expect(response.body.currentPeriod[0].y).to.eql(0); + expect(ntcCell.body.currentPeriod[0].y).to.eql(0); + }); + }); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/mobile/mobile_sessions_chart.spec.ts b/x-pack/test/apm_api_integration/tests/mobile/mobile_sessions_chart.spec.ts new file mode 100644 index 00000000000000..fe3c9863af8d59 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/mobile/mobile_sessions_chart.spec.ts @@ -0,0 +1,141 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ENVIRONMENT_ALL } from '@kbn/apm-plugin/common/environment_filter_values'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { generateMobileData } from './generate_mobile_data'; + +export default function ApiTest({ getService }: FtrProviderContext) { + const apmApiClient = getService('apmApiClient'); + const registry = getService('registry'); + const synthtraceEsClient = getService('synthtraceEsClient'); + + const start = new Date('2023-01-01T00:00:00.000Z').getTime(); + const end = new Date('2023-01-01T02:00:00.000Z').getTime(); + + async function getSessionsChart({ + environment = ENVIRONMENT_ALL.value, + kuery = '', + serviceName, + transactionType = 'mobile', + offset, + }: { + environment?: string; + kuery?: string; + serviceName: string; + transactionType?: string; + offset?: string; + }) { + return await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/mobile-services/{serviceName}/transactions/charts/sessions', + params: { + path: { serviceName }, + query: { + environment, + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + offset, + kuery, + transactionType, + }, + }, + }); + } + + registry.when('without data loaded', { config: 'basic', archives: [] }, () => { + describe('when no data', () => { + it('handles empty state', async () => { + const response = await getSessionsChart({ serviceName: 'foo' }); + expect(response.body.currentPeriod).to.eql([]); + expect(response.body.previousPeriod).to.eql([]); + expect(response.status).to.be(200); + }); + }); + }); + + registry.when('with data loaded', { config: 'basic', archives: [] }, () => { + before(async () => { + await generateMobileData({ + synthtraceEsClient, + start, + end, + }); + }); + + after(() => synthtraceEsClient.clean()); + + describe('when data is loaded', () => { + it('returns timeseries for sessions chart', async () => { + const response = await getSessionsChart({ serviceName: 'synth-android', offset: '1d' }); + + expect(response.status).to.be(200); + expect( + response.body.currentPeriod.some( + (item: { x: number; y?: number | null }) => item.x && item.y + ) + ).to.eql(true); + + expect(response.body.currentPeriod[0].y).to.eql(8); + expect(response.body.previousPeriod[0].y).to.eql(0); + }); + + it('returns only current period timeseries when offset is not available', async () => { + const response = await getSessionsChart({ serviceName: 'synth-android' }); + + expect(response.status).to.be(200); + expect( + response.body.currentPeriod.some( + (item: { x: number; y?: number | null }) => item.x && item.y + ) + ).to.eql(true); + + expect(response.body.currentPeriod[0].y).to.eql(8); + expect(response.body.previousPeriod).to.eql([]); + }); + }); + + describe('when filters are applied', () => { + it('returns empty state for filters', async () => { + const response = await getSessionsChart({ + serviceName: 'synth-android', + environment: 'production', + kuery: `app.version:"none"`, + }); + + expect( + response.body.currentPeriod.every( + (item: { x: number; y?: number | null }) => item.y === 0 + ) + ).to.eql(true); + expect( + response.body.previousPeriod.every( + (item: { x: number; y?: number | null }) => item.y === 0 + ) + ).to.eql(true); + }); + + it('returns the correct values filter is applied', async () => { + const response = await getSessionsChart({ + serviceName: 'synth-android', + environment: 'production', + kuery: `transaction.name : "Start View - View Appearing"`, + }); + + expect(response.status).to.be(200); + expect( + response.body.currentPeriod.some( + (item: { x: number; y?: number | null }) => item.x && item.y + ) + ).to.eql(true); + + expect(response.body.currentPeriod[0].y).to.eql(2); + expect(response.body.previousPeriod).to.eql([]); + }); + }); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/mobile/mobile_stats.spec.ts b/x-pack/test/apm_api_integration/tests/mobile/mobile_stats.spec.ts index c21839a5058b27..32ff956a70007c 100644 --- a/x-pack/test/apm_api_integration/tests/mobile/mobile_stats.spec.ts +++ b/x-pack/test/apm_api_integration/tests/mobile/mobile_stats.spec.ts @@ -149,7 +149,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); expect(response.sessions.value).to.eql(3); - expect(response.requests.value).to.eql(6); + expect(response.requests.value).to.eql(0); expect(response.crashCount.value).to.eql(0); expect(response.maxLoadTime.value).to.eql(null); }); diff --git a/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts b/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts index 95911cfbb8d8b4..3fe37df612d0d2 100644 --- a/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts +++ b/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts @@ -100,64 +100,60 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); } - registry.when( - 'Service group counts', - { config: 'basic', archives: [] }, - () => { - let synthbeansServiceGroupId: string; - let opbeansServiceGroupId: string; + registry.when('Service group counts', { config: 'basic', archives: [] }, () => { + let synthbeansServiceGroupId: string; + let opbeansServiceGroupId: string; + before(async () => { + const [, { body: synthbeansServiceGroup }, { body: opbeansServiceGroup }] = await Promise.all( + [ + generateData({ start, end, synthtraceEsClient }), + saveServiceGroup({ + groupName: 'synthbeans', + kuery: 'service.name: synth*', + }), + saveServiceGroup({ + groupName: 'opbeans', + kuery: 'service.name: opbeans*', + }), + ] + ); + synthbeansServiceGroupId = synthbeansServiceGroup.id; + opbeansServiceGroupId = opbeansServiceGroup.id; + }); + + after(async () => { + await deleteAllServiceGroups(); + await synthtraceEsClient.clean(); + }); + + it('returns the correct number of services', async () => { + const response = await getServiceGroupCounts(); + expect(response.status).to.be(200); + expect(Object.keys(response.body).length).to.be(2); + expect(response.body[synthbeansServiceGroupId]).to.have.property('services', 2); + expect(response.body[opbeansServiceGroupId]).to.have.property('services', 1); + }); + + describe('with alerts', () => { + let ruleId: string; before(async () => { - const [, { body: synthbeansServiceGroup }, { body: opbeansServiceGroup }] = - await Promise.all([ - generateData({ start, end, synthtraceEsClient }), - saveServiceGroup({ - groupName: 'synthbeans', - kuery: 'service.name: synth*', - }), - saveServiceGroup({ - groupName: 'opbeans', - kuery: 'service.name: opbeans*', - }), - ]); - synthbeansServiceGroupId = synthbeansServiceGroup.id; - opbeansServiceGroupId = opbeansServiceGroup.id; + const { body: createdRule } = await createRule(); + ruleId = createdRule.id; + await waitForActiveAlert({ ruleId, esClient, log }); }); after(async () => { - await deleteAllServiceGroups(); - await synthtraceEsClient.clean(); + await supertest.delete(`/api/alerting/rule/${ruleId}`).set('kbn-xsrf', 'true'); + await esDeleteAllIndices('.alerts*'); }); - it('returns the correct number of services', async () => { + it('returns the correct number of alerts', async () => { const response = await getServiceGroupCounts(); expect(response.status).to.be(200); expect(Object.keys(response.body).length).to.be(2); - expect(response.body[synthbeansServiceGroupId]).to.have.property('services', 2); - expect(response.body[opbeansServiceGroupId]).to.have.property('services', 1); + expect(response.body[synthbeansServiceGroupId]).to.have.property('alerts', 1); + expect(response.body[opbeansServiceGroupId]).to.have.property('alerts', 0); }); - - describe('with alerts', () => { - let ruleId: string; - before(async () => { - const { body: createdRule } = await createRule(); - ruleId = createdRule.id; - await waitForActiveAlert({ ruleId, esClient, log }); - }); - - after(async () => { - await supertest.delete(`/api/alerting/rule/${ruleId}`).set('kbn-xsrf', 'true'); - await esDeleteAllIndices('.alerts*'); - }); - - it('returns the correct number of alerts', async () => { - const response = await getServiceGroupCounts(); - expect(response.status).to.be(200); - expect(Object.keys(response.body).length).to.be(2); - expect(response.body[synthbeansServiceGroupId]).to.have.property('alerts', 1); - expect(response.body[opbeansServiceGroupId]).to.have.property('alerts', 0); - }); - }); - }, - true // skipped Failing: See https://github.com/elastic/kibana/issues/147473 - ); + }); + }); } diff --git a/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts b/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts index d914d86e7689af..3644c37b7a945f 100644 --- a/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts +++ b/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts @@ -383,8 +383,7 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte expect(await waitFor(hasBeenAppliedByAgent)).to.be(true); }); }); - }, - true + } ); registry.when('Agent configurations through fleet', { config: 'basic', archives: [] }, () => { @@ -530,12 +529,12 @@ async function expectStatusCode( try { response = await fn(); } catch (e) { - if (e && e.response && e.response.status) { - if (e.response.status === statusCode) { + if (e && e.res && e.res.status) { + if (e.res.status === statusCode) { return; } throw new Error( - `Expected a [${statusCode}] response, got [${e.response.status}]: ${inspect(e.response)}` + `Expected a [${statusCode}] response, got [${e.res.status}]: ${inspect(e.res)}` ); } else { throw new Error( diff --git a/x-pack/test/cases_api_integration/common/lib/connectors.ts b/x-pack/test/cases_api_integration/common/lib/connectors.ts new file mode 100644 index 00000000000000..4948495ddf665e --- /dev/null +++ b/x-pack/test/cases_api_integration/common/lib/connectors.ts @@ -0,0 +1,324 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import getPort from 'get-port'; +import http from 'http'; + +import type SuperTest from 'supertest'; +import { + CASES_INTERNAL_URL, + CASE_CONFIGURE_CONNECTORS_URL, +} from '@kbn/cases-plugin/common/constants'; +import { + CasesConfigureResponse, + CaseConnector, + ConnectorTypes, + CasePostRequest, + CaseResponse, + GetCaseConnectorsResponse, +} from '@kbn/cases-plugin/common/api'; +import { ActionResult, FindActionResult } from '@kbn/actions-plugin/server/types'; +import { User } from './authentication/types'; +import { superUser } from './authentication/users'; +import { getPostCaseRequest } from './mock'; +import { ObjectRemover as ActionsRemover } from '../../../alerting_api_integration/common/lib'; +import { getServiceNowServer } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/plugin'; +import { RecordingServiceNowSimulator } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/servicenow_simulation'; +import { + createConfiguration, + getConfigurationRequest, + createCase, + getSpaceUrlPrefix, +} from './utils'; + +export const getResilientConnector = () => ({ + name: 'Resilient Connector', + connector_type_id: '.resilient', + secrets: { + apiKeyId: 'id', + apiKeySecret: 'secret', + }, + config: { + apiUrl: 'http://some.non.existent.com', + orgId: 'pkey', + }, +}); + +export const getWebhookConnector = () => ({ + name: 'A generic Webhook action', + connector_type_id: '.webhook', + secrets: { + user: 'user', + password: 'password', + }, + config: { + headers: { + 'Content-Type': 'text/plain', + }, + url: 'http://some.non.existent.com', + }, +}); + +export const getEmailConnector = () => ({ + name: 'An email action', + connector_type_id: '.email', + config: { + service: '__json', + from: 'bob@example.com', + }, + secrets: { + user: 'bob', + password: 'supersecret', + }, +}); + +export const getServiceNowOAuthConnector = () => ({ + name: 'ServiceNow OAuth Connector', + connector_type_id: '.servicenow', + secrets: { + clientSecret: 'xyz', + privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', + }, + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', + }, +}); + +export const getJiraConnector = () => ({ + name: 'Jira Connector', + connector_type_id: '.jira', + secrets: { + email: 'elastic@elastic.co', + apiToken: 'token', + }, + config: { + apiUrl: 'http://some.non.existent.com', + projectKey: 'pkey', + }, +}); + +export const getCasesWebhookConnector = () => ({ + name: 'Cases Webhook Connector', + connector_type_id: '.cases-webhook', + secrets: { + user: 'user', + password: 'pass', + }, + config: { + createCommentJson: '{"body":{{{case.comment}}}}', + createCommentMethod: 'post', + createCommentUrl: 'http://some.non.existent.com/{{{external.system.id}}}/comment', + createIncidentJson: + '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', + createIncidentMethod: 'post', + createIncidentResponseKey: 'id', + createIncidentUrl: 'http://some.non.existent.com/', + getIncidentResponseExternalTitleKey: 'key', + hasAuth: true, + headers: { [`content-type`]: 'application/json' }, + viewIncidentUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', + getIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', + updateIncidentJson: + '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', + updateIncidentMethod: 'put', + updateIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', + }, +}); + +export const getServiceNowSIRConnector = () => ({ + name: 'ServiceNow SIR Connector', + connector_type_id: '.servicenow-sir', + secrets: { + username: 'admin', + password: 'password', + }, + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + }, +}); + +export const getServiceNowConnector = () => ({ + name: 'ServiceNow Connector', + connector_type_id: '.servicenow', + secrets: { + username: 'admin', + password: 'password', + }, + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + }, +}); + +export const getRecordingServiceNowSimulatorServer = async (): Promise<{ + server: RecordingServiceNowSimulator; + url: string; +}> => { + const simulator = await RecordingServiceNowSimulator.start(); + const url = await startServiceNowSimulatorListening(simulator.server); + + return { server: simulator, url }; +}; + +const startServiceNowSimulatorListening = async (server: http.Server) => { + const port = await getPort({ port: getPort.makeRange(9000, 9100) }); + if (!server.listening) { + server.listen(port); + } + const url = `http://localhost:${port}`; + + return url; +}; + +export const getServiceNowSimulationServer = async (): Promise<{ + server: http.Server; + url: string; +}> => { + const server = await getServiceNowServer(); + const url = await startServiceNowSimulatorListening(server); + + return { server, url }; +}; + +export const getCaseConnectors = async ({ + supertest, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: connectors } = await supertest + .get(`${getSpaceUrlPrefix(auth.space)}${CASE_CONFIGURE_CONNECTORS_URL}/_find`) + .auth(auth.user.username, auth.user.password) + .expect(expectedHttpCode); + + return connectors; +}; + +export const createCaseWithConnector = async ({ + supertest, + configureReq = {}, + serviceNowSimulatorURL, + actionsRemover, + auth = { user: superUser, space: null }, + createCaseReq = getPostCaseRequest(), + headers = {}, +}: { + supertest: SuperTest.SuperTest; + serviceNowSimulatorURL: string; + actionsRemover: ActionsRemover; + configureReq?: Record; + auth?: { user: User; space: string | null } | null; + createCaseReq?: CasePostRequest; + headers?: Record; +}): Promise<{ + postedCase: CaseResponse; + connector: CreateConnectorResponse; + configuration: CasesConfigureResponse; +}> => { + const connector = await createConnector({ + supertest, + req: { + ...getServiceNowConnector(), + config: { apiUrl: serviceNowSimulatorURL }, + }, + auth: auth ?? undefined, + }); + + actionsRemover.add(auth?.space ?? 'default', connector.id, 'action', 'actions'); + + const [configuration, postedCase] = await Promise.all([ + createConfiguration( + supertest, + { + ...getConfigurationRequest({ + id: connector.id, + name: connector.name, + type: connector.connector_type_id as ConnectorTypes, + }), + ...configureReq, + }, + 200, + auth ?? undefined + ), + createCase( + supertest, + { + ...createCaseReq, + connector: { + id: connector.id, + name: connector.name, + type: connector.connector_type_id, + fields: { + urgency: '2', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + } as CaseConnector, + }, + 200, + auth, + headers + ), + ]); + + return { postedCase, connector, configuration }; +}; + +export type CreateConnectorResponse = Omit & { + connector_type_id: string; +}; + +export const createConnector = async ({ + supertest, + req, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + req: Record; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: connector } = await supertest + .post(`${getSpaceUrlPrefix(auth.space)}/api/actions/connector`) + .auth(auth.user.username, auth.user.password) + .set('kbn-xsrf', 'true') + .send(req) + .expect(expectedHttpCode); + + return connector; +}; + +export const getConnectors = async ({ + supertest, + caseId, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + caseId: string; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: connectors } = await supertest + .get(`${getSpaceUrlPrefix(auth.space)}${CASES_INTERNAL_URL}/${caseId}/_connectors`) + .auth(auth.user.username, auth.user.password) + .expect(expectedHttpCode); + + return connectors; +}; diff --git a/x-pack/test/cases_api_integration/common/lib/utils.ts b/x-pack/test/cases_api_integration/common/lib/utils.ts index 1af320a5d5c975..58dc5674315467 100644 --- a/x-pack/test/cases_api_integration/common/lib/utils.ts +++ b/x-pack/test/cases_api_integration/common/lib/utils.ts @@ -6,8 +6,6 @@ */ import { omit } from 'lodash'; -import getPort from 'get-port'; -import http from 'http'; import expect from '@kbn/expect'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -19,7 +17,6 @@ import type SuperTest from 'supertest'; import { CASES_INTERNAL_URL, CASES_URL, - CASE_CONFIGURE_CONNECTORS_URL, CASE_CONFIGURE_URL, CASE_REPORTERS_URL, CASE_STATUS_URL, @@ -57,16 +54,13 @@ import { } from '@kbn/cases-plugin/common/api'; import { getCaseUserActionUrl } from '@kbn/cases-plugin/common/api/helpers'; import { SignalHit } from '@kbn/security-solution-plugin/server/lib/detection_engine/signals/types'; -import { ActionResult, FindActionResult } from '@kbn/actions-plugin/server/types'; +import { ActionResult } from '@kbn/actions-plugin/server/types'; import { ESCasesConfigureAttributes } from '@kbn/cases-plugin/server/services/configure/types'; import { ESCaseAttributes } from '@kbn/cases-plugin/server/services/cases/types'; import type { SavedObjectsRawDocSource } from '@kbn/core/server'; import { User } from './authentication/types'; import { superUser } from './authentication/users'; -import { getPostCaseRequest, postCaseReq } from './mock'; -import { ObjectRemover as ActionsRemover } from '../../../alerting_api_integration/common/lib'; -import { getServiceNowServer } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/plugin'; -import { RecordingServiceNowSimulator } from '../../../alerting_api_integration/common/plugins/actions_simulators/server/servicenow_simulation'; +import { postCaseReq } from './mock'; function toArray(input: T | T[]): T[] { if (Array.isArray(input)) { @@ -209,77 +203,6 @@ export const getConfigurationOutput = ( }; }; -export const getServiceNowConnector = () => ({ - name: 'ServiceNow Connector', - connector_type_id: '.servicenow', - secrets: { - username: 'admin', - password: 'password', - }, - config: { - apiUrl: 'http://some.non.existent.com', - usesTableApi: false, - }, -}); - -export const getServiceNowOAuthConnector = () => ({ - name: 'ServiceNow OAuth Connector', - connector_type_id: '.servicenow', - secrets: { - clientSecret: 'xyz', - privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', - }, - config: { - apiUrl: 'http://some.non.existent.com', - usesTableApi: false, - isOAuth: true, - clientId: 'abc', - userIdentifierValue: 'elastic', - jwtKeyId: 'def', - }, -}); - -export const getJiraConnector = () => ({ - name: 'Jira Connector', - connector_type_id: '.jira', - secrets: { - email: 'elastic@elastic.co', - apiToken: 'token', - }, - config: { - apiUrl: 'http://some.non.existent.com', - projectKey: 'pkey', - }, -}); - -export const getCasesWebhookConnector = () => ({ - name: 'Cases Webhook Connector', - connector_type_id: '.cases-webhook', - secrets: { - user: 'user', - password: 'pass', - }, - config: { - createCommentJson: '{"body":{{{case.comment}}}}', - createCommentMethod: 'post', - createCommentUrl: 'http://some.non.existent.com/{{{external.system.id}}}/comment', - createIncidentJson: - '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', - createIncidentMethod: 'post', - createIncidentResponseKey: 'id', - createIncidentUrl: 'http://some.non.existent.com/', - getIncidentResponseExternalTitleKey: 'key', - hasAuth: true, - headers: { [`content-type`]: 'application/json' }, - viewIncidentUrl: 'http://some.non.existent.com/browse/{{{external.system.title}}}', - getIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', - updateIncidentJson: - '{"fields":{"summary":{{{case.title}}},"description":{{{case.description}}},"project":{"key":"ROC"},"issuetype":{"id":"10024"}}}', - updateIncidentMethod: 'put', - updateIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', - }, -}); - export const getMappings = () => [ { source: 'title', @@ -298,60 +221,6 @@ export const getMappings = () => [ }, ]; -export const getResilientConnector = () => ({ - name: 'Resilient Connector', - connector_type_id: '.resilient', - secrets: { - apiKeyId: 'id', - apiKeySecret: 'secret', - }, - config: { - apiUrl: 'http://some.non.existent.com', - orgId: 'pkey', - }, -}); - -export const getServiceNowSIRConnector = () => ({ - name: 'ServiceNow SIR Connector', - connector_type_id: '.servicenow-sir', - secrets: { - username: 'admin', - password: 'password', - }, - config: { - apiUrl: 'http://some.non.existent.com', - usesTableApi: false, - }, -}); - -export const getWebhookConnector = () => ({ - name: 'A generic Webhook action', - connector_type_id: '.webhook', - secrets: { - user: 'user', - password: 'password', - }, - config: { - headers: { - 'Content-Type': 'text/plain', - }, - url: 'http://some.non.existent.com', - }, -}); - -export const getEmailConnector = () => ({ - name: 'An email action', - connector_type_id: '.email', - config: { - service: '__json', - from: 'bob@example.com', - }, - secrets: { - user: 'bob', - password: 'supersecret', - }, -}); - interface CommonSavedObjectAttributes { id?: string | null; created_at?: string | null; @@ -589,76 +458,6 @@ export const getCaseSavedObjectsFromES = async ({ es }: { es: Client }) => { return configure; }; -export const createCaseWithConnector = async ({ - supertest, - configureReq = {}, - serviceNowSimulatorURL, - actionsRemover, - auth = { user: superUser, space: null }, - createCaseReq = getPostCaseRequest(), - headers = {}, -}: { - supertest: SuperTest.SuperTest; - serviceNowSimulatorURL: string; - actionsRemover: ActionsRemover; - configureReq?: Record; - auth?: { user: User; space: string | null } | null; - createCaseReq?: CasePostRequest; - headers?: Record; -}): Promise<{ - postedCase: CaseResponse; - connector: CreateConnectorResponse; - configuration: CasesConfigureResponse; -}> => { - const connector = await createConnector({ - supertest, - req: { - ...getServiceNowConnector(), - config: { apiUrl: serviceNowSimulatorURL }, - }, - auth: auth ?? undefined, - }); - - actionsRemover.add(auth?.space ?? 'default', connector.id, 'action', 'actions'); - const configuration = await createConfiguration( - supertest, - { - ...getConfigurationRequest({ - id: connector.id, - name: connector.name, - type: connector.connector_type_id as ConnectorTypes, - }), - ...configureReq, - }, - 200, - auth ?? undefined - ); - - const postedCase = await createCase( - supertest, - { - ...createCaseReq, - connector: { - id: connector.id, - name: connector.name, - type: connector.connector_type_id, - fields: { - urgency: '2', - impact: '2', - severity: '2', - category: 'software', - subcategory: 'os', - }, - } as CaseConnector, - }, - 200, - auth, - headers - ); - - return { postedCase, connector, configuration }; -}; - export const createCase = async ( supertest: SuperTest.SuperTest, params: CasePostRequest, @@ -979,44 +778,6 @@ export type CreateConnectorResponse = Omit & { connector_type_id: string; }; -export const createConnector = async ({ - supertest, - req, - expectedHttpCode = 200, - auth = { user: superUser, space: null }, -}: { - supertest: SuperTest.SuperTest; - req: Record; - expectedHttpCode?: number; - auth?: { user: User; space: string | null }; -}): Promise => { - const { body: connector } = await supertest - .post(`${getSpaceUrlPrefix(auth.space)}/api/actions/connector`) - .auth(auth.user.username, auth.user.password) - .set('kbn-xsrf', 'true') - .send(req) - .expect(expectedHttpCode); - - return connector; -}; - -export const getCaseConnectors = async ({ - supertest, - expectedHttpCode = 200, - auth = { user: superUser, space: null }, -}: { - supertest: SuperTest.SuperTest; - expectedHttpCode?: number; - auth?: { user: User; space: string | null }; -}): Promise => { - const { body: connectors } = await supertest - .get(`${getSpaceUrlPrefix(auth.space)}${CASE_CONFIGURE_CONNECTORS_URL}/_find`) - .auth(auth.user.username, auth.user.password) - .expect(expectedHttpCode); - - return connectors; -}; - export const updateConfiguration = async ( supertest: SuperTest.SuperTest, id: string, @@ -1265,36 +1026,6 @@ export const getAlertsAttachedToCase = async ({ return theCase; }; -export const getRecordingServiceNowSimulatorServer = async (): Promise<{ - server: RecordingServiceNowSimulator; - url: string; -}> => { - const simulator = await RecordingServiceNowSimulator.start(); - const url = await startServiceNowSimulatorListening(simulator.server); - - return { server: simulator, url }; -}; - -const startServiceNowSimulatorListening = async (server: http.Server) => { - const port = await getPort({ port: getPort.makeRange(9000, 9100) }); - if (!server.listening) { - server.listen(port); - } - const url = `http://localhost:${port}`; - - return url; -}; - -export const getServiceNowSimulationServer = async (): Promise<{ - server: http.Server; - url: string; -}> => { - const server = await getServiceNowServer(); - const url = await startServiceNowSimulatorListening(server); - - return { server, url }; -}; - /** * Extracts the warning value a warning header that is formatted according to RFC 7234. * For example for the string 299 Kibana-8.1.0 "Deprecation endpoint", the return value is Deprecation endpoint. diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts index a78f70710dbad6..536863dc95d0ab 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/cases/push_case.ts @@ -15,13 +15,13 @@ import { deleteComments, deleteConfiguration, getConfigurationRequest, - getServiceNowConnector, - createConnector, createConfiguration, createCase, pushCase, } from '../../../../common/lib/utils'; +import { getServiceNowConnector, createConnector } from '../../../../common/lib/connectors'; + // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts index 57854075c20fb4..f91826f431d868 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; -import { getCaseConnectors } from '../../../../common/lib/utils'; +import { getCaseConnectors } from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts index fe039eed5a0238..715029434324ab 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/no_public_base_url/push.ts @@ -18,13 +18,11 @@ import { import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../alerting_api_integration/common/lib'; +import { pushCase, deleteAllCaseItems, bulkCreateAttachments } from '../../../common/lib/utils'; import { - pushCase, - deleteAllCaseItems, createCaseWithConnector, getRecordingServiceNowSimulatorServer, - bulkCreateAttachments, -} from '../../../common/lib/utils'; +} from '../../../common/lib/connectors'; import { RecordingServiceNowSimulator } from '../../../../alerting_api_integration/common/plugins/actions_simulators/server/servicenow_simulation'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts index e1051a3b5de12c..a50c11ff414079 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/push_case.ts @@ -34,20 +34,22 @@ import { updateCase, deleteAllCaseItems, superUserSpace1Auth, - createCaseWithConnector, - createConnector, - getServiceNowConnector, getConnectorMappingsFromES, getCase, - getServiceNowSimulationServer, createConfiguration, getSignalsWithES, delay, calculateDuration, - getRecordingServiceNowSimulatorServer, getComment, bulkCreateAttachments, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createCaseWithConnector, + getRecordingServiceNowSimulatorServer, + getServiceNowSimulationServer, + createConnector, +} from '../../../../common/lib/connectors'; import { globalRead, noKibanaPrivileges, diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts index 77ac223a07592f..81a6253076d2eb 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/user_actions/get_all_user_actions.ts @@ -13,17 +13,19 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { defaultUser, getPostCaseRequest } from '../../../../../common/lib/mock'; import { createCase, - createCaseWithConnector, deleteCasesByESQuery, deleteCasesUserActions, deleteComments, deleteConfiguration, getCaseUserActions, - getServiceNowSimulationServer, pushCase, updateCase, updateConfiguration, } from '../../../../../common/lib/utils'; +import { + createCaseWithConnector, + getServiceNowSimulationServer, +} from '../../../../../common/lib/connectors'; import { ObjectRemover as ActionsRemover } from '../../../../../../alerting_api_integration/common/lib'; import { setupSuperUserProfile } from '../../../../../common/lib/user_profiles'; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts index 3809806d9ec119..8b29db8e0f9b62 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_configure.ts @@ -12,15 +12,17 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { - getServiceNowConnector, - createConnector, createConfiguration, getConfiguration, getConfigurationRequest, removeServerGeneratedPropertiesFromSavedObject, getConfigurationOutput, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + getServiceNowSimulationServer, + createConnector, +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts index 5ed6163a015433..32dc2173b4ec75 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts @@ -11,15 +11,15 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { getServiceNowConnector, + getServiceNowSIRConnector, getServiceNowOAuthConnector, getJiraConnector, getResilientConnector, createConnector, - getServiceNowSIRConnector, getEmailConnector, getCaseConnectors, getCasesWebhookConnector, -} from '../../../../common/lib/utils'; +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts index 6fd90d0620fd2b..0bec95a51b7451 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/patch_configure.ts @@ -18,10 +18,12 @@ import { deleteConfiguration, createConfiguration, updateConfiguration, +} from '../../../../common/lib/utils'; +import { getServiceNowConnector, createConnector, getServiceNowSimulationServer, -} from '../../../../common/lib/utils'; +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts index f9df2610dca294..561008b71bd14d 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/post_configure.ts @@ -17,10 +17,12 @@ import { getConfigurationOutput, deleteConfiguration, createConfiguration, - createConnector, +} from '../../../../common/lib/utils'; +import { getServiceNowConnector, getServiceNowSimulationServer, -} from '../../../../common/lib/utils'; + createConnector, +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts index becac642b1c2e2..beb0c8e64045c5 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts @@ -38,6 +38,7 @@ export default ({ loadTestFile, getService }: FtrProviderContext): void => { // Internal routes loadTestFile(require.resolve('./internal/suggest_user_profiles')); + loadTestFile(require.resolve('./internal/get_connectors')); // Common loadTestFile(require.resolve('../common')); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/get_connectors.ts new file mode 100644 index 00000000000000..bb4d9e8b99b8c5 --- /dev/null +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/get_connectors.ts @@ -0,0 +1,676 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import http from 'http'; +import expect from '@kbn/expect'; + +import { ActionTypes, CaseSeverity, ConnectorTypes } from '@kbn/cases-plugin/common/api'; +import { + globalRead, + noKibanaPrivileges, + obsOnly, + obsOnlyRead, + obsSec, + obsSecRead, + secOnly, + secOnlyRead, + superUser, +} from '../../../../common/lib/authentication/users'; +import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { + createCase, + createComment, + deleteAllCaseItems, + getCaseUserActions, + pushCase, + updateCase, +} from '../../../../common/lib/utils'; +import { getPostCaseRequest, postCommentUserReq } from '../../../../common/lib/mock'; +import { + createCaseWithConnector, + createConnector, + getConnectors, + getJiraConnector, + getServiceNowConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + const actionsRemover = new ActionsRemover(supertest); + + describe('get_connectors', () => { + let serviceNowSimulatorURL: string = ''; + let serviceNowServer: http.Server; + + before(async () => { + const { server, url } = await getServiceNowSimulationServer(); + serviceNowServer = server; + serviceNowSimulatorURL = url; + }); + + afterEach(async () => { + await deleteAllCaseItems(es); + await actionsRemover.removeAll(); + }); + + after(async () => { + serviceNowServer.close(); + }); + + it('does not return the connectors for a case that does not have connectors', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + expect(Object.keys(connectors).length).to.be(0); + }); + + it('retrieves multiple connectors', async () => { + const [{ postedCase, connector: serviceNowConnector }, jiraConnector] = await Promise.all([ + createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }), + createConnector({ + supertest, + req: { + ...getJiraConnector(), + }, + }), + ]); + + actionsRemover.add('default', jiraConnector.id, 'action', 'actions'); + + const theCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: serviceNowConnector.id, + }); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: theCase.id, + version: theCase.version, + connector: { + id: jiraConnector.id, + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: null, parent: null }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: theCase.id, supertest }); + expect(Object.keys(connectors).length).to.be(2); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[jiraConnector.id].id).to.be(jiraConnector.id); + }); + + describe('retrieving fields', () => { + it('retrieves a single connector using the create case user action', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const theCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const connectors = await getConnectors({ caseId: theCase.id, supertest }); + const snConnector = connectors[connector.id]; + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].fields).to.eql({ + category: 'software', + impact: '2', + severity: '2', + subcategory: 'os', + urgency: '2', + }); + + expect(snConnector.needsToBePushed).to.be(false); + expect(snConnector.name).to.be('ServiceNow Connector'); + expect(snConnector.id).to.be(connector.id); + }); + + it('retrieves a single connector using the connector user action', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + + const jiraConnector = await createConnector({ + supertest, + req: { + ...getJiraConnector(), + }, + }); + + actionsRemover.add('default', jiraConnector.id, 'action', 'actions'); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + connector: { + id: jiraConnector.id, + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: null, parent: null }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[jiraConnector.id].id).to.be(jiraConnector.id); + }); + + it('returns the fields of the connector update after a case was created with a connector', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + // change urgency to 3 + await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[serviceNowConnector.id].fields).to.eql({ + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }); + }); + }); + + describe('push', () => { + describe('latestPushDate', () => { + it('does not set latestPushDate when the connector has not been used to push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors).to.have.property(connector.id); + expect(connectors[connector.id].latestPushDate).to.be(undefined); + }); + + it('sets latestPushDate to the most recent push date', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + await createComment({ + supertest, + caseId: postedCase.id, + params: postCommentUserReq, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const [userActions, connectors] = await Promise.all([ + getCaseUserActions({ supertest, caseID: postedCase.id }), + getConnectors({ caseId: postedCase.id, supertest }), + ]); + + const pushes = userActions.filter((ua) => ua.type === ActionTypes.pushed); + const latestPush = pushes[pushes.length - 1]; + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].latestPushDate).to.eql(latestPush.created_at); + }); + }); + + describe('hasBeenPushed', () => { + it('sets hasBeenPushed to false when the connector has not been used to push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].hasBeenPushed).to.be(false); + }); + + it('sets hasBeenPushed to true when the connector was used to push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].hasBeenPushed).to.be(true); + }); + }); + + describe('needsToBePushed', () => { + it('sets needs to push to true when a push has not occurred', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(true); + }); + + it('sets needs to push to false when a push has occurred', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(false); + }); + + it('sets needs to push to true when a comment was created after the last push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + await createComment({ + supertest, + caseId: postedCase.id, + params: postCommentUserReq, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(true); + }); + + it('sets needs to push to false when the severity of a case was changed after the last push', async () => { + const { postedCase, connector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const pushedCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: connector.id, + }); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + severity: CaseSeverity.CRITICAL, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[connector.id].id).to.be(connector.id); + expect(connectors[connector.id].needsToBePushed).to.be(false); + }); + + it('sets needs to push to false the service now connector and true for jira', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const [pushedCase, jiraConnector] = await Promise.all([ + pushCase({ + supertest, + caseId: postedCase.id, + connectorId: serviceNowConnector.id, + }), + createConnector({ + supertest, + req: { + ...getJiraConnector(), + }, + }), + ]); + + actionsRemover.add('default', jiraConnector.id, 'action', 'actions'); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + connector: { + id: jiraConnector.id, + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: null, parent: null }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(2); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[serviceNowConnector.id].needsToBePushed).to.be(false); + expect(connectors[jiraConnector.id].id).to.be(jiraConnector.id); + expect(connectors[jiraConnector.id].needsToBePushed).to.be(true); + }); + + describe('changing connector fields', () => { + it('sets needs to push to false when the latest connector fields matches those used in the push', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + + const serviceNowConnector = await createConnector({ + supertest, + req: { + ...getServiceNowConnector(), + config: { apiUrl: serviceNowSimulatorURL }, + }, + }); + + actionsRemover.add('default', serviceNowConnector.id, 'action', 'actions'); + + const updatedCasesServiceNow = await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '2', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const pushedCase = await pushCase({ + supertest, + caseId: updatedCasesServiceNow[0].id, + connectorId: serviceNowConnector.id, + }); + + // switch urgency to 3 + const updatedCases = await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + // switch urgency back to 2 + await updateCase({ + supertest, + params: { + cases: [ + { + id: updatedCases[0].id, + version: updatedCases[0].version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '2', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[serviceNowConnector.id].needsToBePushed).to.be(false); + }); + + it('sets needs to push to true when the latest connector fields do not match those used in the push', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest, + serviceNowSimulatorURL, + actionsRemover, + }); + + const pushedCase = await pushCase({ + supertest, + caseId: postedCase.id, + connectorId: serviceNowConnector.id, + }); + + // switch urgency to 3 + await updateCase({ + supertest, + params: { + cases: [ + { + id: pushedCase.id, + version: pushedCase.version, + connector: { + id: serviceNowConnector.id, + name: 'SN', + type: ConnectorTypes.serviceNowITSM, + fields: { + urgency: '3', + impact: '2', + severity: '2', + category: 'software', + subcategory: 'os', + }, + }, + }, + ], + }, + }); + + const connectors = await getConnectors({ caseId: postedCase.id, supertest }); + + expect(Object.keys(connectors).length).to.be(1); + expect(connectors[serviceNowConnector.id].id).to.be(serviceNowConnector.id); + expect(connectors[serviceNowConnector.id].needsToBePushed).to.be(true); + }); + }); + }); + }); + + describe('rbac', () => { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + it('should retrieve the connectors for a case', async () => { + const { postedCase, connector: serviceNowConnector } = await createCaseWithConnector({ + supertest: supertestWithoutAuth, + serviceNowSimulatorURL, + actionsRemover, + auth: { user: superUser, space: 'space1' }, + createCaseReq: getPostCaseRequest({ owner: 'securitySolutionFixture' }), + }); + + for (const user of [globalRead, superUser, secOnly, secOnlyRead, obsSec, obsSecRead]) { + const connectors = await getConnectors({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + auth: { user, space: 'space1' }, + }); + + expect(Object.keys(connectors).length).to.eql(1); + expect(connectors[serviceNowConnector.id].id).to.eql(serviceNowConnector.id); + } + }); + + it('should not get connectors for a case when the user does not have access to the owner', async () => { + const { postedCase } = await createCaseWithConnector({ + supertest: supertestWithoutAuth, + serviceNowSimulatorURL, + actionsRemover, + auth: { user: superUser, space: 'space1' }, + createCaseReq: getPostCaseRequest({ owner: 'securitySolutionFixture' }), + }); + + for (const user of [noKibanaPrivileges, obsOnly, obsOnlyRead]) { + await getConnectors({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + expectedHttpCode: 403, + auth: { user, space: 'space1' }, + }); + } + }); + + it('should not get a case in a space the user does not have permissions to', async () => { + const { postedCase } = await createCaseWithConnector({ + supertest: supertestWithoutAuth, + serviceNowSimulatorURL, + actionsRemover, + auth: { user: superUser, space: 'space2' }, + createCaseReq: getPostCaseRequest({ owner: 'securitySolutionFixture' }), + }); + + await getConnectors({ + supertest: supertestWithoutAuth, + caseId: postedCase.id, + expectedHttpCode: 403, + auth: { user: secOnly, space: 'space2' }, + }); + }); + }); + }); +}; diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts index 09cbc2b9ad18b2..5d97cea038d5f9 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/cases/push_case.ts @@ -12,13 +12,12 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { nullUser } from '../../../../common/lib/mock'; +import { pushCase, deleteAllCaseItems, getAuthWithSuperUser } from '../../../../common/lib/utils'; + import { - pushCase, - deleteAllCaseItems, createCaseWithConnector, - getAuthWithSuperUser, getServiceNowSimulationServer, -} from '../../../../common/lib/utils'; +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts index c68437968e0da9..025e7ba08308fb 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_configure.ts @@ -12,16 +12,18 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { - getServiceNowConnector, - createConnector, createConfiguration, getConfiguration, getConfigurationRequest, removeServerGeneratedPropertiesFromSavedObject, getConfigurationOutput, getAuthWithSuperUser, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; import { nullUser } from '../../../../common/lib/mock'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts index 5ec6db8bd62fb8..2d5269baaf270f 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts @@ -9,19 +9,18 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; +import { getAuthWithSuperUser, getActionsSpace } from '../../../../common/lib/utils'; import { getServiceNowConnector, - getServiceNowOAuthConnector, - getJiraConnector, - getResilientConnector, - createConnector, getServiceNowSIRConnector, - getAuthWithSuperUser, - getCaseConnectors, - getActionsSpace, getEmailConnector, + getCaseConnectors, getCasesWebhookConnector, -} from '../../../../common/lib/utils'; + getServiceNowOAuthConnector, + getJiraConnector, + createConnector, + getResilientConnector, +} from '../../../../common/lib/connectors'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts index e984cab68f9ddd..54423a31956729 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/patch_configure.ts @@ -18,12 +18,14 @@ import { deleteConfiguration, createConfiguration, updateConfiguration, - getServiceNowConnector, - createConnector, getAuthWithSuperUser, getActionsSpace, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; import { nullUser } from '../../../../common/lib/mock'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts index 4a8ffe56d35eb8..97e80e790312e8 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/post_configure.ts @@ -17,12 +17,14 @@ import { getConfigurationOutput, deleteConfiguration, createConfiguration, - createConnector, - getServiceNowConnector, getAuthWithSuperUser, getActionsSpace, - getServiceNowSimulationServer, } from '../../../../common/lib/utils'; +import { + getServiceNowConnector, + createConnector, + getServiceNowSimulationServer, +} from '../../../../common/lib/connectors'; import { nullUser } from '../../../../common/lib/mock'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/detection_engine_api_integration/utils/install_detection_rules_package_from_fleet.ts b/x-pack/test/detection_engine_api_integration/utils/install_detection_rules_package_from_fleet.ts new file mode 100644 index 00000000000000..72408d8fd2af1e --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/utils/install_detection_rules_package_from_fleet.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { epmRouteService } from '@kbn/fleet-plugin/common'; +import { InstallPackageResponse } from '@kbn/fleet-plugin/common/types'; +import type { ToolingLog } from '@kbn/tooling-log'; +import type SuperTest from 'supertest'; + +/** + * Installed the security_detection_engine package via fleet API. Will + * @param supertest The supertest deps + * @param log The tooling logger + * @param version The version to install, e.g. '8.4.1' + * @param overrideExistingPackage Whether or not to force the install + */ +export const installDetectionRulesPackageFromFleet = async ( + supertest: SuperTest.SuperTest, + log: ToolingLog, + version: string, + overrideExistingPackage: true +): Promise => { + const response = await supertest + .post(epmRouteService.getInstallPath('security_detection_engine', version)) + .set('kbn-xsrf', 'true') + .send({ + force: overrideExistingPackage, + }); + if (response.status !== 200) { + log.error( + `Did not get an expected 200 "ok" when installing 'security_detection_engine' fleet package'. body: ${JSON.stringify( + response.body + )}, status: ${JSON.stringify(response.status)}` + ); + } + return response.body; +}; + +/** + * Returns the `--xpack.securitySolution.prebuiltRulesPackageVersion=8.3.1` setting + * as configured in the kbnServerArgs from the test's config.ts. + * @param kbnServerArgs Kibana server args within scope + */ +export const getPrebuiltRulesPackageVersionFromServerArgs = (kbnServerArgs: string[]): string => { + const re = + /--xpack\.securitySolution\.prebuiltRulesPackageVersion=(?.*)/; + for (const serverArg of kbnServerArgs) { + const match = re.exec(serverArg); + const prebuiltRulesPackageVersion = match?.groups?.prebuiltRulesPackageVersion; + if (prebuiltRulesPackageVersion) { + return prebuiltRulesPackageVersion; + } + } + + throw Error( + 'xpack.securitySolution.prebuiltRulesPackageVersion is not set in the server arguments' + ); +}; diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts index b8703cd5a1380e..c437197f9cafbe 100644 --- a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts +++ b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts @@ -58,6 +58,7 @@ export default function (providerContext: FtrProviderContext) { const { body } = await supertest.get(`/api/fleet/agent_policies/${createdPolicy.id}`); expect(body.item.is_managed).to.equal(false); + expect(body.item.inactivity_timeout).to.equal(1209600); expect(body.item.status).to.be('active'); }); @@ -624,6 +625,7 @@ export default function (providerContext: FtrProviderContext) { revision: 2, schema_version: FLEET_AGENT_POLICIES_SCHEMA_VERSION, updated_by: 'elastic', + inactivity_timeout: 1209600, package_policies: [], }); }); @@ -787,6 +789,7 @@ export default function (providerContext: FtrProviderContext) { updated_by: 'elastic', package_policies: [], monitoring_enabled: ['logs', 'metrics'], + inactivity_timeout: 1209600, }); const listResponseAfterUpdate = await fetchPackageList(); diff --git a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts index 21d1bc646c5c84..04b8d80fdbee19 100644 --- a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts +++ b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts @@ -110,6 +110,7 @@ export default function (providerContext: FtrProviderContext) { await generateAgent(providerContext, 'healthy', `agent-${++agentCount}`, agentPolicy.id); await generateAgent(providerContext, 'offline', `agent-${++agentCount}`, agentPolicy.id); await generateAgent(providerContext, 'error', `agent-${++agentCount}`, agentPolicy.id); + await generateAgent(providerContext, 'inactive', `agent-${++agentCount}`, agentPolicy.id); await generateAgent(providerContext, 'degraded', `agent-${++agentCount}`, agentPolicy.i); await generateAgent( providerContext, @@ -137,7 +138,7 @@ export default function (providerContext: FtrProviderContext) { unhealthy: 3, offline: 1, unenrolled: 0, - inactive: 0, + inactive: 1, updating: 1, total_all_statuses: 8, }); diff --git a/x-pack/test/fleet_api_integration/helpers.ts b/x-pack/test/fleet_api_integration/helpers.ts index c0f1543ee6e857..50bf8ba1ad7e47 100644 --- a/x-pack/test/fleet_api_integration/helpers.ts +++ b/x-pack/test/fleet_api_integration/helpers.ts @@ -52,7 +52,17 @@ export async function generateAgent( data = { policy_revision_idx: 1, last_checkin_status: 'degraded' }; break; case 'offline': - data = { policy_revision_idx: 1, last_checkin: '2017-06-07T18:59:04.498Z' }; + // default inactivity timeout is 2 weeks + // anything less + above offline timeout will be offline + const oneWeekAgoTimestamp = new Date().getTime() - 7 * 24 * 60 * 60 * 1000; + data = { policy_revision_idx: 1, last_checkin: new Date(oneWeekAgoTimestamp).toISOString() }; + break; + case 'inactive': + const threeWeeksAgoTimestamp = new Date().getTime() - 21 * 24 * 60 * 60 * 1000; + data = { + policy_revision_idx: 1, + last_checkin: new Date(threeWeeksAgoTimestamp).toISOString(), + }; break; // Agent with last checkin status as error and currently unenrolling => should displayd updating status case 'error-unenrolling': diff --git a/x-pack/test/functional_with_es_ssl/apps/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover/search_source_alert.ts index f583abef819944..7a6870c53685c1 100644 --- a/x-pack/test/functional_with_es_ssl/apps/discover/search_source_alert.ts +++ b/x-pack/test/functional_with_es_ssl/apps/discover/search_source_alert.ts @@ -410,6 +410,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.click('openEditRuleFlyoutButton'); await queryBar.setQuery('message:msg-1'); await filterBar.addFilter({ field: 'message.keyword', operation: 'is', value: 'msg-1' }); + await retry.waitFor('filters modal to become hidden', async () => { + return !(await testSubjects.exists('saveFilter')); + }); await testSubjects.click('thresholdPopover'); await testSubjects.setValue('alertThresholdInput', '1'); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts index 00f008519f237b..bf9f30f34bb3ff 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts @@ -15,5 +15,6 @@ export default ({ loadTestFile, getService }: FtrProviderContext) => { loadTestFile(require.resolve('./details')); loadTestFile(require.resolve('./connectors')); loadTestFile(require.resolve('./logs_list')); + loadTestFile(require.resolve('./rules_settings')); }); }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_settings.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_settings.ts new file mode 100644 index 00000000000000..6b4297f2dc1536 --- /dev/null +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_settings.ts @@ -0,0 +1,139 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { createAlert } from '../../lib/alert_api_actions'; +import { ObjectRemover } from '../../lib/object_remover'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const testSubjects = getService('testSubjects'); + const supertest = getService('supertest'); + const pageObjects = getPageObjects(['common', 'triggersActionsUI', 'header', 'security']); + const browser = getService('browser'); + const objectRemover = new ObjectRemover(supertest); + const retry = getService('retry'); + + async function refreshAlertsList() { + await retry.try(async () => { + await pageObjects.common.navigateToApp('triggersActions'); + await testSubjects.click('triggersActions'); + const searchResults = await pageObjects.triggersActionsUI.getAlertsList(); + expect(searchResults).to.have.length(1); + }); + } + + async function dragRangeInput( + testId: string, + steps: number = 1, + direction: 'left' | 'right' = 'right' + ) { + const inputEl = await testSubjects.find(testId); + await inputEl.focus(); + const browserKey = direction === 'left' ? browser.keys.LEFT : browser.keys.RIGHT; + while (steps--) { + await browser.pressKeys(browserKey); + } + } + + describe('rules settings modal', () => { + before(async () => { + await supertest + .post(`/internal/alerting/rules/settings/_flapping`) + .set('kbn-xsrf', 'foo') + .send({ + enabled: true, + lookBackWindow: 10, + statusChangeThreshold: 10, + }) + .expect(200); + }); + + beforeEach(async () => { + await createAlert({ + supertest, + objectRemover, + }); + await refreshAlertsList(); + }); + + afterEach(async () => { + await objectRemover.removeAll(); + }); + + it('rules settings link should be enabled', async () => { + await testSubjects.existOrFail('rulesSettingsLink'); + const button = await testSubjects.find('rulesSettingsLink'); + const isDisabled = await button.getAttribute('disabled'); + expect(isDisabled).to.equal(null); + }); + + it('should allow the user to open up the rules settings modal', async () => { + await testSubjects.click('rulesSettingsLink'); + await testSubjects.existOrFail('rulesSettingsModal'); + await testSubjects.waitForDeleted('centerJustifiedSpinner'); + + // Flapping enabled by default + await testSubjects.missingOrFail('rulesSettingsModalFlappingOffPrompt'); + + await testSubjects.existOrFail('rulesSettingsModalEnableSwitch'); + await testSubjects.existOrFail('lookBackWindowRangeInput'); + await testSubjects.existOrFail('statusChangeThresholdRangeInput'); + + const lookBackWindowInput = await testSubjects.find('lookBackWindowRangeInput'); + const statusChangeThresholdInput = await testSubjects.find('statusChangeThresholdRangeInput'); + + const lookBackWindowValue = await lookBackWindowInput.getAttribute('value'); + const statusChangeThresholdValue = await statusChangeThresholdInput.getAttribute('value'); + + expect(lookBackWindowValue).to.eql('10'); + expect(statusChangeThresholdValue).to.eql('10'); + }); + + it('should allow the user to modify rules settings', async () => { + await testSubjects.click('rulesSettingsLink'); + await testSubjects.waitForDeleted('centerJustifiedSpinner'); + + await dragRangeInput('lookBackWindowRangeInput', 5, 'right'); + await dragRangeInput('statusChangeThresholdRangeInput', 5, 'left'); + + let lookBackWindowInput = await testSubjects.find('lookBackWindowRangeInput'); + let statusChangeThresholdInput = await testSubjects.find('statusChangeThresholdRangeInput'); + + let lookBackWindowValue = await lookBackWindowInput.getAttribute('value'); + let statusChangeThresholdValue = await statusChangeThresholdInput.getAttribute('value'); + + expect(lookBackWindowValue).to.eql('15'); + expect(statusChangeThresholdValue).to.eql('5'); + + await testSubjects.click('rulesSettingsModalEnableSwitch'); + await testSubjects.existOrFail('rulesSettingsModalFlappingOffPrompt'); + + // Save + await testSubjects.click('rulesSettingsModalSaveButton'); + await pageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.missingOrFail('rulesSettingsModal'); + + // Open up the modal again + await testSubjects.click('rulesSettingsLink'); + await testSubjects.waitForDeleted('centerJustifiedSpinner'); + + // Flapping initially disabled + await testSubjects.existOrFail('rulesSettingsModalFlappingOffPrompt'); + await testSubjects.click('rulesSettingsModalEnableSwitch'); + + lookBackWindowInput = await testSubjects.find('lookBackWindowRangeInput'); + statusChangeThresholdInput = await testSubjects.find('statusChangeThresholdRangeInput'); + + lookBackWindowValue = await lookBackWindowInput.getAttribute('value'); + statusChangeThresholdValue = await statusChangeThresholdInput.getAttribute('value'); + + expect(lookBackWindowValue).to.eql('15'); + expect(statusChangeThresholdValue).to.eql('5'); + }); + }); +}; diff --git a/x-pack/test/security_api_integration/session_concurrent_limit.config.ts b/x-pack/test/security_api_integration/session_concurrent_limit.config.ts new file mode 100644 index 00000000000000..7c9fcf6bc8bf25 --- /dev/null +++ b/x-pack/test/security_api_integration/session_concurrent_limit.config.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { resolve } from 'path'; +import { FtrConfigProviderContext } from '@kbn/test'; +import { services } from './services'; + +// the default export of config files must be a config provider +// that returns an object with the projects config values +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const xPackAPITestsConfig = await readConfigFile(require.resolve('../api_integration/config.ts')); + + const kibanaPort = xPackAPITestsConfig.get('servers.kibana.port'); + const idpPath = resolve(__dirname, './fixtures/saml/idp_metadata.xml'); + + const testEndpointsPlugin = resolve(__dirname, '../security_functional/plugins/test_endpoints'); + + return { + testFiles: [resolve(__dirname, './tests/session_concurrent_limit')], + services, + servers: xPackAPITestsConfig.get('servers'), + esTestCluster: { + ...xPackAPITestsConfig.get('esTestCluster'), + serverArgs: [ + ...xPackAPITestsConfig.get('esTestCluster.serverArgs'), + 'xpack.security.authc.token.enabled=true', + 'xpack.security.authc.realms.native.native1.order=0', + 'xpack.security.authc.realms.saml.saml1.order=1', + `xpack.security.authc.realms.saml.saml1.idp.metadata.path=${idpPath}`, + 'xpack.security.authc.realms.saml.saml1.idp.entity_id=http://www.elastic.co/saml1', + `xpack.security.authc.realms.saml.saml1.sp.entity_id=http://localhost:${kibanaPort}`, + `xpack.security.authc.realms.saml.saml1.sp.logout=http://localhost:${kibanaPort}/logout`, + `xpack.security.authc.realms.saml.saml1.sp.acs=http://localhost:${kibanaPort}/api/security/saml/callback`, + 'xpack.security.authc.realms.saml.saml1.attributes.principal=urn:oid:0.0.7', + ], + }, + + kbnTestServer: { + ...xPackAPITestsConfig.get('kbnTestServer'), + serverArgs: [ + ...xPackAPITestsConfig.get('kbnTestServer.serverArgs'), + `--plugin-path=${testEndpointsPlugin}`, + '--xpack.security.session.concurrentSessions.maxSessions=2', + `--xpack.security.authc.providers=${JSON.stringify({ + basic: { basic1: { order: 0 } }, + saml: { saml1: { order: 1, realm: 'saml1' } }, + anonymous: { + anonymous1: { + order: 3, + credentials: { username: 'anonymous_user', password: 'changeme' }, + }, + }, + })}`, + // Exclude Uptime tasks to not interfere (additional ES load) with the session cleanup task. + `--xpack.task_manager.unsafe.exclude_task_types=${JSON.stringify(['UPTIME:*'])}`, + ], + }, + + junit: { + reportName: 'X-Pack Security API Integration Tests (Session Concurrent Limit)', + }, + }; +} diff --git a/x-pack/test/security_api_integration/tests/session_concurrent_limit/cleanup.ts b/x-pack/test/security_api_integration/tests/session_concurrent_limit/cleanup.ts new file mode 100644 index 00000000000000..ee9cff2eedd703 --- /dev/null +++ b/x-pack/test/security_api_integration/tests/session_concurrent_limit/cleanup.ts @@ -0,0 +1,385 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { parse as parseCookie, Cookie } from 'tough-cookie'; +import { setTimeout as setTimeoutAsync } from 'timers/promises'; +import expect from '@kbn/expect'; +import { adminTestUser } from '@kbn/test'; +import type { AuthenticationProvider } from '@kbn/security-plugin/common'; +import { + AggregateName, + AggregationsMultiTermsAggregate, + AggregationsMultiTermsBucket, + AggregationsTopHitsAggregate, + SearchTotalHits, +} from '@elastic/elasticsearch/lib/api/types'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { getSAMLRequestId, getSAMLResponse } from '../../fixtures/saml/saml_tools'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertestWithoutAuth'); + const es = getService('es'); + const security = getService('security'); + const esDeleteAllIndices = getService('esDeleteAllIndices'); + const config = getService('config'); + const log = getService('log'); + const randomness = getService('randomness'); + const testUser = { username: 'test_user', password: 'changeme' }; + const basicProvider = { type: 'basic', name: 'basic1' }; + const samlProvider = { type: 'saml', name: 'saml1' }; + const anonymousProvider = { type: 'anonymous', name: 'anonymous1' }; + const kibanaServerConfig = config.get('servers.kibana'); + + async function checkSessionCookie( + sessionCookie: Cookie, + username: string, + provider: AuthenticationProvider + ) { + const apiResponse = await supertest + .get('/internal/security/me') + .set('kbn-xsrf', 'xxx') + .set('Cookie', sessionCookie.cookieString()) + .expect(200); + + expect(apiResponse.body.username).to.be(username); + expect(apiResponse.body.authentication_provider).to.eql(provider); + + return Array.isArray(apiResponse.headers['set-cookie']) + ? parseCookie(apiResponse.headers['set-cookie'][0])! + : undefined; + } + + async function checkSessionCookieInvalid(sessionCookie: Cookie) { + await supertest + .get('/internal/security/me') + .set('kbn-xsrf', 'xxx') + .set('Cookie', sessionCookie.cookieString()) + .expect(401); + } + + async function getNumberOfSessionDocuments() { + await es.indices.refresh({ index: '.kibana_security_session*' }); + + const sessionDocuments = await es.search({ index: '.kibana_security_session*' }); + log.debug(`Existing sessions: ${JSON.stringify(sessionDocuments.hits)}.`); + + return (sessionDocuments.hits.total as SearchTotalHits).value; + } + + async function loginWithBasic(credentials: { username: string; password: string }) { + const authenticationResponse = await supertest + .post('/internal/security/login') + .set('kbn-xsrf', 'xxx') + .send({ + providerType: basicProvider.type, + providerName: basicProvider.name, + currentURL: '/', + params: credentials, + }) + .expect(200); + + return parseCookie(authenticationResponse.headers['set-cookie'][0])!; + } + + async function startSAMLHandshake() { + const handshakeResponse = await supertest + .post('/internal/security/login') + .set('kbn-xsrf', 'xxx') + .send({ providerType: samlProvider.type, providerName: samlProvider.name, currentURL: '' }) + .expect(200); + + return { + cookie: parseCookie(handshakeResponse.headers['set-cookie'][0])!, + location: handshakeResponse.body.location, + }; + } + + async function finishSAMLHandshake(handshakeCookie: Cookie, handshakeLocation: string) { + const authenticationResponse = await supertest + .post('/api/security/saml/callback') + .set('kbn-xsrf', 'xxx') + .set('Cookie', handshakeCookie.cookieString()) + .send({ + SAMLResponse: await getSAMLResponse({ + destination: `http://localhost:${kibanaServerConfig.port}/api/security/saml/callback`, + sessionIndex: String(randomness.naturalNumber()), + inResponseTo: await getSAMLRequestId(handshakeLocation), + }), + }) + .expect(302); + + return parseCookie(authenticationResponse.headers['set-cookie'][0])!; + } + + async function loginWithSAML() { + const { cookie, location } = await startSAMLHandshake(); + return finishSAMLHandshake(cookie, location); + } + + async function loginWithAnonymous() { + const authenticationResponse = await supertest + .post('/internal/security/login') + .set('kbn-xsrf', 'xxx') + .send({ + providerType: anonymousProvider.type, + providerName: anonymousProvider.name, + currentURL: '/', + }) + .expect(200); + + return parseCookie(authenticationResponse.headers['set-cookie'][0])!; + } + + async function toggleSessionCleanupTask(enabled: boolean) { + await supertest + .post('/session/toggle_cleanup_task') + .set('kbn-xsrf', 'xxx') + .auth(adminTestUser.username, adminTestUser.password) + .send({ enabled }) + .expect(200); + } + + describe('Session Concurrent Limit cleanup', () => { + before(async () => { + await security.user.create('anonymous_user', { + password: 'changeme', + roles: [], + full_name: 'Guest', + }); + }); + + after(async () => { + await security.user.delete('anonymous_user'); + }); + + beforeEach(async function () { + this.timeout(120000); + await toggleSessionCleanupTask(false); + await es.cluster.health({ index: '.kibana_security_session*', wait_for_status: 'green' }); + await esDeleteAllIndices('.kibana_security_session*'); + }); + + it('should properly clean up sessions that exceeded concurrent session limit', async function () { + this.timeout(100000); + + log.debug(`Log in as ${testUser.username} 3 times with a 0.5s delay.`); + + const basicSessionCookieOne = await loginWithBasic(testUser); + await setTimeoutAsync(500); + const basicSessionCookieTwo = await loginWithBasic(testUser); + await setTimeoutAsync(500); + const basicSessionCookieThree = await loginWithBasic(testUser); + + expect(await getNumberOfSessionDocuments()).to.be(3); + + // Let's wait for 60s to make sure cleanup routine runs after it was enabled. + log.debug('Waiting for cleanup job to run...'); + await toggleSessionCleanupTask(true); + await setTimeoutAsync(60000); + + // The oldest session should have been removed, but the rest should still be valid. + expect(await getNumberOfSessionDocuments()).to.be(2); + + await checkSessionCookieInvalid(basicSessionCookieOne); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieThree, testUser.username, basicProvider); + }); + + it('should properly clean up sessions that exceeded concurrent session limit even for multiple providers', async function () { + this.timeout(100000); + + log.debug(`Log in as ${testUser.username} and SAML user 3 times each with a 0.5s delay.`); + + const basicSessionCookieOne = await loginWithBasic(testUser); + const samlSessionCookieOne = await loginWithSAML(); + await setTimeoutAsync(500); + const basicSessionCookieTwo = await loginWithBasic(testUser); + const samlSessionCookieTwo = await loginWithSAML(); + await setTimeoutAsync(500); + const basicSessionCookieThree = await loginWithBasic(testUser); + const samlSessionCookieThree = await loginWithSAML(); + + expect(await getNumberOfSessionDocuments()).to.be(6); + + // Let's wait for 60s to make sure cleanup routine runs after it was enabled. + log.debug('Waiting for cleanup job to run...'); + await toggleSessionCleanupTask(true); + await setTimeoutAsync(60000); + + // The oldest session should have been removed, but the rest should still be valid. + expect(await getNumberOfSessionDocuments()).to.be(4); + + await checkSessionCookieInvalid(basicSessionCookieOne); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieThree, testUser.username, basicProvider); + + await checkSessionCookieInvalid(samlSessionCookieOne); + await checkSessionCookie(samlSessionCookieTwo, 'a@b.c', samlProvider); + await checkSessionCookie(samlSessionCookieThree, 'a@b.c', samlProvider); + }); + + it('should properly clean up sessions that exceeded concurrent session limit when legacy sessions are present', async function () { + this.timeout(100000); + + log.debug(`Log in as ${testUser.username} and SAML user 3 times each with a 0.5s delay.`); + + const basicSessionCookieOne = await loginWithBasic(testUser); + const samlSessionCookieOne = await loginWithSAML(); + await setTimeoutAsync(500); + const basicSessionCookieTwo = await loginWithBasic(testUser); + const samlSessionCookieTwo = await loginWithSAML(); + await setTimeoutAsync(500); + const basicSessionCookieThree = await loginWithBasic(testUser); + const samlSessionCookieThree = await loginWithSAML(); + + expect(await getNumberOfSessionDocuments()).to.be(6); + + // Remove `createdAt` field from the most recent sessions to emulate legacy sessions. + // 1. Get the latest session for every unique credentials. + const aggResponse = await es.search< + unknown, + Record + >({ + index: '.kibana_security_session*', + size: 0, + filter_path: 'aggregations.sessions.buckets.top.hits.hits._id', + aggs: { + sessions: { + multi_terms: { terms: [{ field: 'usernameHash' }, { field: 'provider.type' }] }, + aggs: { top: { top_hits: { sort: [{ createdAt: { order: 'desc' } }], size: 1 } } }, + }, + }, + }); + + // 2. Extract session IDs from the nested top_hits aggregation. + const sessionIds = + (aggResponse.aggregations?.sessions.buckets as AggregationsMultiTermsBucket[]).flatMap( + (bucket) => { + const sessionId = (bucket.top as AggregationsTopHitsAggregate).hits?.hits?.[0]?._id; + return sessionId ? [sessionId] : []; + } + ) ?? []; + expect(sessionIds.length).to.be(2); + + // 3. Remove `createdAt` field for the latest sessions emulating legacy sessions. + await es.updateByQuery({ + index: '.kibana_security_session*', + body: { script: 'ctx._source.remove("createdAt")', query: { ids: { values: sessionIds } } }, + refresh: true, + }); + + // Let's wait for 60s to make sure cleanup routine runs after it was enabled. + log.debug('Waiting for cleanup job to run...'); + await toggleSessionCleanupTask(true); + await setTimeoutAsync(60000); + + // The oldest session should have been removed, but the rest should still be valid. + expect(await getNumberOfSessionDocuments()).to.be(4); + + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookieInvalid(basicSessionCookieThree); + + await checkSessionCookie(samlSessionCookieOne, 'a@b.c', samlProvider); + await checkSessionCookie(samlSessionCookieTwo, 'a@b.c', samlProvider); + await checkSessionCookieInvalid(samlSessionCookieThree); + }); + + it('should not clean up session if the limit is not exceeded', async function () { + this.timeout(100000); + + log.debug(`Log in as ${testUser.username} 2 times with a 0.5s delay.`); + + const basicSessionCookieOne = await loginWithBasic(testUser); + await setTimeoutAsync(500); + const basicSessionCookieTwo = await loginWithBasic(testUser); + + expect(await getNumberOfSessionDocuments()).to.be(2); + + // Let's wait for 60s to make sure cleanup routine runs after it was enabled. + log.debug('Waiting for cleanup job to run...'); + await toggleSessionCleanupTask(true); + await setTimeoutAsync(60000); + + // The oldest session should have been removed, but the rest should still be valid. + expect(await getNumberOfSessionDocuments()).to.be(2); + + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + }); + + it('should not clean up sessions of the anonymous users', async function () { + this.timeout(100000); + + log.debug(`Log in as anonymous_user 3 times.`); + + const anonymousSessionCookieOne = await loginWithAnonymous(); + const anonymousSessionCookieTwo = await loginWithAnonymous(); + const anonymousSessionCookieThree = await loginWithAnonymous(); + + expect(await getNumberOfSessionDocuments()).to.be(3); + + // Let's wait for 60s to make sure cleanup routine runs after it was enabled. + log.debug('Waiting for cleanup job to run...'); + await toggleSessionCleanupTask(true); + await setTimeoutAsync(60000); + + // The oldest session should have been removed, but the rest should still be valid. + expect(await getNumberOfSessionDocuments()).to.be(3); + + // All sessions should be active. + for (const anonymousSessionCookie of [ + anonymousSessionCookieOne, + anonymousSessionCookieTwo, + anonymousSessionCookieThree, + ]) { + await checkSessionCookie(anonymousSessionCookie, 'anonymous_user', anonymousProvider); + } + }); + + it('should not clean up unauthenticated sessions', async function () { + this.timeout(100000); + + log.debug(`Starting SAML handshake 3 times.`); + + const unauthenticatedSessionOne = await startSAMLHandshake(); + const unauthenticatedSessionTwo = await startSAMLHandshake(); + const unauthenticatedSessionThree = await startSAMLHandshake(); + + expect(await getNumberOfSessionDocuments()).to.be(3); + + // Let's wait for 60s to make sure cleanup routine runs after it was enabled. + log.debug('Waiting for cleanup job to run...'); + await toggleSessionCleanupTask(true); + await setTimeoutAsync(60000); + + // The oldest session should have been removed, but the rest should still be valid. + expect(await getNumberOfSessionDocuments()).to.be(3); + + // Finish SAML handshake (all should succeed since we don't enforce limit at session creation time). + const samlSessionCookieOne = await finishSAMLHandshake( + unauthenticatedSessionOne.cookie, + unauthenticatedSessionOne.location + ); + await setTimeoutAsync(500); + const samlSessionCookieTwo = await finishSAMLHandshake( + unauthenticatedSessionTwo.cookie, + unauthenticatedSessionTwo.location + ); + await setTimeoutAsync(500); + const samlSessionCookieThree = await finishSAMLHandshake( + unauthenticatedSessionThree.cookie, + unauthenticatedSessionThree.location + ); + + // For authenticated sessions limit should be enforced + await checkSessionCookieInvalid(samlSessionCookieOne); + await checkSessionCookie(samlSessionCookieTwo, 'a@b.c', samlProvider); + await checkSessionCookie(samlSessionCookieThree, 'a@b.c', samlProvider); + }); + }); +} diff --git a/x-pack/test/security_api_integration/tests/session_concurrent_limit/global_limit.ts b/x-pack/test/security_api_integration/tests/session_concurrent_limit/global_limit.ts new file mode 100644 index 00000000000000..3b4fecf6ee7c4d --- /dev/null +++ b/x-pack/test/security_api_integration/tests/session_concurrent_limit/global_limit.ts @@ -0,0 +1,267 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { parse as parseCookie, Cookie } from 'tough-cookie'; +import expect from '@kbn/expect'; +import { adminTestUser } from '@kbn/test'; +import type { AuthenticationProvider } from '@kbn/security-plugin/common/model'; +import { getSAMLRequestId, getSAMLResponse } from '../../fixtures/saml/saml_tools'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertestWithoutAuth'); + const es = getService('es'); + const security = getService('security'); + const config = getService('config'); + const log = getService('log'); + const randomness = getService('randomness'); + const kibanaServerConfig = config.get('servers.kibana'); + const testUser = { username: 'test_user', password: 'changeme' }; + const basicProvider = { type: 'basic', name: 'basic1' }; + const samlProvider = { type: 'saml', name: 'saml1' }; + const anonymousProvider = { type: 'anonymous', name: 'anonymous1' }; + + async function checkSessionCookie( + sessionCookie: Cookie, + username: string, + provider: AuthenticationProvider + ) { + const apiResponse = await supertest + .get('/internal/security/me') + .set('kbn-xsrf', 'xxx') + .set('Cookie', sessionCookie.cookieString()) + .expect(200); + + expect(apiResponse.body.username).to.be(username); + expect(apiResponse.body.authentication_provider).to.eql(provider); + + return Array.isArray(apiResponse.headers['set-cookie']) + ? parseCookie(apiResponse.headers['set-cookie'][0])! + : undefined; + } + + async function checkSessionCookieInvalid(sessionCookie: Cookie) { + await supertest + .get('/internal/security/me') + .set('kbn-xsrf', 'xxx') + .set('Cookie', sessionCookie.cookieString()) + .expect(401); + } + + async function loginWithSAML() { + const handshakeResponse = await supertest + .post('/internal/security/login') + .set('kbn-xsrf', 'xxx') + .send({ providerType: samlProvider.type, providerName: samlProvider.name, currentURL: '' }) + .expect(200); + + const authenticationResponse = await supertest + .post('/api/security/saml/callback') + .set('kbn-xsrf', 'xxx') + .set('Cookie', parseCookie(handshakeResponse.headers['set-cookie'][0])!.cookieString()) + .send({ + SAMLResponse: await getSAMLResponse({ + destination: `http://localhost:${kibanaServerConfig.port}/api/security/saml/callback`, + sessionIndex: String(randomness.naturalNumber()), + inResponseTo: await getSAMLRequestId(handshakeResponse.body.location), + }), + }) + .expect(302); + + return parseCookie(authenticationResponse.headers['set-cookie'][0])!; + } + + async function loginWithBasic(credentials: { username: string; password: string }) { + const authenticationResponse = await supertest + .post('/internal/security/login') + .set('kbn-xsrf', 'xxx') + .send({ + providerType: basicProvider.type, + providerName: basicProvider.name, + currentURL: '/', + params: credentials, + }) + .expect(200); + + return parseCookie(authenticationResponse.headers['set-cookie'][0])!; + } + + async function loginWithAnonymous() { + const authenticationResponse = await supertest + .post('/internal/security/login') + .set('kbn-xsrf', 'xxx') + .send({ + providerType: anonymousProvider.type, + providerName: anonymousProvider.name, + currentURL: '/', + }) + .expect(200); + + return parseCookie(authenticationResponse.headers['set-cookie'][0])!; + } + + async function toggleSessionCleanupTask(enabled: boolean) { + await supertest + .post('/session/toggle_cleanup_task') + .set('kbn-xsrf', 'xxx') + .auth(adminTestUser.username, adminTestUser.password) + .send({ enabled }) + .expect(200); + } + + describe('Session Global Concurrent Limit', () => { + before(async function () { + this.timeout(120000); + // Disable cleanup task to not interfere with the tests. + await toggleSessionCleanupTask(false); + await security.user.create('anonymous_user', { + password: 'changeme', + roles: [], + full_name: 'Guest', + }); + }); + + after(async () => { + // Enable cleanup task again. + await toggleSessionCleanupTask(true); + await security.user.delete('anonymous_user'); + }); + + beforeEach(async () => { + await security.testUser.setRoles(['kibana_admin']); + await es.cluster.health({ index: '.kibana_security_session*', wait_for_status: 'green' }); + await supertest + .post('/api/security/session/_invalidate') + .set('kbn-xsrf', 'xxx') + .auth(adminTestUser.username, adminTestUser.password) + .send({ match: 'all' }) + .expect(200); + }); + + it('should properly enforce session limit with single provider', async function () { + const basicSessionCookieOne = await loginWithBasic(testUser); + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + + const basicSessionCookieTwo = await loginWithBasic(testUser); + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + + // The oldest session should be displaced. + const basicSessionCookieThree = await loginWithBasic(testUser); + await checkSessionCookieInvalid(basicSessionCookieOne); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieThree, testUser.username, basicProvider); + + // The next oldest session should be displaced as well. + const basicSessionCookieFour = await loginWithBasic(testUser); + await checkSessionCookieInvalid(basicSessionCookieTwo); + await checkSessionCookie(basicSessionCookieThree, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieFour, testUser.username, basicProvider); + }); + + it('should properly enforce session limit with single provider and multiple users', async function () { + const basicSessionCookieOne = await loginWithBasic(testUser); + const basicSessionCookieTwo = await loginWithBasic(testUser); + const basicSessionCookieThree = await loginWithBasic(adminTestUser); + const basicSessionCookieFour = await loginWithBasic(adminTestUser); + + // All sessions should be active. + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieThree, adminTestUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieFour, adminTestUser.username, basicProvider); + + // The oldest session of the admin user should be displaced. + const basicSessionCookieFive = await loginWithBasic(adminTestUser); + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookieInvalid(basicSessionCookieThree); + await checkSessionCookie(basicSessionCookieFour, adminTestUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieFive, adminTestUser.username, basicProvider); + + // The next oldest session of the admin user should be displaced as well. + const basicSessionCookieSix = await loginWithBasic(adminTestUser); + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookieInvalid(basicSessionCookieFour); + await checkSessionCookie(basicSessionCookieFive, adminTestUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieSix, adminTestUser.username, basicProvider); + + // Only the oldest session of the ordinary user should be displaced. + const basicSessionCookieSeven = await loginWithBasic(testUser); + await checkSessionCookieInvalid(basicSessionCookieOne); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieFive, adminTestUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieSix, adminTestUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieSeven, testUser.username, basicProvider); + }); + + it('should properly enforce session limit even for multiple concurrent logins', async function () { + const basicSessionCookies = await Promise.all( + Array.from({ length: 10 }).map(() => loginWithBasic(testUser)) + ); + + // Since logins were concurrent we cannot know upfront their `createdAt` timestamps and + // hence which specific sessions will be outside the limit. + const statusCodes = []; + for (const basicSessionCookie of basicSessionCookies) { + const { statusCode } = await supertest + .get('/internal/security/me') + .set('kbn-xsrf', 'xxx') + .set('Cookie', basicSessionCookie.cookieString()); + statusCodes.push(statusCode); + } + + log.debug(`Collected status codes: ${JSON.stringify(statusCodes)}.`); + + expect(statusCodes.filter((statusCode) => statusCode === 200)).to.have.length(2); + expect(statusCodes.filter((statusCode) => statusCode === 401)).to.have.length(8); + }); + + it('should properly enforce session limit with multiple providers', async function () { + const basicSessionCookieOne = await loginWithBasic(testUser); + const basicSessionCookieTwo = await loginWithBasic(testUser); + + const samlSessionCookieOne = await loginWithSAML(); + const samlSessionCookieTwo = await loginWithSAML(); + + // All sessions should be active. + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookie(samlSessionCookieOne, 'a@b.c', samlProvider); + await checkSessionCookie(samlSessionCookieTwo, 'a@b.c', samlProvider); + + // Exceed limit with SAML credentials, other sessions shouldn't be affected. + const samlSessionCookieThree = await loginWithSAML(); + await checkSessionCookie(basicSessionCookieOne, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookieInvalid(samlSessionCookieOne); + await checkSessionCookie(samlSessionCookieTwo, 'a@b.c', samlProvider); + await checkSessionCookie(samlSessionCookieThree, 'a@b.c', samlProvider); + + // Exceed limit with Basic credentials, other sessions shouldn't be affected. + const basicSessionCookieThree = await loginWithBasic(testUser); + await checkSessionCookieInvalid(basicSessionCookieOne); + await checkSessionCookie(basicSessionCookieTwo, testUser.username, basicProvider); + await checkSessionCookie(basicSessionCookieThree, testUser.username, basicProvider); + await checkSessionCookie(samlSessionCookieTwo, 'a@b.c', samlProvider); + await checkSessionCookie(samlSessionCookieThree, 'a@b.c', samlProvider); + }); + + it('should not enforce session limit for anonymous users', async function () { + // All sessions should be active. + for (const anonymousSessionCookie of [ + await loginWithAnonymous(), + await loginWithAnonymous(), + await loginWithAnonymous(), + await loginWithAnonymous(), + ]) { + await checkSessionCookie(anonymousSessionCookie, 'anonymous_user', anonymousProvider); + } + }); + }); +} diff --git a/x-pack/test/security_api_integration/tests/session_concurrent_limit/index.ts b/x-pack/test/security_api_integration/tests/session_concurrent_limit/index.ts new file mode 100644 index 00000000000000..61463eaccb09b8 --- /dev/null +++ b/x-pack/test/security_api_integration/tests/session_concurrent_limit/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('security APIs - Session Concurrent Limit', function () { + loadTestFile(require.resolve('./cleanup')); + loadTestFile(require.resolve('./global_limit')); + }); +} diff --git a/x-pack/test/security_functional/plugins/test_endpoints/kibana.json b/x-pack/test/security_functional/plugins/test_endpoints/kibana.json index 6546325cb2d68f..4c9364e7ed2188 100644 --- a/x-pack/test/security_functional/plugins/test_endpoints/kibana.json +++ b/x-pack/test/security_functional/plugins/test_endpoints/kibana.json @@ -3,7 +3,7 @@ "owner": { "name": "Platform Security", "githubTeam": "kibana-security" }, "version": "8.0.0", "kibanaVersion": "kibana", - "requiredPlugins":["security"], + "requiredPlugins":["security", "taskManager"], "server": true, "ui": true } diff --git a/x-pack/test/security_functional/plugins/test_endpoints/server/index.ts b/x-pack/test/security_functional/plugins/test_endpoints/server/index.ts index 43b634048d8cd2..33ce96a3cfffa5 100644 --- a/x-pack/test/security_functional/plugins/test_endpoints/server/index.ts +++ b/x-pack/test/security_functional/plugins/test_endpoints/server/index.ts @@ -5,11 +5,25 @@ * 2.0. */ -import { PluginInitializer, Plugin } from '@kbn/core/server'; +import { PluginInitializer, Plugin, CoreSetup } from '@kbn/core/server'; +import { + TaskManagerSetupContract, + TaskManagerStartContract, +} from '@kbn/task-manager-plugin/server'; import { initRoutes } from './init_routes'; -export const plugin: PluginInitializer = (initializerContext): Plugin => ({ - setup: (core) => initRoutes(initializerContext, core), +export interface PluginSetupDependencies { + taskManager: TaskManagerSetupContract; +} + +export interface PluginStartDependencies { + taskManager: TaskManagerStartContract; +} + +export const plugin: PluginInitializer = ( + initializerContext +): Plugin => ({ + setup: (core: CoreSetup) => initRoutes(initializerContext, core), start: () => {}, stop: () => {}, }); diff --git a/x-pack/test/security_functional/plugins/test_endpoints/server/init_routes.ts b/x-pack/test/security_functional/plugins/test_endpoints/server/init_routes.ts index 16db5c82429314..9ffcb635f041e4 100644 --- a/x-pack/test/security_functional/plugins/test_endpoints/server/init_routes.ts +++ b/x-pack/test/security_functional/plugins/test_endpoints/server/init_routes.ts @@ -7,9 +7,20 @@ import { schema } from '@kbn/config-schema'; import { errors } from '@elastic/elasticsearch'; -import { CoreSetup, PluginInitializerContext } from '@kbn/core/server'; +import { CoreSetup, CoreStart, PluginInitializerContext } from '@kbn/core/server'; +import type { + TaskManagerStartContract, + ConcreteTaskInstance, + BulkUpdateTaskResult, +} from '@kbn/task-manager-plugin/server'; +import { PluginStartDependencies } from '.'; -export function initRoutes(initializerContext: PluginInitializerContext, core: CoreSetup) { +export const SESSION_INDEX_CLEANUP_TASK_NAME = 'session_cleanup'; + +export function initRoutes( + initializerContext: PluginInitializerContext, + core: CoreSetup +) { const logger = initializerContext.logger.get(); const authenticationAppOptions = { simulateUnauthorized: false }; @@ -96,4 +107,127 @@ export function initRoutes(initializerContext: PluginInitializerContext, core: C } } ); + + async function waitUntilTaskIsIdle(taskManager: TaskManagerStartContract) { + logger.info(`Waiting until session cleanup task is in idle.`); + + const RETRY_SCALE_DURATION = 1000; + let retriesElapsed = 0; + let taskInstance: ConcreteTaskInstance; + while (retriesElapsed < 15 /** max around ~100s **/) { + await new Promise((resolve) => setTimeout(resolve, retriesElapsed * RETRY_SCALE_DURATION)); + + try { + taskInstance = await taskManager.get(SESSION_INDEX_CLEANUP_TASK_NAME); + if (taskInstance.status === 'idle') { + logger.info(`Session cleanup task is in idle state: ${JSON.stringify(taskInstance)}.`); + return; + } + } catch (err) { + logger.error(`Failed to fetch task: ${err?.message || err}.`); + throw err; + } + + if (++retriesElapsed < 15) { + logger.warn( + `Session cleanup task is NOT in idle state (waiting for ${ + retriesElapsed * RETRY_SCALE_DURATION + }ms before retrying): ${JSON.stringify(taskInstance)}.` + ); + } else { + logger.error( + `Failed to wait until session cleanup tasks enters an idle state: ${JSON.stringify( + taskInstance + )}.` + ); + } + } + } + + async function refreshTaskManagerIndex( + enabled: boolean, + coreStart: CoreStart, + taskManager: TaskManagerStartContract + ) { + // Refresh task manager index before trying to modify a task document. + // Might not be needed once https://github.com/elastic/kibana/pull/148985 is merged. + try { + logger.info( + `Refreshing task manager index (enabled: ${enabled}), current task: ${JSON.stringify( + await taskManager.get(SESSION_INDEX_CLEANUP_TASK_NAME) + )}...` + ); + + const refreshResult = await coreStart.elasticsearch.client.asInternalUser.indices.refresh({ + index: '.kibana_task_manager', + expand_wildcards: 'all', + }); + + logger.info( + `Successfully refreshed task manager index (enabled: ${enabled}), refresh result: ${JSON.stringify( + refreshResult + )}, current task: ${JSON.stringify( + await taskManager.get(SESSION_INDEX_CLEANUP_TASK_NAME) + )}.` + ); + } catch (err) { + logger.error( + `Failed to refresh task manager index (enabled: ${enabled}): ${err?.message || err}.` + ); + } + } + + router.post( + { + path: '/session/toggle_cleanup_task', + validate: { body: schema.object({ enabled: schema.boolean() }) }, + }, + async (context, request, response) => { + const [coreStart, { taskManager }] = await core.getStartServices(); + logger.info(`Toggle session cleanup task (enabled: ${request.body.enabled}).`); + + await refreshTaskManagerIndex(request.body.enabled, coreStart, taskManager); + + let bulkEnableDisableResult: BulkUpdateTaskResult; + try { + if (request.body.enabled) { + logger.info( + `Going to enable the following task: ${JSON.stringify( + await taskManager.get(SESSION_INDEX_CLEANUP_TASK_NAME) + )}.` + ); + bulkEnableDisableResult = await taskManager.bulkEnable( + [SESSION_INDEX_CLEANUP_TASK_NAME], + true /** runSoon **/ + ); + } else { + bulkEnableDisableResult = await taskManager.bulkDisable([ + SESSION_INDEX_CLEANUP_TASK_NAME, + ]); + } + + await refreshTaskManagerIndex(request.body.enabled, coreStart, taskManager); + + // Make sure that the task enters idle state before acknowledging that task was disabled. + if (!request.body.enabled) { + await waitUntilTaskIsIdle(taskManager); + } + } catch (err) { + logger.error( + `Failed to toggle session cleanup task (enabled: ${request.body.enabled}): ${ + err?.message || err + }.` + ); + throw err; + } + + logger.info( + `Successfully toggled session cleanup task (enabled: ${ + request.body.enabled + }, enable/disable response: ${JSON.stringify(bulkEnableDisableResult)}).` + ); + + return response.ok(); + } + ); } diff --git a/x-pack/test/security_functional/plugins/test_endpoints/tsconfig.json b/x-pack/test/security_functional/plugins/test_endpoints/tsconfig.json index 2802334020ecbb..43a87600f622d8 100644 --- a/x-pack/test/security_functional/plugins/test_endpoints/tsconfig.json +++ b/x-pack/test/security_functional/plugins/test_endpoints/tsconfig.json @@ -13,6 +13,7 @@ "kbn_references": [ "@kbn/core", "@kbn/security-plugin", + "@kbn/task-manager-plugin", "@kbn/config-schema", ] } diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index 81d18ce1cab5d8..c8048c0b1ba4ba 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -52,6 +52,8 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { // mock cloud to enable the guided onboarding tour in e2e tests '--xpack.cloud.id=test', `--home.disableWelcomeScreen=true`, + // Specify which version of the detection-rules package to install + // `--xpack.securitySolution.prebuiltRulesPackageVersion=8.3.1`, ], }, }; diff --git a/yarn.lock b/yarn.lock index 7fe3223f3b8600..8133cfeb06aa25 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7348,13 +7348,6 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== -"@types/minipass@*": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@types/minipass/-/minipass-2.2.0.tgz#51ad404e8eb1fa961f75ec61205796807b6f9651" - integrity sha512-wuzZksN4w4kyfoOv/dlpov4NOunwutLA/q7uc00xU02ZyUY+aoM5PWIXEKBMnm0NHd4a+N71BMjq+x7+2Af1fg== - dependencies: - "@types/node" "*" - "@types/mock-fs@^4.13.1": version "4.13.1" resolved "https://registry.yarnpkg.com/@types/mock-fs/-/mock-fs-4.13.1.tgz#9201554ceb23671badbfa8ac3f1fa9e0706305be" @@ -7410,10 +7403,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@16.11.41", "@types/node@>= 8", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@>=8.9.0", "@types/node@^10.1.0", "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^14.14.31": - version "16.11.41" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.41.tgz#88eb485b1bfdb4c224d878b7832239536aa2f813" - integrity sha512-mqoYK2TnVjdkGk8qXAVGc/x9nSaTpSrFaGFm43BUH3IdoBV0nta6hYaGmdOvIMlbHJbUEVen3gvwpwovAZKNdQ== +"@types/node@*", "@types/node@18.11.18", "@types/node@>= 8", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@>=8.9.0", "@types/node@^10.1.0", "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^14.14.31": + version "18.11.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" + integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== "@types/nodemailer@^6.4.0": version "6.4.0" @@ -7898,13 +7891,13 @@ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== -"@types/tar@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.5.tgz#5f953f183e36a15c6ce3f336568f6051b7b183f3" - integrity sha512-cgwPhNEabHaZcYIy5xeMtux2EmYBitfqEceBUi2t5+ETy4dW6kswt6WX4+HqLeiiKOo42EXbGiDmVJ2x+vi37Q== +"@types/tar@^6.1.3": + version "6.1.3" + resolved "https://registry.yarnpkg.com/@types/tar/-/tar-6.1.3.tgz#46a2ce7617950c4852dfd7e9cd41aa8161b9d750" + integrity sha512-YzDOr5kdAeqS8dcO6NTTHTMJ44MUCBDoLEIyPtwEn7PssKqUYL49R1iCVJPeiPzPlKi6DbH33eZkpeJ27e4vHg== dependencies: - "@types/minipass" "*" "@types/node" "*" + minipass "^3.3.5" "@types/tempy@^0.2.0": version "0.2.0" @@ -8618,7 +8611,7 @@ abab@^2.0.3, abab@^2.0.4, abab@^2.0.5, abab@^2.0.6: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -abbrev@1: +abbrev@1, abbrev@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -16507,10 +16500,10 @@ inquirer@^8.2.3: through "^2.3.6" wrap-ansi "^7.0.0" -install-artifact-from-github@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.3.0.tgz#cab6ff821976b8a35b0c079da19a727c90381a40" - integrity sha512-iT8v1GwOAX0pPXifF/5ihnMhHOCo3OeK7z3TQa4CtSNCIg8k0UxqBEk9jRwz8OP68hHXvJ2gxRa89KYHtBkqGA== +install-artifact-from-github@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.3.1.tgz#eefaad9af35d632e5d912ad1569c1de38c3c2462" + integrity sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg== internal-slot@^1.0.3: version "1.0.3" @@ -19266,7 +19259,7 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^10.0.4: +make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.4: version "10.2.1" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== @@ -19968,10 +19961,17 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: - version "3.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" - integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6, minipass@^3.3.5: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.0.tgz#7cebb0f9fa7d56f0c5b17853cbe28838a8dbbd3b" + integrity sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw== dependencies: yallist "^4.0.0" @@ -20284,7 +20284,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.15.0, nan@^2.17.0: +nan@^2.16.0, nan@^2.17.0: version "2.17.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== @@ -20541,6 +20541,22 @@ node-gyp@^8.4.1: tar "^6.1.2" which "^2.0.2" +node-gyp@^9.0.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.3.0.tgz#f8eefe77f0ad8edb3b3b898409b53e697642b319" + integrity sha512-A6rJWfXFz7TQNjpldJ915WFb1LnhO4lIve3ANPbWreuEoLoKlFT3sxIepPBkLhM27crW8YmN+pjlgbasH6cH/Q== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^10.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -20642,6 +20658,13 @@ nopt@^5.0.0: dependencies: abbrev "1" +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -22795,14 +22818,14 @@ re-resizable@^6.1.1: dependencies: fast-memoize "^2.5.1" -re2@1.17.4: - version "1.17.4" - resolved "https://registry.yarnpkg.com/re2/-/re2-1.17.4.tgz#7bf29290bdde963014e77bd2c2e799a6d788386e" - integrity sha512-xyZ4h5PqE8I9tAxTh3G0UttcK5ufrcUxReFjGzfX61vtanNbS1XZHjnwRSyPcLgChI4KLxVgOT/ioZXnUAdoTA== +re2@1.17.7: + version "1.17.7" + resolved "https://registry.yarnpkg.com/re2/-/re2-1.17.7.tgz#e14cab85a177a5534c7215c322d1b043c55aa1e9" + integrity sha512-X8GSuiBoVWwcjuppqSjsIkRxNUKDdjhkO9SBekQbZ2ksqWUReCy7DQPWOVpoTnpdtdz5PIpTTxTFzvJv5UMfjA== dependencies: - install-artifact-from-github "^1.3.0" - nan "^2.15.0" - node-gyp "^8.4.1" + install-artifact-from-github "^1.3.1" + nan "^2.16.0" + node-gyp "^9.0.0" react-ace@^7.0.5: version "7.0.5" @@ -25115,10 +25138,10 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +source-map@^0.7.3, source-map@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== source-map@^0.8.0-beta.0: version "0.8.0-beta.0" @@ -26049,7 +26072,7 @@ tar-stream@^2.1.4, tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -tar@6.1.11, tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: +tar@6.1.11: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -26061,6 +26084,18 @@ tar@6.1.11, tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: mkdirp "^1.0.3" yallist "^4.0.0" +tar@^6.0.2, tar@^6.1.11, tar@^6.1.13, tar@^6.1.2: + version "6.1.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" + integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^4.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + tcomb-validation@^3.3.0: version "3.4.1" resolved "https://registry.yarnpkg.com/tcomb-validation/-/tcomb-validation-3.4.1.tgz#a7696ec176ce56a081d9e019f8b732a5a8894b65"